All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Kuusisaari, Juhamatti (Infinera - FI/Espoo)" <juhamatti.kuusisaari@coriant.com>
To: "dev@dpdk.org" <dev@dpdk.org>
Subject: Re: [PATCH v8] net/pcap: physical interface MAC address support
Date: Tue, 9 Oct 2018 04:30:28 +0000	[thread overview]
Message-ID: <HE1PR0402MB2921A6B99FEDF5E0603D89BF9DE70@HE1PR0402MB2921.eurprd04.prod.outlook.com> (raw)
In-Reply-To: <20181006004959.13097-1-ferruh.yigit@intel.com>



> -----Original Message-----
> From: Ferruh Yigit [mailto:ferruh.yigit@intel.com]
> Sent: Saturday, October 06, 2018 3:50 AM
> To: Bruce Richardson <bruce.richardson@intel.com>; John McNamara
> <john.mcnamara@intel.com>; Marko Kovacevic
> <marko.kovacevic@intel.com>
> Cc: dev@dpdk.org; Ferruh Yigit <ferruh.yigit@intel.com>; Juhamatti
> Kuusisaari <Juhamatti.Kuusisaari@coriant.com>; Juhamatti Kuusisaari
> <juhamatti.kuusisaari@coriant.com>
> Subject: [PATCH v8] net/pcap: physical interface MAC address support
> 
> CAUTION: This email originated from outside of the organization. Do not click
> links or open attachments unless you recognize the sender and know the
> content is safe.
> 
> 
> From: Juhamatti Kuusisaari <Juhamatti.Kuusisaari@coriant.com>
> 
> At the moment, PCAP interfaces use dummy MAC by default. This change
> adds support for selecting PCAP physical interface MAC with phy_mac=1
> devarg. This allows to setup packet flows using the physical interface
> MAC.
> 
> Signed-off-by: Juhamatti Kuusisaari <juhamatti.kuusisaari@coriant.com>
> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> ---
> 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
> 
> 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(-)
> 
> diff --git a/doc/guides/nics/pcap_ring.rst b/doc/guides/nics/pcap_ring.rst
> 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:
> 
>          iface=eth0
> 
> +Runtime Config Options
> +^^^^^^^^^^^^^^^^^^^^^^
> +
> +- Use PCAP interface physical MAC
> +
> + In case ``iface=`` configuration is set, user may want to use the selected
> interface's physical MAC
> + address. This can be done with a ``devarg`` ``phy_mac``, for example::
> +
> +   --vdev 'net_pcap0,iface=eth0,phy_mac=1'
> +
>  Examples of Usage
>  ^^^^^^^^^^^^^^^^^
> 
> 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.
> 
> +* **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.**
> 
>    Added event ethernet Tx adapter library that  provides configuration and
> 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 <time.h>
> 
>  #include <net/if.h>
> +#include <sys/socket.h>
> +#include <sys/ioctl.h>
> +#include <unistd.h>
> +
> +#if defined(RTE_EXEC_ENV_BSDAPP)
> +#include <sys/sysctl.h>
> +#include <net/if_dl.h>
> +#endif
> 
>  #include <pcap.h>
> 
> @@ -17,6 +25,7 @@
>  #include <rte_malloc.h>
>  #include <rte_mbuf.h>
>  #include <rte_bus_vdev.h>
> +#include <rte_string_fns.h>
> 
>  #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"
> 
>  #define ETH_PCAP_ARG_MAXLEN    64
> 
> @@ -70,6 +80,7 @@ struct pmd_internals {
>         struct ether_addr eth_addr;
>         int if_index;
>         int single_iface;
> +       int phy_mac;
>  };
> 
>  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;
>  };
> 
>  static const char *valid_arguments[] = {
> @@ -89,6 +101,7 @@ static const char *valid_arguments[] = {
>         ETH_PCAP_RX_IFACE_IN_ARG,
>         ETH_PCAP_TX_IFACE_ARG,
>         ETH_PCAP_IFACE_ARG,
> +       ETH_PCAP_PHY_MAC_ARG,
>         NULL
>  };
> 
> @@ -859,6 +872,20 @@ open_tx_iface(const char *key, const char *value,
> void *extra_args)
>         return open_iface(key, value, extra_args);
>  }
> 
> +static int
> +select_phy_mac(const char *key __rte_unused, const char *value,
> +               void *extra_args)
> +{
> +       if (extra_args) {
> +               const int phy_mac = atoi(value);
> +               int *enable_phy_mac = extra_args;
> +
> +               if (phy_mac)
> +                       *enable_phy_mac = 1;
> +       }
> +       return 0;
> +}
> +
>  static struct rte_vdev_driver pmd_pcap_drv;
> 
>  static int
> @@ -894,6 +921,7 @@ pmd_init_internals(struct rte_vdev_device *vdev,
>         (*internals)->eth_addr = (struct ether_addr) {
>                 .addr_bytes = { 0x02, 0x70, 0x63, 0x61, 0x70, iface_idx++ }
>         };
> +       (*internals)->phy_mac = 0;
>         data = (*eth_dev)->data;
>         data->nb_rx_queues = (uint16_t)nb_rx_queues;
>         data->nb_tx_queues = (uint16_t)nb_tx_queues;
> @@ -909,15 +937,96 @@ pmd_init_internals(struct rte_vdev_device *vdev,
>         return 0;
>  }
> 
> +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 = socket(AF_INET, SOCK_DGRAM, 0);
> +
> +       if (if_fd == -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 = 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 = 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 = 0;
> +       char *buf;
> +
> +       mib[0] = CTL_NET;
> +       mib[1] = AF_ROUTE;
> +       mib[2] = 0;
> +       mib[3] = AF_LINK;
> +       mib[4] = NET_RT_IFLIST;
> +       mib[5] = if_nametoindex(if_name);
> +
> +       if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0)
> +               return -1;
> +
> +       if (len == 0)
> +               return -1;
> +
> +       buf = rte_malloc(NULL, len, 0);
> +       if (!buf)
> +               return -1;
> +
> +       if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
> +               rte_free(buf);
> +               return -1;
> +       }
> +       ifm = (struct if_msghdr *)buf;
> +       sdl = (struct sockaddr_dl *)(ifm + 1);
> +
> +       mac_addrs = 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 = 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_queues,
>                 struct pmd_devargs *tx_queues, const unsigned int nb_tx_queues,
> -               struct rte_kvargs *kvlist, struct pmd_internals **internals,
> -               struct rte_eth_dev **eth_dev)
> +               struct pmd_internals **internals, struct rte_eth_dev **eth_dev)
>  {
> -       struct rte_kvargs_pair *pair = NULL;
> -       unsigned int k_idx;
>         unsigned int i;
> 
>         /* 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);
>         }
> 
> -       for (k_idx = 0; k_idx < kvlist->count; k_idx++) {
> -               pair = &kvlist->pairs[k_idx];
> -               if (strstr(pair->key, ETH_PCAP_IFACE_ARG) != NULL)
> -                       break;
> -       }
> -
> -       if (pair == NULL)
> -               (*internals)->if_index = 0;
> -       else
> -               (*internals)->if_index = if_nametoindex(pair->value);
> -
>         return 0;
>  }
> 
> @@ -967,15 +1065,14 @@ static int
>  eth_from_pcaps(struct rte_vdev_device *vdev,
>                 struct pmd_devargs *rx_queues, const unsigned int nb_rx_queues,
>                 struct pmd_devargs *tx_queues, const unsigned int nb_tx_queues,
> -               struct rte_kvargs *kvlist, int single_iface,
> -               unsigned int using_dumpers)
> +               int single_iface, unsigned int using_dumpers)
>  {
>         struct pmd_internals *internals = NULL;
>         struct rte_eth_dev *eth_dev = NULL;
>         int ret;
> 
>         ret = eth_from_pcaps_common(vdev, rx_queues, nb_rx_queues,
> -               tx_queues, nb_tx_queues, kvlist, &internals, &eth_dev);
> +               tx_queues, nb_tx_queues, &internals, &eth_dev);
> 
>         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 = single_iface;
> 
> +       if (single_iface) {
> +               internals->if_index = 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 = eth_pcap_update_mac(rx_queues->queue[0].name,
> +                                       eth_dev, vdev->device.numa_node);
> +                       if (ret == 0)
> +                               internals->phy_mac = 1;
> +               }
> +       }
> +
>         eth_dev->rx_pkt_burst = eth_pcap_rx;
> 
>         if (using_dumpers)
> @@ -1039,12 +1148,18 @@ pmd_pcap_probe(struct rte_vdev_device *dev)
> 
>                 ret = rte_kvargs_process(kvlist, ETH_PCAP_IFACE_ARG,
>                                 &open_rx_tx_iface, &pcaps);
> -
>                 if (ret < 0)
>                         goto free_kvlist;
> 
>                 dumpers.queue[0] = pcaps.queue[0];
> 
> +               ret = rte_kvargs_process(kvlist, ETH_PCAP_PHY_MAC_ARG,
> +                               &select_phy_mac, &pcaps.phy_mac);
> +               if (ret < 0)
> +                       goto free_kvlist;
> +
> +               dumpers.phy_mac = pcaps.phy_mac;
> +
>                 single_iface = 1;
>                 pcaps.num_of_queue = 1;
>                 dumpers.num_of_queue = 1;
> @@ -1089,7 +1204,7 @@ pmd_pcap_probe(struct rte_vdev_device *dev)
> 
>  create_eth:
>         ret = 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);
> 
>  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 = NULL;
>         struct rte_eth_dev *eth_dev = NULL;
> 
>         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 == NULL)
>                 return -1;
> 
> +       internals = eth_dev->data->dev_private;
> +       if (internals && internals->phy_mac)
> +               rte_free(eth_dev->data->mac_addrs);
> +
>         rte_free(eth_dev->data->dev_private);
> 
>         rte_eth_dev_release_port(eth_dev);
> @@ -1133,7 +1253,8 @@ RTE_PMD_REGISTER_PARAM_STRING(net_pcap,
>         ETH_PCAP_RX_IFACE_ARG "=<ifc> "
>         ETH_PCAP_RX_IFACE_IN_ARG "=<ifc> "
>         ETH_PCAP_TX_IFACE_ARG "=<ifc> "
> -       ETH_PCAP_IFACE_ARG "=<ifc>");
> +       ETH_PCAP_IFACE_ARG "=<ifc> "
> +       ETH_PCAP_PHY_MAC_ARG "=<int>");

Acked-by: Juhamatti Kuusisaari <juhamatti.kuusisaari@coriant.com>

>  RTE_INIT(eth_pcap_init_log)
>  {
> --
> 2.17.1

  parent reply	other threads:[~2018-10-09  4:30 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-06 16:56 [PATCH v5] net/pcap: physical interface MAC address support Juhamatti Kuusisaari
2018-09-10 12:03 ` Ferruh Yigit
2018-09-10 17:20   ` Kuusisaari, Juhamatti (Coriant - FI/Espoo)
2018-09-10 16:55 ` [PATCH v6] " Juhamatti Kuusisaari
2018-09-11 15:35   ` Ferruh Yigit
2018-10-01  7:30     ` Kuusisaari, Juhamatti (Coriant - FI/Espoo)
2018-10-05 20:27   ` [PATCH v7] " Ferruh Yigit
2018-10-06  0:49     ` [PATCH v8] " Ferruh Yigit
2018-10-08 12:14       ` Ferruh Yigit
2018-10-09  4:30       ` Kuusisaari, Juhamatti (Infinera - FI/Espoo) [this message]
2018-10-09 12:04         ` Ferruh Yigit

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=HE1PR0402MB2921A6B99FEDF5E0603D89BF9DE70@HE1PR0402MB2921.eurprd04.prod.outlook.com \
    --to=juhamatti.kuusisaari@coriant.com \
    --cc=dev@dpdk.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.