From mboxrd@z Thu Jan 1 00:00:00 1970 From: Olivier Matz Subject: [PATCH 00/18] software parser for packet type Date: Tue, 5 Jul 2016 17:41:32 +0200 Message-ID: <1467733310-20875-1-git-send-email-olivier.matz@6wind.com> To: dev@dpdk.org Return-path: Received: from proxy.6wind.com (host.76.145.23.62.rev.coltfrance.com [62.23.145.76]) by dpdk.org (Postfix) with ESMTP id C2261591F for ; Tue, 5 Jul 2016 17:42:00 +0200 (CEST) Received: from glumotte.dev.6wind.com (unknown [10.16.0.195]) by proxy.6wind.com (Postfix) with ESMTP id A0DE825842 for ; Tue, 5 Jul 2016 17:42:00 +0200 (CEST) List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" This patchset introduces a software packet type parser. This feature is targeted for v16.11. The goal here is to provide a reference implementation for packet type parsing. This function will be used by testpmd to compare its result with the value given by the hardware. It will also be useful when implementing Rx offload support in virtio pmd. Indeed, the virtio protocol gives the csum start and offset, but it does not give the L4 protocol nor it tells if the checksum is relevant for inner or outer. This information has to be known to properly set the ol_flags in mbuf. Olivier Matz (18): doc: add template for release notes 16.11 mbuf: add function to read packet data net: move Ethernet header definitions to the net library mbuf: move packet type definitions in a new file mbuf: add function to get packet type from data mbuf: support Vlan in software packet type parser mbuf: support QinQ in software packet type parser net: add Mpls header structure mbuf: support Mpls in software packet type parser mbuf: support Ip tunnels in software packet type parser net: add Gre header structure mbuf: support Gre in software packet type parser mbuf: support Nvgre in software packet type parser mbuf: get ptype for the first layers only mbuf: add functions to dump packet type mbuf: clarify definition of fragment packet types app/testpmd: dump ptype using the new function app/testpmd: display sw packet type app/test-pmd/rxonly.c | 195 ++------- doc/guides/rel_notes/release_16_11.rst | 173 ++++++++ lib/librte_ether/Makefile | 3 +- lib/librte_ether/rte_ether.h | 416 ------------------- lib/librte_mbuf/Makefile | 7 +- lib/librte_mbuf/rte_mbuf.c | 36 ++ lib/librte_mbuf/rte_mbuf.h | 530 ++---------------------- lib/librte_mbuf/rte_mbuf_ptype.c | 735 +++++++++++++++++++++++++++++++++ lib/librte_mbuf/rte_mbuf_ptype.h | 735 +++++++++++++++++++++++++++++++++ lib/librte_mbuf/rte_mbuf_version.map | 16 + lib/librte_net/Makefile | 4 +- lib/librte_net/rte_ether.h | 419 +++++++++++++++++++ lib/librte_net/rte_gre.h | 71 ++++ lib/librte_net/rte_mpls.h | 64 +++ 14 files changed, 2317 insertions(+), 1087 deletions(-) create mode 100644 doc/guides/rel_notes/release_16_11.rst delete mode 100644 lib/librte_ether/rte_ether.h create mode 100644 lib/librte_mbuf/rte_mbuf_ptype.c create mode 100644 lib/librte_mbuf/rte_mbuf_ptype.h create mode 100644 lib/librte_net/rte_ether.h create mode 100644 lib/librte_net/rte_gre.h create mode 100644 lib/librte_net/rte_mpls.h Test report =========== Topology: dut +-------------+ | | | ixgbe pmd +---. | | | | | | | ixgbe linux +---' | | +-------------+ We will send packets with scapy from the kernel interface to testpmd with rxonly engine, and check the logs to verify the packet type. # compile and run testpmd cd dpdk.org/ make config T=x86_64-native-linuxapp-gcc make -j32 mkdir -p /mnt/huge mount -t hugetlbfs nodev /mnt/huge echo 256 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages modprobe uio_pci_generic python tools/dpdk_nic_bind.py -b uio_pci_generic 0000:04:00.0 ./build/app/testpmd -l 2,4 -- --total-num-mbufs=65536 -i --port-topology=chained --enable-rx-cksum --disable-hw-vlan-filter --disable-hw-vlan-strip set fwd rxonly set verbose 1 start # on another terminal, run scapy scapy eh = Ether(src="00:01:02:03:04:05", dst="00:1B:21:AB:8F:10") vlan = Dot1Q(vlan=0x666) eth = "ixgbe2" class MPLS(Packet): name = "MPLS" fields_desc = [ BitField("label", 3, 20), BitField("cos", 0, 3), BitField("bs", 1, 1), ByteField("ttl", 0) ] bind_layers(Ether, MPLS, type=0x8847) bind_layers(GRE, IPv6, type=0x86dd) v4/udp ====== # scapy p = eh/IP()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/vlan/IP()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/vlan/vlan/IP()/UDP()/Raw("x"*32) p.type=0x88A8 # QinQ sendp(p, iface=eth) p = eh/MPLS(bs=1)/IP()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/IP(options=IPOption('\x83\x03\x10'))/UDP()/Raw("x"*32) sendp(p, iface=eth) # displayed in testpmd port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=74 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 L4_UDP - sw ptype: L2_ETHER L3_IPV4 L4_UDP - l2_len=14 - l3_len=20 - l4_len=8 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x8100 - length=78 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 L4_UDP - sw ptype: L2_ETHER_VLAN L3_IPV4 L4_UDP - l2_len=18 - l3_len=20 - l4_len=8 - Receive queue=0x0 PKT_RX_VLAN_PKT port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x88a8 - length=82 - nb_segs=1 - hw ptype: L2_ETHER - sw ptype: L2_ETHER_QINQ L3_IPV4 L4_UDP - l2_len=22 - l3_len=20 - l4_len=8 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x8847 - length=78 - nb_segs=1 - hw ptype: L2_ETHER - sw ptype: L2_ETHER_MPLS - l2_len=18 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=78 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4_EXT L4_UDP - sw ptype: L2_ETHER L3_IPV4_EXT L4_UDP - l2_len=14 - l3_len=24 - l4_len=8 - Receive queue=0x0 v4/tcp ====== # scapy p = eh/IP()/TCP()/Raw("x"*32) sendp(p, iface=eth) p = eh/vlan/IP()/TCP()/Raw("x"*32) sendp(p, iface=eth) p = eh/vlan/vlan/IP()/TCP()/Raw("x"*32) p.type=0x88A8 # QinQ sendp(p, iface=eth) p = eh/IP(options=IPOption('\x83\x03\x10'))/TCP()/Raw("x"*32) sendp(p, iface=eth) p = eh/IP()/TCP(options=[('MSS',1200)])/Raw("x"*32) sendp(p, iface=eth) # displayed in testpmd port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=86 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 L4_TCP - sw ptype: L2_ETHER L3_IPV4 L4_TCP - l2_len=14 - l3_len=20 - l4_len=20 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x8100 - length=90 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 L4_TCP - sw ptype: L2_ETHER_VLAN L3_IPV4 L4_TCP - l2_len=18 - l3_len=20 - l4_len=20 - Receive queue=0x0 PKT_RX_VLAN_PKT port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x88a8 - length=94 - nb_segs=1 - hw ptype: L2_ETHER - sw ptype: L2_ETHER_QINQ L3_IPV4 L4_TCP - l2_len=22 - l3_len=20 - l4_len=20 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=90 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4_EXT L4_TCP - sw ptype: L2_ETHER L3_IPV4_EXT L4_TCP - l2_len=14 - l3_len=24 - l4_len=20 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=90 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 L4_TCP - sw ptype: L2_ETHER L3_IPV4 L4_TCP - l2_len=14 - l3_len=20 - l4_len=24 - Receive queue=0x0 v6/udp ====== # scapy p = eh/IPv6()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/vlan/IPv6()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/vlan/vlan/IPv6()/UDP()/Raw("x"*32) p.type=0x88A8 # QinQ sendp(p, iface=eth) p = eh/IPv6()/IPv6ExtHdrHopByHop()/UDP()/Raw("x"*32) sendp(p, iface=eth) # displayed in testpmd port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x86dd - length=94 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV6 L4_UDP - sw ptype: L2_ETHER L3_IPV6 L4_UDP - l2_len=14 - l3_len=40 - l4_len=8 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x8100 - length=98 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV6 L4_UDP - sw ptype: L2_ETHER_VLAN L3_IPV6 L4_UDP - l2_len=18 - l3_len=40 - l4_len=8 - Receive queue=0x0 PKT_RX_VLAN_PKT port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x88a8 - length=102 - nb_segs=1 - hw ptype: L2_ETHER - sw ptype: L2_ETHER_QINQ L3_IPV6 L4_UDP - l2_len=22 - l3_len=40 - l4_len=8 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x86dd - length=102 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV6_EXT L4_UDP - sw ptype: L2_ETHER L3_IPV6_EXT L4_UDP - l2_len=14 - l3_len=48 - l4_len=8 - Receive queue=0x0 v6/tcp ====== # scapy p = eh/IPv6()/TCP()/Raw("x"*32) sendp(p, iface=eth) p = eh/vlan/IPv6()/TCP()/Raw("x"*32) sendp(p, iface=eth) p = eh/vlan/vlan/IPv6()/TCP()/Raw("x"*32) p.type=0x88A8 # QinQ sendp(p, iface=eth) p = eh/IPv6()/TCP()/Raw("x"*32) sendp(p, iface=eth) p = eh/IPv6()/IPv6ExtHdrHopByHop()/TCP(options=[('MSS',1200)])/Raw("x"*32) sendp(p, iface=eth) # displayed in testpmd port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x86dd - length=106 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV6 L4_TCP - sw ptype: L2_ETHER L3_IPV6 L4_TCP - l2_len=14 - l3_len=40 - l4_len=20 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x8100 - length=110 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV6 L4_TCP - sw ptype: L2_ETHER_VLAN L3_IPV6 L4_TCP - l2_len=18 - l3_len=40 - l4_len=20 - Receive queue=0x0 PKT_RX_VLAN_PKT port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x88a8 - length=114 - nb_segs=1 - hw ptype: L2_ETHER - sw ptype: L2_ETHER_QINQ L3_IPV6 L4_TCP - l2_len=22 - l3_len=40 - l4_len=20 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x86dd - length=106 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV6 L4_TCP - sw ptype: L2_ETHER L3_IPV6 L4_TCP - l2_len=14 - l3_len=40 - l4_len=20 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x86dd - length=118 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV6_EXT L4_TCP - sw ptype: L2_ETHER L3_IPV6_EXT L4_TCP - l2_len=14 - l3_len=48 - l4_len=24 - Receive queue=0x0 tunnels ======= # scapy p = eh/IP()/IP()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/IP(options=IPOption('\x83\x03\x10'))/IP()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/IP()/IPv6()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/IPv6(nh=4)/IP()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/IPv6()/IPv6()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/IP()/GRE()/IP()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/IP(options=IPOption('\x83\x03\x10'))/GRE()/IP()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/IP()/GRE(key_present=1)/IP()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/IP()/GRE(proto=0x86dd)/IPv6()/UDP()/Raw("x"*32) sendp(p, iface=eth) p = eh/IP()/GRE(proto=0x6558)/Ether()/IP()/UDP()/Raw("x"*32) sendp(p, iface=eth) # displayed in testpmd port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=94 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 - sw ptype: L2_ETHER L3_IPV4 TUNNEL_IP INNER_L3_IPV4 INNER_L4_UDP - l2_len=14 - l3_len=20 - tunnel_len=0 - inner_l3_len=20 - inner_l4_len=8 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=98 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4_EXT - sw ptype: L2_ETHER L3_IPV4_EXT TUNNEL_IP INNER_L3_IPV4 INNER_L4_UDP - l2_len=14 - l3_len=24 - tunnel_len=0 - inner_l3_len=20 - inner_l4_len=8 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=114 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 TUNNEL_IP INNER_L3_IPV6 INNER_L4_UDP - sw ptype: L2_ETHER L3_IPV4 TUNNEL_IP INNER_L3_IPV6 INNER_L4_UDP - l2_len=14 - l3_len=20 - tunnel_len=0 - inner_l3_len=40 - inner_l4_len=8 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x86dd - length=114 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV6 - sw ptype: L2_ETHER L3_IPV6 TUNNEL_IP INNER_L3_IPV4 INNER_L4_UDP - l2_len=14 - l3_len=40 - tunnel_len=0 - inner_l3_len=20 - inner_l4_len=8 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x86dd - length=134 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV6 - sw ptype: L2_ETHER L3_IPV6 TUNNEL_IP INNER_L3_IPV6 INNER_L4_UDP - l2_len=14 - l3_len=40 - tunnel_len=0 - inner_l3_len=40 - inner_l4_len=8 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=98 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 - sw ptype: L2_ETHER L3_IPV4 TUNNEL_GRE INNER_L3_IPV4 INNER_L4_UDP - l2_len=14 - l3_len=20 - tunnel_len=4 - inner_l3_len=20 - inner_l4_len=8 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=102 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4_EXT - sw ptype: L2_ETHER L3_IPV4_EXT TUNNEL_GRE INNER_L3_IPV4 INNER_L4_UDP - l2_len=14 - l3_len=24 - tunnel_len=4 - inner_l3_len=20 - inner_l4_len=8 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=102 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 - sw ptype: L2_ETHER L3_IPV4 TUNNEL_GRE INNER_L3_IPV4 INNER_L4_UDP - l2_len=14 - l3_len=20 - tunnel_len=8 - inner_l3_len=20 - inner_l4_len=8 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=118 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 - sw ptype: L2_ETHER L3_IPV4 TUNNEL_GRE INNER_L3_IPV6 INNER_L4_UDP - l2_len=14 - l3_len=20 - tunnel_len=4 - inner_l3_len=40 - inner_l4_len=8 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=112 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 - sw ptype: L2_ETHER L3_IPV4 TUNNEL_NVGRE INNER_L2_ETHER INNER_L3_IPV4 INNER_L4_UDP - l2_len=14 - l3_len=20 - tunnel_len=4 - inner_l2_len=14 - inner_l3_len=20 - inner_l4_len=8 - Receive queue=0x0 L2 or L3 only ============= # scapy p = eh/IP()/Raw("x"*32) sendp(p, iface=eth) p = eh/IPv6()/Raw("x"*32) sendp(p, iface=eth) p = eh/Raw("x"*32) sendp(p, iface=eth) port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=66 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 - sw ptype: L2_ETHER L3_IPV4 - l2_len=14 - l3_len=20 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x86dd - length=86 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV6 - sw ptype: L2_ETHER L3_IPV6 - l2_len=14 - l3_len=40 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0000 - length=60 - nb_segs=1 - hw ptype: L2_ETHER - sw ptype: L2_ETHER - l2_len=14 - Receive queue=0x0 fragments ========= # scapy p1, p2 = fragment(eh/IP()/UDP()/Raw("x"*32), 32) sendp(p1, iface=eth) sendp(p2, iface=eth) p3, p4 = eh/IP()/GRE(proto=0x6558)/p1, eh/IP()/GRE(proto=0x6558)/p2 sendp(p3, iface=eth) sendp(p4, iface=eth) # displayed in testpmd port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=66 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 - sw ptype: L2_ETHER L3_IPV4 L4_FRAG - l2_len=14 - l3_len=20 - l4_len=0 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=60 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 - sw ptype: L2_ETHER L3_IPV4 L4_FRAG - l2_len=14 - l3_len=20 - l4_len=0 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=104 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 - sw ptype: L2_ETHER L3_IPV4 TUNNEL_NVGRE INNER_L2_ETHER INNER_L3_IPV4 INNER_L4_FRAG - l2_len=14 - l3_len=20 - tunnel_len=4 - inner_l2_len=14 - inner_l3_len=20 - inner_l4_len=0 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=80 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 - sw ptype: L2_ETHER L3_IPV4 TUNNEL_NVGRE INNER_L2_ETHER INNER_L3_IPV4 INNER_L4_FRAG - l2_len=14 - l3_len=20 - tunnel_len=4 - inner_l2_len=14 - inner_l3_len=20 - inner_l4_len=0 - Receive queue=0x0 # scapy p1, p2 = fragment6(eh/IPv6()/IPv6ExtHdrFragment()/UDP()/Raw("x"*32), 100) sendp(p1, iface=eth) sendp(p2, iface=eth) p3, p4 = eh/IP()/GRE(proto=0x6558)/p1, eh/IP()/GRE(proto=0x6558)/p2 sendp(p3, iface=eth) sendp(p4, iface=eth) # displayed in testpmd port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x86dd - length=94 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV6_EXT - sw ptype: L2_ETHER L3_IPV6_EXT L4_FRAG - l2_len=14 - l3_len=48 - l4_len=0 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x86dd - length=70 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV6_EXT - sw ptype: L2_ETHER L3_IPV6_EXT L4_FRAG - l2_len=14 - l3_len=48 - l4_len=0 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=132 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 - sw ptype: L2_ETHER L3_IPV4 TUNNEL_NVGRE INNER_L2_ETHER INNER_L3_IPV6_EXT INNER_L4_FRAG - l2_len=14 - l3_len=20 - tunnel_len=4 - inner_l2_len=14 - inner_l3_len=48 - inner_l4_len=0 - Receive queue=0x0 port 0/queue 0: received 1 packets src=00:01:02:03:04:05 - dst=00:1B:21:AB:8F:10 - type=0x0800 - length=108 - nb_segs=1 - hw ptype: L2_ETHER L3_IPV4 - sw ptype: L2_ETHER L3_IPV4 TUNNEL_NVGRE INNER_L2_ETHER INNER_L3_IPV6_EXT INNER_L4_FRAG - l2_len=14 - l3_len=20 - tunnel_len=4 - inner_l2_len=14 - inner_l3_len=48 - inner_l4_len=0 - Receive queue=0x0 -- 2.8.1