From c7fff9e6eb2ba6f9d71389dc43c606b55f9379ce Mon Sep 17 00:00:00 2001
From: jiangheng <jiangheng14@huawei.com>
Date: Tue, 18 Jun 2024 15:33:14 +0800
Subject: [PATCH] parse packages type in rx_poll

---
 src/lstack/netif/lstack_ethdev.c | 28 ++++++++---
 src/lstack/netif/lstack_vdev.c   | 84 ++++++++++++++++++++------------
 2 files changed, 73 insertions(+), 39 deletions(-)

diff --git a/src/lstack/netif/lstack_ethdev.c b/src/lstack/netif/lstack_ethdev.c
index 45c5f9e..3bfa8af 100644
--- a/src/lstack/netif/lstack_ethdev.c
+++ b/src/lstack/netif/lstack_ethdev.c
@@ -130,6 +130,25 @@ void kni_handle_tx(struct rte_mbuf *mbuf)
 }
 #endif
 
+#define IS_ARP_PKT(ptype) ((ptype & RTE_PTYPE_L2_ETHER_ARP) == RTE_PTYPE_L2_ETHER_ARP)
+#define IS_IPV4_TCP_PKT(ptype) (RTE_ETH_IS_IPV4_HDR(ptype) && \
+        ((ptype & RTE_PTYPE_L4_TCP) == RTE_PTYPE_L4_TCP) && \
+        ((ptype & RTE_PTYPE_L4_FRAG) != RTE_PTYPE_L4_FRAG) && \
+        (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0))
+
+#define IS_IPV6_TCP_PKT(ptype) (RTE_ETH_IS_IPV6_HDR(ptype) && \
+        ((ptype & RTE_PTYPE_L4_TCP) == RTE_PTYPE_L4_TCP) && \
+        ((ptype & RTE_PTYPE_L4_FRAG) != RTE_PTYPE_L4_FRAG) && \
+        (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0))
+
+#define IS_IPV4_UDP_PKT(ptype) (RTE_ETH_IS_IPV4_HDR(ptype) && \
+        ((ptype & RTE_PTYPE_L4_UDP) == RTE_PTYPE_L4_UDP) && \
+        (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0))
+
+#define IS_IPV6_UDP_PKT(ptype) (RTE_ETH_IS_IPV6_HDR(ptype) && \
+        ((ptype & RTE_PTYPE_L4_UDP) == RTE_PTYPE_L4_UDP) && \
+        (RTE_ETH_IS_TUNNEL_PKT(ptype) == 0))
+
 int32_t eth_dev_poll(void)
 {
     uint32_t nr_pkts;
@@ -151,14 +170,7 @@ int32_t eth_dev_poll(void)
         int transfer_type = TRANSFER_CURRENT_THREAD;
         /* copy arp into other stack */
         if (!use_ltran()) {
-            struct rte_ether_hdr *ethh = rte_pktmbuf_mtod(stack->pkts[i], struct rte_ether_hdr *);
-            u16_t type;
-            type = ethh->ether_type;
-            if (type == PP_HTONS(ETHTYPE_VLAN)) {
-                struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr *)(((char *)ethh) + SIZEOF_ETH_HDR);
-                type = vlan->tpid;
-            }
-            if (unlikely(RTE_BE16(RTE_ETHER_TYPE_ARP) == type)) {
+            if (unlikely(IS_ARP_PKT(stack->pkts[i]->packet_type))) {
                 stack_broadcast_arp(stack->pkts[i], stack);
                 /* copy arp into other process */
                 transfer_arp_to_other_process(stack->pkts[i]);
diff --git a/src/lstack/netif/lstack_vdev.c b/src/lstack/netif/lstack_vdev.c
index 107ee8c..5ce69a9 100644
--- a/src/lstack/netif/lstack_vdev.c
+++ b/src/lstack/netif/lstack_vdev.c
@@ -72,6 +72,58 @@ static uint32_t ltran_rx_poll(struct protocol_stack *stack, struct rte_mbuf **pk
     return rcvd_pkts;
 }
 
+static inline void vdev_pkts_parse(struct rte_mbuf **pkts, int pkt_num)
+{
+    for (int i = 0; i < pkt_num; i++) {
+        struct rte_ether_hdr *ethh = rte_pktmbuf_mtod(pkts[i], struct rte_ether_hdr *);
+        u16_t type  = ethh->ether_type;
+        if (type == RTE_BE16(RTE_ETHER_TYPE_VLAN)) {
+            struct rte_vlan_hdr *vlan = (struct rte_vlan_hdr *)(ethh + 1);
+            type = vlan->eth_proto;
+            pkts[i]->l2_len = sizeof(struct rte_ether_hdr) + sizeof(struct rte_vlan_hdr);
+        } else {
+            pkts[i]->l2_len = sizeof(struct rte_ether_hdr);
+        }
+
+        if (type == RTE_BE16(RTE_ETHER_TYPE_IPV4)) {
+            struct rte_ipv4_hdr *iph = rte_pktmbuf_mtod_offset(pkts[i], struct rte_ipv4_hdr *,
+                pkts[i]->l2_len);
+            if (unlikely((iph->version_ihl & IPV4_MASK) != IPV4_VERION)) {
+                continue;
+            }
+            pkts[i]->l3_len = sizeof(struct rte_ipv4_hdr);
+            if (iph->next_proto_id == IPPROTO_TCP) {
+                struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct rte_tcp_hdr *,
+                    pkts[i]->l2_len + pkts[i]->l3_len);
+                pkts[i]->l4_len = TCP_HDR_LEN(tcp_hdr);
+
+                pkts[i]->packet_type = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP;
+            } else if (iph->next_proto_id == IPPROTO_UDP) {
+                pkts[i]->l4_len = sizeof(struct rte_udp_hdr);
+                pkts[i]->packet_type = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_UDP;
+            }
+
+        } else if (type == RTE_BE16(RTE_ETHER_TYPE_IPV6)) {
+            struct rte_ipv6_hdr *iph6 = rte_pktmbuf_mtod_offset(pkts[i], struct rte_ipv6_hdr *,
+                pkts[i]->l2_len);
+            pkts[i]->l3_len = sizeof(struct rte_ipv6_hdr);
+            if (iph6->proto == IPPROTO_TCP) {
+                struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct rte_tcp_hdr *,
+                    pkts[i]->l2_len + pkts[i]->l3_len);
+                pkts[i]->l4_len = TCP_HDR_LEN(tcp_hdr);
+                pkts[i]->packet_type = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP;
+            } else if (iph6->proto == IPPROTO_UDP) {
+                pkts[i]->l4_len = sizeof(struct rte_udp_hdr);
+                pkts[i]->packet_type = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP;
+            }
+        } else if (type == RTE_BE16(RTE_ETHER_TYPE_ARP)) {
+            pkts[i]->packet_type = RTE_PTYPE_L2_ETHER_ARP;
+        } else {
+            continue;
+        }
+    }
+}
+
 static uint32_t vdev_rx_poll(struct protocol_stack *stack, struct rte_mbuf **pkts, uint32_t max_mbuf)
 {
     struct rte_gro_param gro_param = {
@@ -82,6 +134,7 @@ static uint32_t vdev_rx_poll(struct protocol_stack *stack, struct rte_mbuf **pkt
     };
 
     uint32_t pkt_num = rte_eth_rx_burst(stack->port_id, stack->queue_id, pkts, max_mbuf);
+    vdev_pkts_parse(pkts, pkt_num);
     if (pkt_num <= 1) {
         return pkt_num;
     }
@@ -92,37 +145,6 @@ static uint32_t vdev_rx_poll(struct protocol_stack *stack, struct rte_mbuf **pkt
         return pkt_num;
     }
 
-    for (uint32_t i = 0; i < pkt_num; i++) {
-        struct rte_ether_hdr *ethh = rte_pktmbuf_mtod(pkts[i], struct rte_ether_hdr *);
-        u16_t type  = ethh->ether_type;
-
-        pkts[i]->l2_len = sizeof(struct rte_ether_hdr);
-
-        if (type == RTE_BE16(RTE_ETHER_TYPE_IPV4)) {
-            struct rte_ipv4_hdr *iph = rte_pktmbuf_mtod_offset(pkts[i], struct rte_ipv4_hdr *,
-                sizeof(struct rte_ether_hdr));
-            if (unlikely((iph->version_ihl & IPV4_MASK) != IPV4_VERION)) {
-                continue;
-            }
-            pkts[i]->l3_len = sizeof(struct rte_ipv4_hdr);
-
-            struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct rte_tcp_hdr *,
-                sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv4_hdr));
-            pkts[i]->l4_len = TCP_HDR_LEN(tcp_hdr);
-
-            pkts[i]->packet_type = RTE_PTYPE_L3_IPV4 | RTE_PTYPE_L4_TCP;
-        } else if (type == RTE_BE16(RTE_ETHER_TYPE_IPV6)) {
-            pkts[i]->l3_len = sizeof(struct rte_ipv6_hdr);
-
-            struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(pkts[i], struct rte_tcp_hdr *,
-                sizeof(struct rte_ether_hdr) + sizeof(struct rte_ipv6_hdr));
-            pkts[i]->l4_len = TCP_HDR_LEN(tcp_hdr);
-
-            pkts[i]->packet_type = RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP;
-        } else {
-            continue;
-        }
-    }
     pkt_num =  rte_gro_reassemble_burst(pkts, pkt_num, &gro_param);
 
     return pkt_num;
-- 
2.33.0

