diff options
author | Maxim Uvarov <maxim.uvarov@linaro.org> | 2015-06-08 10:07:22 +0300 |
---|---|---|
committer | Zoltan Kiss <zoltan.kiss@linaro.org> | 2015-06-09 19:34:50 +0100 |
commit | 19121fd26494c136b3ec5734dccd26abc0751335 (patch) | |
tree | b0c1a106c2b3ca8a35f2e714e6eb138efa6ac640 | |
parent | 3000df7d88b57af6ed2c1c2b383e1966818d556f (diff) |
dpdk: pktio implement promisc mode on vdevs
DPDK PMD vdev like pcap does not support switching promisc mode.
Use system calls for corresponding devices.
Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
Signed-off-by: Zoltan Kiss <zoltan.kiss@linaro.org>
-rw-r--r-- | platform/linux-dpdk/include/odp_packet_dpdk.h | 2 | ||||
-rw-r--r-- | platform/linux-dpdk/odp_packet_dpdk.c | 5 | ||||
-rw-r--r-- | platform/linux-dpdk/odp_packet_io.c | 87 |
3 files changed, 91 insertions, 3 deletions
diff --git a/platform/linux-dpdk/include/odp_packet_dpdk.h b/platform/linux-dpdk/include/odp_packet_dpdk.h index ced4f5b63..608e4799b 100644 --- a/platform/linux-dpdk/include/odp_packet_dpdk.h +++ b/platform/linux-dpdk/include/odp_packet_dpdk.h @@ -81,6 +81,8 @@ typedef struct { char ifname[32]; uint8_t portid; uint16_t queueid; + odp_bool_t vdev_sysc_promisc; /**< promiscuous mode defined with + system call */ } pkt_dpdk_t; /** diff --git a/platform/linux-dpdk/odp_packet_dpdk.c b/platform/linux-dpdk/odp_packet_dpdk.c index 472cb1b4a..2b6a8c8a3 100644 --- a/platform/linux-dpdk/odp_packet_dpdk.c +++ b/platform/linux-dpdk/odp_packet_dpdk.c @@ -171,6 +171,11 @@ int setup_pkt_dpdk(pkt_dpdk_t * const pkt_dpdk, const char *netdev, } rte_eth_promiscuous_enable(portid); + /* Some DPDK PMD vdev like pcap do not support promisc mode change. Use + * system call for them. */ + if (!rte_eth_promiscuous_get(portid)) + pkt_dpdk->vdev_sysc_promisc = 1; + rte_eth_allmulticast_enable(portid); return 0; } diff --git a/platform/linux-dpdk/odp_packet_io.c b/platform/linux-dpdk/odp_packet_io.c index 94c8f5920..d47b3ee1a 100644 --- a/platform/linux-dpdk/odp_packet_io.c +++ b/platform/linux-dpdk/odp_packet_io.c @@ -702,9 +702,53 @@ int pktin_poll(pktio_entry_t *entry) return 0; } +static int _dpdk_vdev_promisc_mode_set(uint8_t port_id, int enable) +{ + struct rte_eth_dev_info dev_info = {0}; + struct ifreq ifr; + int ret; + int sockfd; + + rte_eth_dev_info_get(port_id, &dev_info); + if_indextoname(dev_info.if_index, ifr.ifr_name); + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + + ret = ioctl(sockfd, SIOCGIFFLAGS, &ifr); + if (ret < 0) { + close(sockfd); + ODP_DBG("ioctl SIOCGIFFLAGS error\n"); + return -1; + } + + if (enable) + ifr.ifr_flags |= IFF_PROMISC; + else + ifr.ifr_flags &= ~(IFF_PROMISC); + + ret = ioctl(sockfd, SIOCSIFFLAGS, &ifr); + if (ret < 0) { + close(sockfd); + ODP_DBG("ioctl SIOCSIFFLAGS error\n"); + return -1; + } + + ret = ioctl(sockfd, SIOCGIFMTU, &ifr); + if (ret < 0) { + close(sockfd); + ODP_DBG("ioctl SIOCGIFMTU error\n"); + return -1; + } + + ODP_DBG("vdev promisc set to %d\n", enable); + close(sockfd); + return 0; +} + int odp_pktio_promisc_mode_set(odp_pktio_t id, odp_bool_t enable) { pktio_entry_t *entry; + uint8_t portid; + int ret; entry = get_pktio_entry(id); if (entry == NULL) { @@ -727,19 +771,51 @@ int odp_pktio_promisc_mode_set(odp_pktio_t id, odp_bool_t enable) return 0; } + portid = entry->s.pkt_dpdk.portid; if (enable) - rte_eth_promiscuous_enable(entry->s.pkt_dpdk.portid); + rte_eth_promiscuous_enable(portid); else - rte_eth_promiscuous_disable(entry->s.pkt_dpdk.portid); + rte_eth_promiscuous_disable(portid); + + if (entry->s.pkt_dpdk.vdev_sysc_promisc) { + ret = _dpdk_vdev_promisc_mode_set(portid, enable); + if (ret < 0) + ODP_DBG("vdev promisc mode fail\n"); + } unlock_entry(entry); return 0; } +static int _dpdk_vdev_promisc_mode(uint8_t port_id) +{ + struct rte_eth_dev_info dev_info = {0}; + struct ifreq ifr; + int ret; + int sockfd; + + rte_eth_dev_info_get(port_id, &dev_info); + if_indextoname(dev_info.if_index, ifr.ifr_name); + sockfd = socket(AF_INET, SOCK_DGRAM, 0); + ret = ioctl(sockfd, SIOCGIFFLAGS, &ifr); + close(sockfd); + if (ret < 0) { + ODP_DBG("ioctl SIOCGIFFLAGS error\n"); + return -1; + } + + if (ifr.ifr_flags & IFF_PROMISC) { + ODP_DBG("promisc is 1\n"); + return 1; + } else + return 0; +} + int odp_pktio_promisc_mode(odp_pktio_t id) { pktio_entry_t *entry; int promisc; + uint8_t portid; entry = get_pktio_entry(id); if (entry == NULL) { @@ -755,7 +831,12 @@ int odp_pktio_promisc_mode(odp_pktio_t id) return -1; } - promisc = rte_eth_promiscuous_get(entry->s.pkt_dpdk.portid); + portid = entry->s.pkt_dpdk.portid; + + if (entry->s.pkt_dpdk.vdev_sysc_promisc) + promisc = _dpdk_vdev_promisc_mode(portid); + else + promisc = rte_eth_promiscuous_get(portid); unlock_entry(entry); |