ethdev: add min/max MTU to device info
[dpdk.git] / lib / librte_ethdev / rte_ethdev.c
index 9d5107d..10bdfb3 100644 (file)
@@ -48,7 +48,6 @@ int rte_eth_dev_logtype;
 
 static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";
 struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
-static uint16_t eth_dev_last_created_port;
 
 /* spinlock for eth device callbacks */
 static rte_spinlock_t rte_eth_dev_cb_lock = RTE_SPINLOCK_INITIALIZER;
@@ -431,8 +430,6 @@ eth_dev_get(uint16_t port_id)
 
        eth_dev->data = &rte_eth_dev_shared_data->data[port_id];
 
-       eth_dev_last_created_port = port_id;
-
        return eth_dev;
 }
 
@@ -441,6 +438,18 @@ rte_eth_dev_allocate(const char *name)
 {
        uint16_t port_id;
        struct rte_eth_dev *eth_dev = NULL;
+       size_t name_len;
+
+       name_len = strnlen(name, RTE_ETH_NAME_MAX_LEN);
+       if (name_len == 0) {
+               RTE_ETHDEV_LOG(ERR, "Zero length Ethernet device name\n");
+               return NULL;
+       }
+
+       if (name_len >= RTE_ETH_NAME_MAX_LEN) {
+               RTE_ETHDEV_LOG(ERR, "Ethernet device name is too long\n");
+               return NULL;
+       }
 
        rte_eth_dev_shared_data_prepare();
 
@@ -462,7 +471,7 @@ rte_eth_dev_allocate(const char *name)
        }
 
        eth_dev = eth_dev_get(port_id);
-       snprintf(eth_dev->data->name, sizeof(eth_dev->data->name), "%s", name);
+       strlcpy(eth_dev->data->name, name, sizeof(eth_dev->data->name));
        eth_dev->data->port_id = port_id;
        eth_dev->data->mtu = ETHER_MTU;
 
@@ -588,7 +597,6 @@ _rte_eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
 {
        struct rte_eth_dev *ethdev = &rte_eth_devices[port_id];
        struct rte_eth_dev_owner *port_owner;
-       int sret;
 
        if (port_id >= RTE_MAX_ETHPORTS || !is_allocated(ethdev)) {
                RTE_ETHDEV_LOG(ERR, "Port id %"PRIu16" is not allocated\n",
@@ -612,11 +620,8 @@ _rte_eth_dev_owner_set(const uint16_t port_id, const uint64_t old_owner_id,
                return -EPERM;
        }
 
-       sret = snprintf(port_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN, "%s",
-                       new_owner->name);
-       if (sret < 0 || sret >= RTE_ETH_MAX_OWNER_NAME_LEN)
-               RTE_ETHDEV_LOG(ERR, "Port %u owner name was truncated\n",
-                       port_id);
+       /* can not truncate (same structure) */
+       strlcpy(port_owner->name, new_owner->name, RTE_ETH_MAX_OWNER_NAME_LEN);
 
        port_owner->id = new_owner->id;
 
@@ -2527,6 +2532,8 @@ rte_eth_dev_info_get(uint16_t port_id, struct rte_eth_dev_info *dev_info)
        dev_info->rx_desc_lim = lim;
        dev_info->tx_desc_lim = lim;
        dev_info->device = dev->device;
+       dev_info->min_mtu = ETHER_MIN_MTU;
+       dev_info->max_mtu = UINT16_MAX;
 
        RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
        (*dev->dev_ops->dev_infos_get)(dev, dev_info);
@@ -2590,12 +2597,25 @@ int
 rte_eth_dev_set_mtu(uint16_t port_id, uint16_t mtu)
 {
        int ret;
+       struct rte_eth_dev_info dev_info;
        struct rte_eth_dev *dev;
 
        RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
        dev = &rte_eth_devices[port_id];
        RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mtu_set, -ENOTSUP);
 
+       /*
+        * Check if the device supports dev_infos_get, if it does not
+        * skip min_mtu/max_mtu validation here as this requires values
+        * that are populated within the call to rte_eth_dev_info_get()
+        * which relies on dev->dev_ops->dev_infos_get.
+        */
+       if (*dev->dev_ops->dev_infos_get != NULL) {
+               rte_eth_dev_info_get(port_id, &dev_info);
+               if (mtu < dev_info.min_mtu || mtu > dev_info.max_mtu)
+                       return -EINVAL;
+       }
+
        ret = (*dev->dev_ops->mtu_set)(dev, mtu);
        if (!ret)
                dev->data->mtu = mtu;
@@ -3588,9 +3608,15 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 {
        char z_name[RTE_MEMZONE_NAMESIZE];
        const struct rte_memzone *mz;
+       int rc;
 
-       snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
-                dev->data->port_id, queue_id, ring_name);
+       rc = snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
+                     dev->data->port_id, queue_id, ring_name);
+       if (rc >= RTE_MEMZONE_NAMESIZE) {
+               RTE_ETHDEV_LOG(ERR, "ring name too long\n");
+               rte_errno = ENAMETOOLONG;
+               return NULL;
+       }
 
        mz = rte_memzone_lookup(z_name);
        if (mz)