Hellp Asaf,
Thanks for your speedy reply. Please find additional information based on your questions, and I hope they would help to understand our purpose and issue.
We are performing IPinIP tunnelling for traffic, and in this provided test-pmd example we encapsulate IPv4 packets from VMs into IPv6 underlay packets. The refence RFCs for this approach are RFC 1853
and RFC 2473. This
article also provides good visualization on packet structures for this IPinIP tunnelling approach.
No crashing error message or similar happens, thus it is difficult for us to debug what is exactly going on. What is observed is that incoming packets
cannot be captured and processed by this flow rule, compared with using the flow rule only performs eth/ipv6 matching. After removing relevant commands
or code that perform inner header matching for IPv4 and ICMP, packets can be successfully processed. The code snippets to programmably achieve the above described IPinIP tunnelling approach are as following:
<Code snippet to initialise pattern masks>
static const struct rte_flow_item_eth flow_item_eth_mask = {
.hdr.ether_type = 0xffff,
};
static const struct rte_flow_item_ipv6 flow_item_ipv6_dst_mask = {
.hdr.proto = 0xff,
};
static const struct rte_flow_item_ipv4 flow_item_ipv4_proto_mask = {
.hdr.next_proto_id = 0xff,
};
static const struct rte_flow_item_icmp flow_item_icmp_mask = {
.hdr.icmp_type = 0xff,
};
</Code snippet to initialise pattern masks>
<Code snippet to create pattern template>
// pattern template
struct rte_flow_item pattern[] = {
[0] = {.type = RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT, .mask = &represented_port_mask},
[1] = {.type = RTE_FLOW_ITEM_TYPE_ETH, .mask = &flow_item_eth_mask},
[2] = {.type = RTE_FLOW_ITEM_TYPE_IPV6, .mask = &flow_item_ipv6_dst_mask},
[3] = {.type = RTE_FLOW_ITEM_TYPE_IPV4, .mask = &flow_item_ipv4_proto_mask},
[4] = {.type = RTE_FLOW_ITEM_TYPE_ICMP, .mask = &flow_item_icmp_mask},
[5] = {.type = RTE_FLOW_ITEM_TYPE_END,},
};
port_template_info_pf.pattern_templates[0] = create_pattern_template(main_eswitch_port, pattern);
</Code snippet to create pattern template>
<Code snippet to create patterns>
struct rte_flow_item_eth eth_pattern = {.type = htons(0x86DD)};
struct rte_flow_item_ipv6 ipv6_hdr = {0};
ipv6_hdr.hdr.proto = IPPROTO_IPIP;
struct rte_flow_item_ipv4 ipv4_hdr = {0};
ipv4_hdr.hdr.next_proto_id = IPPROTO_ICMP;
struct rte_flow_item_icmp icmp_hdr = {0};
icmp_hdr.hdr.icmp_type = RTE_IP_ICMP_ECHO_REQUEST;
struct rte_flow_item_ethdev represented_port = {.port_id = pf_port_id};
struct rte_flow_item concrete_patterns[6];
concrete_patterns[0].type = RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT;
concrete_patterns[0].spec = &represented_port;
concrete_patterns[0].mask = NULL;
concrete_patterns[0].last = NULL;
concrete_patterns[1].type = RTE_FLOW_ITEM_TYPE_ETH;
concrete_patterns[1].spec = ð_pattern;
concrete_patterns[1].mask = NULL;
concrete_patterns[1].last = NULL;
concrete_patterns[2].type = RTE_FLOW_ITEM_TYPE_IPV6;
concrete_patterns[2].spec = &ipv6_hdr;
concrete_patterns[2].mask = NULL;
concrete_patterns[2].last = NULL;
concrete_patterns[3].type = RTE_FLOW_ITEM_TYPE_IPV4;
concrete_patterns[3].spec = &ipv4_hdr;
concrete_patterns[3].mask = NULL;
concrete_patterns[3].last = NULL;
concrete_patterns[4].type = RTE_FLOW_ITEM_TYPE_ICMP;
concrete_patterns[4].spec = &icmp_hdr;
concrete_patterns[4].mask = NULL;
concrete_patterns[4].last = NULL;
concrete_patterns[5].type = RTE_FLOW_ITEM_TYPE_END;
concrete_patterns[5].spec = NULL;
concrete_patterns[5].mask = NULL;
concrete_patterns[5].last = NULL;
</Code snippet to create patterns>
Looking forward to your further support, and many thanks in advance.
Best regards,
Tao