net/mlx5: fix VLAN stripping indication
[dpdk.git] / drivers / net / af_packet / rte_eth_af_packet.c
index c841ddc..2f87553 100644 (file)
@@ -161,6 +161,12 @@ eth_af_packet_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
                pbuf = (uint8_t *) ppd + ppd->tp_mac;
                memcpy(rte_pktmbuf_mtod(mbuf, void *), pbuf, rte_pktmbuf_data_len(mbuf));
 
+               /* check for vlan info */
+               if (ppd->tp_status & TP_STATUS_VLAN_VALID) {
+                       mbuf->vlan_tci = ppd->tp_vlan_tci;
+                       mbuf->ol_flags |= (PKT_RX_VLAN_PKT | PKT_RX_VLAN_STRIPPED);
+               }
+
                /* release incoming frame and advance ring buffer */
                ppd->tp_status = TP_STATUS_KERNEL;
                if (++framenum >= framecount)
@@ -214,6 +220,14 @@ eth_af_packet_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
                        continue;
                }
 
+               /* insert vlan info if necessary */
+               if (mbuf->ol_flags & PKT_TX_VLAN_PKT) {
+                       if (rte_vlan_insert(&mbuf)) {
+                               rte_pktmbuf_free(mbuf);
+                               continue;
+                       }
+               }
+
                /* point at the next incoming frame */
                if ((ppd->tp_status != TP_STATUS_AVAILABLE) &&
                    (poll(&pfd, 1, -1) < 0))
@@ -447,6 +461,43 @@ eth_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu)
        return 0;
 }
 
+static void
+eth_dev_change_flags(char *if_name, uint32_t flags, uint32_t mask)
+{
+       struct ifreq ifr;
+       int s;
+
+       s = socket(PF_INET, SOCK_DGRAM, 0);
+       if (s < 0)
+               return;
+
+       strncpy(ifr.ifr_name, if_name, IFNAMSIZ);
+       if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
+               goto out;
+       ifr.ifr_flags &= mask;
+       ifr.ifr_flags |= flags;
+       if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0)
+               goto out;
+out:
+       close(s);
+}
+
+static void
+eth_dev_promiscuous_enable(struct rte_eth_dev *dev)
+{
+       struct pmd_internals *internals = dev->data->dev_private;
+
+       eth_dev_change_flags(internals->if_name, IFF_PROMISC, ~0);
+}
+
+static void
+eth_dev_promiscuous_disable(struct rte_eth_dev *dev)
+{
+       struct pmd_internals *internals = dev->data->dev_private;
+
+       eth_dev_change_flags(internals->if_name, 0, ~IFF_PROMISC);
+}
+
 static const struct eth_dev_ops ops = {
        .dev_start = eth_dev_start,
        .dev_stop = eth_dev_stop,
@@ -454,6 +505,8 @@ static const struct eth_dev_ops ops = {
        .dev_configure = eth_dev_configure,
        .dev_infos_get = eth_dev_info,
        .mtu_set = eth_dev_mtu_set,
+       .promiscuous_enable = eth_dev_promiscuous_enable,
+       .promiscuous_disable = eth_dev_promiscuous_disable,
        .rx_queue_setup = eth_rx_queue_setup,
        .tx_queue_setup = eth_tx_queue_setup,
        .rx_queue_release = eth_queue_release,