DPDK patches and discussions
 help / color / mirror / Atom feed
From: Pascal Mazon <pascal.mazon@6wind.com>
To: keith.wiles@intel.com
Cc: dev@dpdk.org, Pascal Mazon <pascal.mazon@6wind.com>
Subject: [dpdk-dev] [PATCH v3 2/3] net/tap: fix null MAC address at init
Date: Fri, 31 Mar 2017 15:54:10 +0200	[thread overview]
Message-ID: <3f667d40be2f2d4db572bfa4200561e5818514b6.1490966849.git.pascal.mazon@6wind.com> (raw)
In-Reply-To: <cover.1490966849.git.pascal.mazon@6wind.com>

Immediately after init (probing), the device MAC address is all zeroes.
It should be possible to get a correct MAC address as soon as that,
without need for a dev_configure().

With this patch, a MAC address is set in eth_dev_tap_create()
explicitly. It either comes from the remote if any was configured, or is
randomly generated. In any case, the device MAC address is guaranteed to
be the correct one when the tap netdevice actually gets created in
tun_alloc().

Fixes: 77a92d9f33a8 ("net/tap: add MAC address management")
Fixes: 7d1aa96ee105 ("net/tap: add remote netdevice traffic capture")

Signed-off-by: Pascal Mazon <pascal.mazon@6wind.com>
---
 drivers/net/tap/rte_eth_tap.c | 85 ++++++++++++++++++++++++-------------------
 1 file changed, 48 insertions(+), 37 deletions(-)

diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c
index 6567bba75b47..72897adcce3b 100644
--- a/drivers/net/tap/rte_eth_tap.c
+++ b/drivers/net/tap/rte_eth_tap.c
@@ -108,9 +108,16 @@ tap_trigger_cb(int sig __rte_unused)
 	tap_trigger = (tap_trigger + 1) | 0x80000000;
 }
 
+/* Specifies on what netdevices the ioctl should be applied */
+enum ioctl_mode {
+	LOCAL_AND_REMOTE,
+	LOCAL_ONLY,
+	REMOTE_ONLY,
+};
+
 static int
 tap_ioctl(struct pmd_internals *pmd, unsigned long request,
-	  struct ifreq *ifr, int set);
+	  struct ifreq *ifr, int set, enum ioctl_mode mode);
 
 static int tap_intr_handle_set(struct rte_eth_dev *dev, int set);
 
@@ -222,10 +229,15 @@ tun_alloc(struct pmd_internals *pmd, uint16_t qid)
 	if (qid == 0) {
 		struct ifreq ifr;
 
-		if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0) < 0)
-			goto error;
-		rte_memcpy(&pmd->eth_addr, ifr.ifr_hwaddr.sa_data,
+		/*
+		 * pmd->eth_addr contains the desired MAC, either from remote
+		 * or from a random assignment. Sync it with the tap netdevice.
+		 */
+		ifr.ifr_hwaddr.sa_family = AF_LOCAL;
+		rte_memcpy(ifr.ifr_hwaddr.sa_data, &pmd->eth_addr,
 			   ETHER_ADDR_LEN);
+		if (tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 0, LOCAL_ONLY) < 0)
+			goto error;
 
 		pmd->if_index = if_nametoindex(pmd->name);
 		if (!pmd->if_index) {
@@ -437,27 +449,22 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 
 static int
 tap_ioctl(struct pmd_internals *pmd, unsigned long request,
-	  struct ifreq *ifr, int set)
+	  struct ifreq *ifr, int set, enum ioctl_mode mode)
 {
 	short req_flags = ifr->ifr_flags;
-	int remote = !!pmd->remote_if_index;
+	int remote = pmd->remote_if_index &&
+		(mode == REMOTE_ONLY || mode == LOCAL_AND_REMOTE);
 
+	if (!pmd->remote_if_index && mode == REMOTE_ONLY)
+		return 0;
 	/*
 	 * If there is a remote netdevice, apply ioctl on it, then apply it on
 	 * the tap netdevice.
 	 */
-	if (request == SIOCGIFFLAGS && !set) {
-		/*
-		 * Special case for getting flags. If set is given,
-		 * then return the flags from the remote netdevice only.
-		 * Otherwise return the flags from the tap netdevice.
-		 */
-		remote = 0;
-	}
 apply:
 	if (remote)
 		snprintf(ifr->ifr_name, IFNAMSIZ, "%s", pmd->remote_iface);
-	else
+	else if (mode == LOCAL_ONLY || mode == LOCAL_AND_REMOTE)
 		snprintf(ifr->ifr_name, IFNAMSIZ, "%s", pmd->name);
 	switch (request) {
 	case SIOCSIFFLAGS:
@@ -470,16 +477,7 @@ tap_ioctl(struct pmd_internals *pmd, unsigned long request,
 			ifr->ifr_flags &= ~req_flags;
 		break;
 	case SIOCGIFFLAGS:
-		if (remote && set)
-			remote = 0; /* don't loop */
-		break;
 	case SIOCGIFHWADDR:
-		/* Set remote MAC on the tap netdevice */
-		if (!remote && pmd->remote_if_index) {
-			request = SIOCSIFHWADDR;
-			goto apply;
-		}
-		break;
 	case SIOCSIFHWADDR:
 	case SIOCSIFMTU:
 		break;
@@ -490,7 +488,7 @@ tap_ioctl(struct pmd_internals *pmd, unsigned long request,
 	}
 	if (ioctl(pmd->ioctl_sock, request, ifr) < 0)
 		goto error;
-	if (remote--)
+	if (remote-- && mode == LOCAL_AND_REMOTE)
 		goto apply;
 	return 0;
 
@@ -507,7 +505,7 @@ tap_link_set_down(struct rte_eth_dev *dev)
 	struct ifreq ifr = { .ifr_flags = IFF_UP };
 
 	dev->data->dev_link.link_status = ETH_LINK_DOWN;
-	return tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0);
+	return tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0, LOCAL_AND_REMOTE);
 }
 
 static int
@@ -517,7 +515,7 @@ tap_link_set_up(struct rte_eth_dev *dev)
 	struct ifreq ifr = { .ifr_flags = IFF_UP };
 
 	dev->data->dev_link.link_status = ETH_LINK_UP;
-	return tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1);
+	return tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1, LOCAL_AND_REMOTE);
 }
 
 static int
@@ -702,14 +700,14 @@ tap_link_update(struct rte_eth_dev *dev, int wait_to_complete __rte_unused)
 	struct ifreq ifr = { .ifr_flags = 0 };
 
 	if (pmd->remote_if_index) {
-		tap_ioctl(pmd, SIOCGIFFLAGS, &ifr, 1);
+		tap_ioctl(pmd, SIOCGIFFLAGS, &ifr, 0, REMOTE_ONLY);
 		if (!(ifr.ifr_flags & IFF_UP) ||
 		    !(ifr.ifr_flags & IFF_RUNNING)) {
 			dev_link->link_status = ETH_LINK_DOWN;
 			return 0;
 		}
 	}
-	tap_ioctl(pmd, SIOCGIFFLAGS, &ifr, 0);
+	tap_ioctl(pmd, SIOCGIFFLAGS, &ifr, 0, LOCAL_ONLY);
 	dev_link->link_status =
 		((ifr.ifr_flags & IFF_UP) && (ifr.ifr_flags & IFF_RUNNING) ?
 		 ETH_LINK_UP :
@@ -724,7 +722,7 @@ tap_promisc_enable(struct rte_eth_dev *dev)
 	struct ifreq ifr = { .ifr_flags = IFF_PROMISC };
 
 	dev->data->promiscuous = 1;
-	tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1);
+	tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1, LOCAL_AND_REMOTE);
 	if (pmd->remote_if_index)
 		tap_flow_implicit_create(pmd, TAP_REMOTE_PROMISC);
 }
@@ -736,7 +734,7 @@ tap_promisc_disable(struct rte_eth_dev *dev)
 	struct ifreq ifr = { .ifr_flags = IFF_PROMISC };
 
 	dev->data->promiscuous = 0;
-	tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0);
+	tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0, LOCAL_AND_REMOTE);
 	if (pmd->remote_if_index)
 		tap_flow_implicit_destroy(pmd, TAP_REMOTE_PROMISC);
 }
@@ -748,7 +746,7 @@ tap_allmulti_enable(struct rte_eth_dev *dev)
 	struct ifreq ifr = { .ifr_flags = IFF_ALLMULTI };
 
 	dev->data->all_multicast = 1;
-	tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1);
+	tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 1, LOCAL_AND_REMOTE);
 	if (pmd->remote_if_index)
 		tap_flow_implicit_create(pmd, TAP_REMOTE_ALLMULTI);
 }
@@ -760,7 +758,7 @@ tap_allmulti_disable(struct rte_eth_dev *dev)
 	struct ifreq ifr = { .ifr_flags = IFF_ALLMULTI };
 
 	dev->data->all_multicast = 0;
-	tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0);
+	tap_ioctl(pmd, SIOCSIFFLAGS, &ifr, 0, LOCAL_AND_REMOTE);
 	if (pmd->remote_if_index)
 		tap_flow_implicit_destroy(pmd, TAP_REMOTE_ALLMULTI);
 }
@@ -780,7 +778,7 @@ tap_mac_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 
 	ifr.ifr_hwaddr.sa_family = AF_LOCAL;
 	rte_memcpy(ifr.ifr_hwaddr.sa_data, mac_addr, ETHER_ADDR_LEN);
-	if (tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1) < 0)
+	if (tap_ioctl(pmd, SIOCSIFHWADDR, &ifr, 1, LOCAL_AND_REMOTE) < 0)
 		return;
 	rte_memcpy(&pmd->eth_addr, mac_addr, ETHER_ADDR_LEN);
 }
@@ -811,7 +809,8 @@ tap_setup_queue(struct rte_eth_dev *dev,
 				struct ifreq ifr;
 
 				ifr.ifr_mtu = dev->data->mtu;
-				if (tap_ioctl(pmd, SIOCSIFMTU, &ifr, 1) < 0) {
+				if (tap_ioctl(pmd, SIOCSIFMTU, &ifr, 1,
+					      LOCAL_AND_REMOTE) < 0) {
 					close(fd);
 					return -1;
 				}
@@ -966,7 +965,7 @@ tap_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
 	struct ifreq ifr = { .ifr_mtu = mtu };
 	int err = 0;
 
-	err = tap_ioctl(pmd, SIOCSIFMTU, &ifr, 1);
+	err = tap_ioctl(pmd, SIOCSIFMTU, &ifr, 1, LOCAL_AND_REMOTE);
 	if (!err)
 		dev->data->mtu = mtu;
 
@@ -1210,13 +1209,25 @@ eth_dev_tap_create(const char *name, char *tap_name, char *remote_iface)
 	 */
 	pmd->nlsk_fd = nl_init(0);
 	if (strlen(remote_iface)) {
+		struct ifreq ifr;
+
 		pmd->remote_if_index = if_nametoindex(remote_iface);
 		snprintf(pmd->remote_iface, RTE_ETH_NAME_MAX_LEN,
 			 "%s", remote_iface);
-		if (!pmd->remote_if_index)
+		if (!pmd->remote_if_index) {
 			RTE_LOG(ERR, PMD, "Could not find %s ifindex: "
 				"remote interface will remain unconfigured\n",
 				remote_iface);
+			return 0;
+		}
+		if (tap_ioctl(pmd, SIOCGIFHWADDR, &ifr, 0, REMOTE_ONLY) < 0) {
+			RTE_LOG(ERR, PMD, "Could not get remote MAC address\n");
+			goto error_exit;
+		}
+		rte_memcpy(&pmd->eth_addr, ifr.ifr_hwaddr.sa_data,
+			   ETHER_ADDR_LEN);
+	} else {
+		eth_random_addr((uint8_t *)&pmd->eth_addr);
 	}
 
 	return 0;
-- 
2.12.0.306.g4a9b9b3

  parent reply	other threads:[~2017-03-31 13:55 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-29  9:44 [dpdk-dev] [PATCH 1/2] net/tap: update netlink error code management Pascal Mazon
2017-03-29  9:44 ` [dpdk-dev] [PATCH 2/2] net/tap: update redirection rule after MAC change Pascal Mazon
2017-03-31 13:02   ` [dpdk-dev] [PATCH v2 1/2] net/tap: fix null MAC address at init Pascal Mazon
2017-03-31 13:54     ` [dpdk-dev] [PATCH v3 0/3] net/tap: netlink and MAC address fixes Pascal Mazon
2017-03-31 13:54       ` [dpdk-dev] [PATCH v3 1/3] net/tap: update netlink error code management Pascal Mazon
2017-03-31 13:54       ` Pascal Mazon [this message]
2017-03-31 13:54       ` [dpdk-dev] [PATCH v3 3/3] net/tap: fix redirection rule after MAC change Pascal Mazon
2017-04-03 13:11       ` [dpdk-dev] [PATCH v3 0/3] net/tap: netlink and MAC address fixes Ferruh Yigit
2017-03-31 13:02   ` [dpdk-dev] [PATCH v2 2/2] net/tap: fix redirection rule after MAC change Pascal Mazon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3f667d40be2f2d4db572bfa4200561e5818514b6.1490966849.git.pascal.mazon@6wind.com \
    --to=pascal.mazon@6wind.com \
    --cc=dev@dpdk.org \
    --cc=keith.wiles@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).