From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Kuusisaari, Juhamatti (Infinera - FI/Espoo)" Subject: Re: [PATCH v8] net/pcap: physical interface MAC address support Date: Tue, 9 Oct 2018 04:30:28 +0000 Message-ID: References: <20181005202723.47967-1-ferruh.yigit@intel.com> <20181006004959.13097-1-ferruh.yigit@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable To: "dev@dpdk.org" Return-path: Received: from EUR01-HE1-obe.outbound.protection.outlook.com (mail-he1eur01on0060.outbound.protection.outlook.com [104.47.0.60]) by dpdk.org (Postfix) with ESMTP id 2B593160 for ; Tue, 9 Oct 2018 06:30:31 +0200 (CEST) In-Reply-To: <20181006004959.13097-1-ferruh.yigit@intel.com> Content-Language: en-US List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" > -----Original Message----- > From: Ferruh Yigit [mailto:ferruh.yigit@intel.com] > Sent: Saturday, October 06, 2018 3:50 AM > To: Bruce Richardson ; John McNamara > ; Marko Kovacevic > > Cc: dev@dpdk.org; Ferruh Yigit ; Juhamatti > Kuusisaari ; Juhamatti Kuusisaari > > Subject: [PATCH v8] net/pcap: physical interface MAC address support >=20 > CAUTION: This email originated from outside of the organization. Do not c= lick > links or open attachments unless you recognize the sender and know the > content is safe. >=20 >=20 > From: Juhamatti Kuusisaari >=20 > At the moment, PCAP interfaces use dummy MAC by default. This change > adds support for selecting PCAP physical interface MAC with phy_mac=3D1 > devarg. This allows to setup packet flows using the physical interface > MAC. >=20 > Signed-off-by: Juhamatti Kuusisaari > Signed-off-by: Ferruh Yigit > --- > v7: > * Add internal->phy_mac to be able to free data->mac_addrs > * code review comments applied > * doc format updates > * NOTE: FreeBSD functionality not tested >=20 > v8: > * don't access kvlist internals directly > * store phy_mac in pmd_devargs instead of passing as arg to function > --- > doc/guides/nics/pcap_ring.rst | 10 ++ > doc/guides/rel_notes/release_18_11.rst | 4 + > drivers/net/pcap/rte_eth_pcap.c | 163 +++++++++++++++++++++---- > 3 files changed, 156 insertions(+), 21 deletions(-) >=20 > diff --git a/doc/guides/nics/pcap_ring.rst b/doc/guides/nics/pcap_ring.rs= t > index 879e5430f..c1ef9196b 100644 > --- a/doc/guides/nics/pcap_ring.rst > +++ b/doc/guides/nics/pcap_ring.rst > @@ -96,6 +96,16 @@ The different stream types are: >=20 > iface=3Deth0 >=20 > +Runtime Config Options > +^^^^^^^^^^^^^^^^^^^^^^ > + > +- Use PCAP interface physical MAC > + > + In case ``iface=3D`` configuration is set, user may want to use the sel= ected > interface's physical MAC > + address. This can be done with a ``devarg`` ``phy_mac``, for example:: > + > + --vdev 'net_pcap0,iface=3Deth0,phy_mac=3D1' > + > Examples of Usage > ^^^^^^^^^^^^^^^^^ >=20 > diff --git a/doc/guides/rel_notes/release_18_11.rst > b/doc/guides/rel_notes/release_18_11.rst > index 89ca3317f..491d97f13 100644 > --- a/doc/guides/rel_notes/release_18_11.rst > +++ b/doc/guides/rel_notes/release_18_11.rst > @@ -98,6 +98,10 @@ New Features > * Support for runtime Rx and Tx queues setup. > * Support multicast MAC address set. >=20 > +* **Added a devarg to use PCAP interface physical MAC address.** > + A new devarg ``phy_mac`` was introduced to allow users to use physical > + MAC address of the selected PCAP interface. > + > * **Added Event Ethernet Tx Adapter.** >=20 > Added event ethernet Tx adapter library that provides configuration a= nd > diff --git a/drivers/net/pcap/rte_eth_pcap.c > b/drivers/net/pcap/rte_eth_pcap.c > index 8736010f0..51d405116 100644 > --- a/drivers/net/pcap/rte_eth_pcap.c > +++ b/drivers/net/pcap/rte_eth_pcap.c > @@ -7,6 +7,14 @@ > #include >=20 > #include > +#include > +#include > +#include > + > +#if defined(RTE_EXEC_ENV_BSDAPP) > +#include > +#include > +#endif >=20 > #include >=20 > @@ -17,6 +25,7 @@ > #include > #include > #include > +#include >=20 > #define RTE_ETH_PCAP_SNAPSHOT_LEN 65535 > #define RTE_ETH_PCAP_SNAPLEN ETHER_MAX_JUMBO_FRAME_LEN > @@ -29,6 +38,7 @@ > #define ETH_PCAP_RX_IFACE_IN_ARG "rx_iface_in" > #define ETH_PCAP_TX_IFACE_ARG "tx_iface" > #define ETH_PCAP_IFACE_ARG "iface" > +#define ETH_PCAP_PHY_MAC_ARG "phy_mac" >=20 > #define ETH_PCAP_ARG_MAXLEN 64 >=20 > @@ -70,6 +80,7 @@ struct pmd_internals { > struct ether_addr eth_addr; > int if_index; > int single_iface; > + int phy_mac; > }; >=20 > struct pmd_devargs { > @@ -80,6 +91,7 @@ struct pmd_devargs { > const char *name; > const char *type; > } queue[RTE_PMD_PCAP_MAX_QUEUES]; > + int phy_mac; > }; >=20 > static const char *valid_arguments[] =3D { > @@ -89,6 +101,7 @@ static const char *valid_arguments[] =3D { > ETH_PCAP_RX_IFACE_IN_ARG, > ETH_PCAP_TX_IFACE_ARG, > ETH_PCAP_IFACE_ARG, > + ETH_PCAP_PHY_MAC_ARG, > NULL > }; >=20 > @@ -859,6 +872,20 @@ open_tx_iface(const char *key, const char *value, > void *extra_args) > return open_iface(key, value, extra_args); > } >=20 > +static int > +select_phy_mac(const char *key __rte_unused, const char *value, > + void *extra_args) > +{ > + if (extra_args) { > + const int phy_mac =3D atoi(value); > + int *enable_phy_mac =3D extra_args; > + > + if (phy_mac) > + *enable_phy_mac =3D 1; > + } > + return 0; > +} > + > static struct rte_vdev_driver pmd_pcap_drv; >=20 > static int > @@ -894,6 +921,7 @@ pmd_init_internals(struct rte_vdev_device *vdev, > (*internals)->eth_addr =3D (struct ether_addr) { > .addr_bytes =3D { 0x02, 0x70, 0x63, 0x61, 0x70, iface_idx= ++ } > }; > + (*internals)->phy_mac =3D 0; > data =3D (*eth_dev)->data; > data->nb_rx_queues =3D (uint16_t)nb_rx_queues; > data->nb_tx_queues =3D (uint16_t)nb_tx_queues; > @@ -909,15 +937,96 @@ pmd_init_internals(struct rte_vdev_device *vdev, > return 0; > } >=20 > +static int > +eth_pcap_update_mac(const char *if_name, struct rte_eth_dev *eth_dev, > + const unsigned int numa_node) > +{ > +#if defined(RTE_EXEC_ENV_LINUXAPP) > + void *mac_addrs; > + struct ifreq ifr; > + int if_fd =3D socket(AF_INET, SOCK_DGRAM, 0); > + > + if (if_fd =3D=3D -1) > + return -1; > + > + rte_strscpy(ifr.ifr_name, if_name, sizeof(ifr.ifr_name)); > + if (ioctl(if_fd, SIOCGIFHWADDR, &ifr)) { > + close(if_fd); > + return -1; > + } > + > + mac_addrs =3D rte_zmalloc_socket(NULL, ETHER_ADDR_LEN, 0, > numa_node); > + if (!mac_addrs) { > + close(if_fd); > + return -1; > + } > + > + PMD_LOG(INFO, "Setting phy MAC for %s", if_name); > + eth_dev->data->mac_addrs =3D mac_addrs; > + rte_memcpy(eth_dev->data->mac_addrs[0].addr_bytes, > + ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN); > + > + close(if_fd); > + > + return 0; > + > +#elif defined(RTE_EXEC_ENV_BSDAPP) > + void *mac_addrs; > + struct if_msghdr *ifm; > + struct sockaddr_dl *sdl; > + int mib[6]; > + size_t len =3D 0; > + char *buf; > + > + mib[0] =3D CTL_NET; > + mib[1] =3D AF_ROUTE; > + mib[2] =3D 0; > + mib[3] =3D AF_LINK; > + mib[4] =3D NET_RT_IFLIST; > + mib[5] =3D if_nametoindex(if_name); > + > + if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) > + return -1; > + > + if (len =3D=3D 0) > + return -1; > + > + buf =3D rte_malloc(NULL, len, 0); > + if (!buf) > + return -1; > + > + if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { > + rte_free(buf); > + return -1; > + } > + ifm =3D (struct if_msghdr *)buf; > + sdl =3D (struct sockaddr_dl *)(ifm + 1); > + > + mac_addrs =3D rte_zmalloc_socket(NULL, ETHER_ADDR_LEN, 0, > numa_node); > + if (!mac_addrs) { > + rte_free(buf); > + return -1; > + } > + > + PMD_LOG(INFO, "Setting phy MAC for %s", if_name); > + eth_dev->data->mac_addrs =3D mac_addrs; > + rte_memcpy(eth_dev->data->mac_addrs[0].addr_bytes, > + LLADDR(sdl), ETHER_ADDR_LEN); > + > + rte_free(buf); > + > + return 0; > +#else > + return -1; > +#endif > +} > + > static int > eth_from_pcaps_common(struct rte_vdev_device *vdev, > struct pmd_devargs *rx_queues, const unsigned int nb_rx_q= ueues, > struct pmd_devargs *tx_queues, const unsigned int nb_tx_q= ueues, > - struct rte_kvargs *kvlist, struct pmd_internals **interna= ls, > - struct rte_eth_dev **eth_dev) > + struct pmd_internals **internals, struct rte_eth_dev **et= h_dev) > { > - struct rte_kvargs_pair *pair =3D NULL; > - unsigned int k_idx; > unsigned int i; >=20 > /* do some parameter checking */ > @@ -949,17 +1058,6 @@ eth_from_pcaps_common(struct rte_vdev_device > *vdev, > snprintf(tx->type, sizeof(tx->type), "%s", queue->type); > } >=20 > - for (k_idx =3D 0; k_idx < kvlist->count; k_idx++) { > - pair =3D &kvlist->pairs[k_idx]; > - if (strstr(pair->key, ETH_PCAP_IFACE_ARG) !=3D NULL) > - break; > - } > - > - if (pair =3D=3D NULL) > - (*internals)->if_index =3D 0; > - else > - (*internals)->if_index =3D if_nametoindex(pair->value); > - > return 0; > } >=20 > @@ -967,15 +1065,14 @@ static int > eth_from_pcaps(struct rte_vdev_device *vdev, > struct pmd_devargs *rx_queues, const unsigned int nb_rx_q= ueues, > struct pmd_devargs *tx_queues, const unsigned int nb_tx_q= ueues, > - struct rte_kvargs *kvlist, int single_iface, > - unsigned int using_dumpers) > + int single_iface, unsigned int using_dumpers) > { > struct pmd_internals *internals =3D NULL; > struct rte_eth_dev *eth_dev =3D NULL; > int ret; >=20 > ret =3D eth_from_pcaps_common(vdev, rx_queues, nb_rx_queues, > - tx_queues, nb_tx_queues, kvlist, &internals, ð_dev); > + tx_queues, nb_tx_queues, &internals, ð_dev); >=20 > if (ret < 0) > return ret; > @@ -983,6 +1080,18 @@ eth_from_pcaps(struct rte_vdev_device *vdev, > /* store weather we are using a single interface for rx/tx or not= */ > internals->single_iface =3D single_iface; >=20 > + if (single_iface) { > + internals->if_index =3D if_nametoindex(rx_queues->queue[0= ].name); > + > + /* phy_mac arg is applied only only if "iface" devarg is = provided */ > + if (rx_queues->phy_mac) { > + int ret =3D eth_pcap_update_mac(rx_queues->queue[= 0].name, > + eth_dev, vdev->device.numa_node); > + if (ret =3D=3D 0) > + internals->phy_mac =3D 1; > + } > + } > + > eth_dev->rx_pkt_burst =3D eth_pcap_rx; >=20 > if (using_dumpers) > @@ -1039,12 +1148,18 @@ pmd_pcap_probe(struct rte_vdev_device *dev) >=20 > ret =3D rte_kvargs_process(kvlist, ETH_PCAP_IFACE_ARG, > &open_rx_tx_iface, &pcaps); > - > if (ret < 0) > goto free_kvlist; >=20 > dumpers.queue[0] =3D pcaps.queue[0]; >=20 > + ret =3D rte_kvargs_process(kvlist, ETH_PCAP_PHY_MAC_ARG, > + &select_phy_mac, &pcaps.phy_mac); > + if (ret < 0) > + goto free_kvlist; > + > + dumpers.phy_mac =3D pcaps.phy_mac; > + > single_iface =3D 1; > pcaps.num_of_queue =3D 1; > dumpers.num_of_queue =3D 1; > @@ -1089,7 +1204,7 @@ pmd_pcap_probe(struct rte_vdev_device *dev) >=20 > create_eth: > ret =3D eth_from_pcaps(dev, &pcaps, pcaps.num_of_queue, &dumpers, > - dumpers.num_of_queue, kvlist, single_iface, is_tx_pcap); > + dumpers.num_of_queue, single_iface, is_tx_pcap); >=20 > free_kvlist: > rte_kvargs_free(kvlist); > @@ -1100,6 +1215,7 @@ pmd_pcap_probe(struct rte_vdev_device *dev) > static int > pmd_pcap_remove(struct rte_vdev_device *dev) > { > + struct pmd_internals *internals =3D NULL; > struct rte_eth_dev *eth_dev =3D NULL; >=20 > PMD_LOG(INFO, "Closing pcap ethdev on numa socket %d", > @@ -1113,6 +1229,10 @@ pmd_pcap_remove(struct rte_vdev_device *dev) > if (eth_dev =3D=3D NULL) > return -1; >=20 > + internals =3D eth_dev->data->dev_private; > + if (internals && internals->phy_mac) > + rte_free(eth_dev->data->mac_addrs); > + > rte_free(eth_dev->data->dev_private); >=20 > rte_eth_dev_release_port(eth_dev); > @@ -1133,7 +1253,8 @@ RTE_PMD_REGISTER_PARAM_STRING(net_pcap, > ETH_PCAP_RX_IFACE_ARG "=3D " > ETH_PCAP_RX_IFACE_IN_ARG "=3D " > ETH_PCAP_TX_IFACE_ARG "=3D " > - ETH_PCAP_IFACE_ARG "=3D"); > + ETH_PCAP_IFACE_ARG "=3D " > + ETH_PCAP_PHY_MAC_ARG "=3D"); Acked-by: Juhamatti Kuusisaari > RTE_INIT(eth_pcap_init_log) > { > -- > 2.17.1