From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by dpdk.org (Postfix) with ESMTP id A99EC1B366 for ; Mon, 12 Feb 2018 15:44:31 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Feb 2018 06:44:30 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,501,1511856000"; d="scan'208";a="17502820" Received: from unknown (HELO localhost.localdomain) ([10.224.122.203]) by orsmga008.jf.intel.com with ESMTP; 12 Feb 2018 06:44:28 -0800 From: Vipin Varghese To: dev@dpdk.org, pascal.mazon@6wind.com Cc: ferruh.yigit@intel.com, deepak.k.jain@intel.com, Vipin Varghese Date: Mon, 12 Feb 2018 20:14:49 +0530 Message-Id: <1518446689-26839-1-git-send-email-vipin.varghese@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: References: Subject: [dpdk-dev] [PATCH v1] net/tap: allow user MAC to be passed as args X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 12 Feb 2018 14:44:32 -0000 Allow TAP PMD to pass user desired MAC address as argument. The argument value is processed as string delimited by ':', is parsed and converted to HEX MAC address after validation. Signed-off-by: Vipin Varghese Signed-off-by: Pascal Mazon --- Changes: - seggrated the function for hex sting validation - Ferruh - Fixed the logic lookup for MAC address --- drivers/net/tap/rte_eth_tap.c | 75 +++++++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c index 9d39384..5f67d51 100644 --- a/drivers/net/tap/rte_eth_tap.c +++ b/drivers/net/tap/rte_eth_tap.c @@ -48,6 +48,10 @@ #define ETH_TAP_MAC_ARG "mac" #define ETH_TAP_MAC_FIXED "fixed" +#define ETH_TAP_USR_MAC_FMT "xx:xx:xx:xx:xx:xx" +#define ETH_TAP_CMP_MAC_FMT "0123456789ABCDEFabcdef" +#define ETH_TAP_MAC_ARG_FMT ETH_TAP_MAC_FIXED "|" ETH_TAP_USR_MAC_FMT + static struct rte_vdev_driver pmd_tap_drv; static const char *valid_arguments[] = { @@ -1335,7 +1339,7 @@ enum ioctl_mode { static int eth_dev_tap_create(struct rte_vdev_device *vdev, char *tap_name, - char *remote_iface, int fixed_mac_type) + char *remote_iface, struct ether_addr *mac_addr) { int numa_node = rte_socket_id(); struct rte_eth_dev *dev; @@ -1397,16 +1401,10 @@ enum ioctl_mode { pmd->txq[i].fd = -1; } - if (fixed_mac_type) { - /* fixed mac = 00:64:74:61:70: */ - static int iface_idx; - char mac[ETHER_ADDR_LEN] = "\0dtap"; - - mac[ETHER_ADDR_LEN - 1] = iface_idx++; - rte_memcpy(&pmd->eth_addr, mac, ETHER_ADDR_LEN); - } else { + if (is_zero_ether_addr(mac_addr)) eth_random_addr((uint8_t *)&pmd->eth_addr); - } + else + rte_memcpy(&pmd->eth_addr, mac_addr, sizeof(mac_addr)); /* Immediately create the netdevice (this will create the 1st queue). */ /* rx queue */ @@ -1567,15 +1565,58 @@ enum ioctl_mode { return 0; } +static int parse_user_mac(struct ether_addr *user_mac, + const char *value) +{ + unsigned int index = 0; + char mac_temp[strlen(ETH_TAP_USR_MAC_FMT) + 1], *mac_byte = NULL; + + if (user_mac == NULL || value == NULL) + return 0; + + snprintf(mac_temp, sizeof(mac_temp), "%s", value); + mac_byte = strtok(mac_temp, ":"); + + while ((mac_byte != NULL) && + (strlen(mac_byte) <= 2) && + (strlen(mac_byte) == strspn(mac_byte, + ETH_TAP_CMP_MAC_FMT))) { + user_mac->addr_bytes[index++] = strtoul(mac_byte, NULL, 16); + mac_byte = strtok(NULL, ":"); + } + + return index; +} + static int set_mac_type(const char *key __rte_unused, const char *value, void *extra_args) { - if (value && - !strncasecmp(ETH_TAP_MAC_FIXED, value, strlen(ETH_TAP_MAC_FIXED))) - *(int *)extra_args = 1; + struct ether_addr *user_mac = extra_args; + + if (!value) + return 0; + + if (!strncasecmp(ETH_TAP_MAC_FIXED, value, strlen(ETH_TAP_MAC_FIXED))) { + static int iface_idx; + + /* fixed mac = 00:64:74:61:70: */ + memcpy((char *)user_mac->addr_bytes, "\0dtap", ETHER_ADDR_LEN); + user_mac->addr_bytes[ETHER_ADDR_LEN - 1] = iface_idx++ + '0'; + goto success; + } + + if (parse_user_mac(user_mac, value) != 6) + goto error; +success: + RTE_LOG(DEBUG, PMD, "TAP user MAC param (%s)\n", value); return 0; + +error: + RTE_LOG(ERR, PMD, "TAP user MAC (%s) is not in format (%s|%s)\n", + value, ETH_TAP_MAC_FIXED, ETH_TAP_USR_MAC_FMT); + return -1; } /* Open a TAP interface device. @@ -1589,7 +1630,7 @@ enum ioctl_mode { int speed; char tap_name[RTE_ETH_NAME_MAX_LEN]; char remote_iface[RTE_ETH_NAME_MAX_LEN]; - int fixed_mac_type = 0; + struct ether_addr user_mac; name = rte_vdev_device_name(dev); params = rte_vdev_device_args(dev); @@ -1626,7 +1667,7 @@ enum ioctl_mode { ret = rte_kvargs_process(kvlist, ETH_TAP_MAC_ARG, &set_mac_type, - &fixed_mac_type); + &user_mac); if (ret == -1) goto leave; } @@ -1637,7 +1678,7 @@ enum ioctl_mode { RTE_LOG(NOTICE, PMD, "Initializing pmd_tap for %s as %s\n", name, tap_name); - ret = eth_dev_tap_create(dev, tap_name, remote_iface, fixed_mac_type); + ret = eth_dev_tap_create(dev, tap_name, remote_iface, &user_mac); leave: if (ret == -1) { @@ -1701,5 +1742,5 @@ enum ioctl_mode { RTE_PMD_REGISTER_ALIAS(net_tap, eth_tap); RTE_PMD_REGISTER_PARAM_STRING(net_tap, ETH_TAP_IFACE_ARG "= " - ETH_TAP_MAC_ARG "=" ETH_TAP_MAC_FIXED " " + ETH_TAP_MAC_ARG "=" ETH_TAP_MAC_ARG_FMT " " ETH_TAP_REMOTE_ARG "="); -- 1.9.1