net: introduce functions to verify L4 checksums
[dpdk.git] / drivers / net / tap / rte_eth_tap.c
index d1e8279..843dbc5 100644 (file)
@@ -7,8 +7,8 @@
 #include <rte_byteorder.h>
 #include <rte_common.h>
 #include <rte_mbuf.h>
-#include <rte_ethdev_driver.h>
-#include <rte_ethdev_vdev.h>
+#include <ethdev_driver.h>
+#include <ethdev_vdev.h>
 #include <rte_malloc.h>
 #include <rte_bus_vdev.h>
 #include <rte_kvargs.h>
@@ -303,6 +303,7 @@ tap_verify_csum(struct rte_mbuf *mbuf)
        uint16_t cksum = 0;
        void *l3_hdr;
        void *l4_hdr;
+       struct rte_udp_hdr *udp_hdr;
 
        if (l2 == RTE_PTYPE_L2_ETHER_VLAN)
                l2_len += 4;
@@ -345,17 +346,31 @@ tap_verify_csum(struct rte_mbuf *mbuf)
                return;
        }
        if (l4 == RTE_PTYPE_L4_UDP || l4 == RTE_PTYPE_L4_TCP) {
+               int cksum_ok;
+
                l4_hdr = rte_pktmbuf_mtod_offset(mbuf, void *, l2_len + l3_len);
                /* Don't verify checksum for multi-segment packets. */
                if (mbuf->nb_segs > 1)
                        return;
-               if (l3 == RTE_PTYPE_L3_IPV4)
-                       cksum = ~rte_ipv4_udptcp_cksum(l3_hdr, l4_hdr);
-               else if (l3 == RTE_PTYPE_L3_IPV6)
-                       cksum = ~rte_ipv6_udptcp_cksum(l3_hdr, l4_hdr);
-               mbuf->ol_flags |= cksum ?
-                       PKT_RX_L4_CKSUM_BAD :
-                       PKT_RX_L4_CKSUM_GOOD;
+               if (l3 == RTE_PTYPE_L3_IPV4 || l3 == RTE_PTYPE_L3_IPV4_EXT) {
+                       if (l4 == RTE_PTYPE_L4_UDP) {
+                               udp_hdr = (struct rte_udp_hdr *)l4_hdr;
+                               if (udp_hdr->dgram_cksum == 0) {
+                                       /*
+                                        * For IPv4, a zero UDP checksum
+                                        * indicates that the sender did not
+                                        * generate one [RFC 768].
+                                        */
+                                       mbuf->ol_flags |= PKT_RX_L4_CKSUM_NONE;
+                                       return;
+                               }
+                       }
+                       cksum_ok = !rte_ipv4_udptcp_cksum_verify(l3_hdr, l4_hdr);
+               } else { /* l3 == RTE_PTYPE_L3_IPV6, checked above */
+                       cksum_ok = !rte_ipv6_udptcp_cksum_verify(l3_hdr, l4_hdr);
+               }
+               mbuf->ol_flags |= cksum_ok ?
+                       PKT_RX_L4_CKSUM_GOOD : PKT_RX_L4_CKSUM_BAD;
        }
 }
 
@@ -751,8 +766,16 @@ pmd_tx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
                        if (num_tso_mbufs < 0)
                                break;
 
-                       mbuf = gso_mbufs;
-                       num_mbufs = num_tso_mbufs;
+                       if (num_tso_mbufs >= 1) {
+                               mbuf = gso_mbufs;
+                               num_mbufs = num_tso_mbufs;
+                       } else {
+                               /* 0 means it can be transmitted directly
+                                * without gso.
+                                */
+                               mbuf = &mbuf_in;
+                               num_mbufs = 1;
+                       }
                } else {
                        /* stats.errs will be incremented */
                        if (rte_pktmbuf_pkt_len(mbuf_in) > max_size)
@@ -1868,7 +1891,7 @@ static const struct eth_dev_ops ops = {
        .stats_reset            = tap_stats_reset,
        .dev_supported_ptypes_get = tap_dev_supported_ptypes_get,
        .rss_hash_update        = tap_rss_hash_update,
-       .filter_ctrl            = tap_dev_filter_ctrl,
+       .flow_ops_get           = tap_dev_flow_ops_get,
 };
 
 static int
@@ -1922,7 +1945,8 @@ eth_dev_tap_create(struct rte_vdev_device *vdev, const char *tap_name,
        /* Setup some default values */
        data = dev->data;
        data->dev_private = pmd;
-       data->dev_flags = RTE_ETH_DEV_INTR_LSC;
+       data->dev_flags = RTE_ETH_DEV_INTR_LSC |
+                               RTE_ETH_DEV_AUTOFILL_QUEUE_XSTATS;
        data->numa_node = numa_node;
 
        data->dev_link = pmd_link;