diff options
| author | luqiuwen <[email protected]> | 2018-12-15 14:47:17 +0600 |
|---|---|---|
| committer | luqiuwen <[email protected]> | 2018-12-15 14:48:49 +0600 |
| commit | 4ba447f6fd1612347ea72ed0f81ac03d09f95d38 (patch) | |
| tree | 683e5df08d73321f1472f6de4626b27f5f2c05fc | |
| parent | 48d78609a0df91ed344e61a86d02758a97a08fcc (diff) | |
修正报文带有MPLS标签时分流错误的问题,增补非对称MPLS标签的分流单元测试用例v4.3.2-20181222
* 原实现在解析带有MPLS标签报文时,使用了硬件提供的报文类型标志。此时,报文类型标志为IPv4,未区分是否具有MPLS标签。因此,原实现认为该报文为不带标签的IPv4包,直接计算报文哈希值,导致分流错误。
* 现修正,默认不读取硬件提供报文类型标志,软件再次解析报文确定报文类型。
* 增补非对称MPLS标签的分流单元测试用例。
| -rw-r--r-- | infra/src/ldbc.c | 52 | ||||
| -rw-r--r-- | infra/test/178.89.4.221_to_31.13.70.49_asym_mpls_ipv4.pcap | bin | 0 -> 497623 bytes | |||
| -rw-r--r-- | infra/test/178.89.4.221_to_31.13.70.49_mpls_ipv4.pcap | bin | 0 -> 121053 bytes | |||
| -rw-r--r-- | infra/test/TestDistributer.cc | 15 | ||||
| -rw-r--r-- | tunnat/src/tunnel.cc | 1 |
5 files changed, 52 insertions, 16 deletions
diff --git a/infra/src/ldbc.c b/infra/src/ldbc.c index b20a965..f1e3fa1 100644 --- a/infra/src/ldbc.c +++ b/infra/src/ldbc.c @@ -15,6 +15,7 @@ #include <string.h> #include <assert.h> #include <stdint.h> +#include <stdbool.h> #include <linux/if_ether.h> #include <linux/ppp_defs.h> @@ -30,6 +31,10 @@ static uint8_t default_rss_key[] = 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa, }; +#ifndef ENABLE_LDBC_BASED_NIC_PTYPE +#define ENABLE_LDBC_BASED_NIC_PTYPE 0 +#endif + static inline int __parser_exit_or_continue(struct pkt_parser * handler, const void * data, enum complex_layer this_layer_type) { @@ -476,22 +481,27 @@ static inline uint32_t __distributer_inner_tuple2(struct distributer * dist_obje pkt_parser_init(&pkt_parser, LAYER_TYPE_L3, 2); /* 根据硬件的解析能力,找到最外层的IP */ - if (RTE_ETH_IS_IPV4_HDR(mbuf->packet_type)) +#if ENABLE_LDBC_BASED_NIC_PTYPE + bool is_no_l2_label = (mbuf->packet_type & RTE_PTYPE_L2_MASK) == RTE_PTYPE_L2_ETHER; + if (is_no_l2_label && RTE_ETH_IS_IPV4_HDR(mbuf->packet_type)) { outer_data = rte_pktmbuf_mtod_offset(mbuf, const char *, sizeof(struct ether_hdr)); __complex_parser_ipv4(&pkt_parser, outer_data, LAYER_TYPE_IPV4); } - - else if (RTE_ETH_IS_IPV6_HDR(mbuf->packet_type)) + else if (is_no_l2_label && RTE_ETH_IS_IPV6_HDR(mbuf->packet_type)) { outer_data = rte_pktmbuf_mtod_offset(mbuf, const char *, sizeof(struct ether_hdr)); __complex_parser_ipv6(&pkt_parser, outer_data, LAYER_TYPE_IPV6); } else { +#endif outer_data = rte_pktmbuf_mtod_offset(mbuf, const char *, 0); __complex_parser_ether(&pkt_parser, outer_data, LAYER_TYPE_ETHER); + +#if ENABLE_LDBC_BASED_NIC_PTYPE } +#endif if (pkt_parser.nr_results == 0) return 0; inner_data = pkt_parser.results[pkt_parser.nr_results - 1].data; @@ -512,22 +522,33 @@ static inline uint32_t __distributer_outer_tuple2(struct distributer * dist_obje { const char * data; int layer_type; - - if(RTE_ETH_IS_IPV4_HDR(mbuf->packet_type)) - { - data = rte_pktmbuf_mtod_offset(mbuf, const char *, sizeof(struct ether_hdr)); - layer_type = LAYER_TYPE_IPV4; - goto _calc_hash; - } - else if(RTE_ETH_IS_IPV6_HDR(mbuf->packet_type)) + /* 判断以太网以上仅为IPv4/IPv6,无任何标签插在以太层和IPv4/IPv6t头之间 + * 若Ether->MPLS->IPv4/IPv6,则RTE_ETH_IS_IPV4_HDR为真,仅根据是否具有 + * IPv4的协议类型无法判断IPv4头的位置 + * + * TODO: 验证使用如下方法的正确性,现在暂时不依赖硬件给的协议类型标签 */ + +#if ENABLE_LDBC_BASED_NIC_PTYPE + if((mbuf->packet_type & RTE_PTYPE_L2_MASK) == RTE_PTYPE_L2_ETHER) { - data = rte_pktmbuf_mtod_offset(mbuf, const char *, sizeof(struct ether_hdr)); - layer_type = LAYER_TYPE_IPV4; - goto _calc_hash; + if(RTE_ETH_IS_IPV4_HDR(mbuf->packet_type)) + { + data = rte_pktmbuf_mtod_offset(mbuf, const char *, sizeof(struct ether_hdr)); + layer_type = LAYER_TYPE_IPV4; + goto _calc_hash; + } + + if(RTE_ETH_IS_IPV6_HDR(mbuf->packet_type)) + { + data = rte_pktmbuf_mtod_offset(mbuf, const char *, sizeof(struct ether_hdr)); + layer_type = LAYER_TYPE_IPV4; + goto _calc_hash; + } } else { +#endif struct pkt_parser pkt_parser; pkt_parser_init(&pkt_parser, LAYER_TYPE_L3, 1); @@ -537,7 +558,10 @@ static inline uint32_t __distributer_outer_tuple2(struct distributer * dist_obje data = pkt_parser.results[0].data; layer_type = pkt_parser.results[0].this_layer_type; goto _calc_hash; + +#if ENABLE_LDBC_BASED_NIC_PTYPE } +#endif _calc_hash: return dist_object->fn_hash_0(dist_object, data, layer_type, 0); diff --git a/infra/test/178.89.4.221_to_31.13.70.49_asym_mpls_ipv4.pcap b/infra/test/178.89.4.221_to_31.13.70.49_asym_mpls_ipv4.pcap Binary files differnew file mode 100644 index 0000000..6972721 --- /dev/null +++ b/infra/test/178.89.4.221_to_31.13.70.49_asym_mpls_ipv4.pcap diff --git a/infra/test/178.89.4.221_to_31.13.70.49_mpls_ipv4.pcap b/infra/test/178.89.4.221_to_31.13.70.49_mpls_ipv4.pcap Binary files differnew file mode 100644 index 0000000..932a3dc --- /dev/null +++ b/infra/test/178.89.4.221_to_31.13.70.49_mpls_ipv4.pcap diff --git a/infra/test/TestDistributer.cc b/infra/test/TestDistributer.cc index 0d47f54..2cac372 100644 --- a/infra/test/TestDistributer.cc +++ b/infra/test/TestDistributer.cc @@ -2,6 +2,7 @@ #include <gtest/gtest.h> #include <memory> #include <exception> +#include <rte_mbuf.h> extern "C" { @@ -134,7 +135,19 @@ std::tuple<const char *, enum e_dist_mode, enum e_hash_mode> testTable[] LDBC_HASH_SYM_CRC), std::make_tuple("178_89_4_219_to_117_122_217_89_ipv4.pcap", LDBC_DIST_OUTER_TUPLE2, - LDBC_HASH_SYM_RSS) + LDBC_HASH_SYM_RSS), + std::make_tuple("178.89.4.221_to_31.13.70.49_mpls_ipv4.pcap", + LDBC_DIST_OUTER_TUPLE2, + LDBC_HASH_SYM_CRC), + std::make_tuple("178.89.4.221_to_31.13.70.49_mpls_ipv4.pcap", + LDBC_DIST_OUTER_TUPLE2, + LDBC_HASH_SYM_RSS), + std::make_tuple("178.89.4.221_to_31.13.70.49_asym_mpls_ipv4.pcap", + LDBC_DIST_OUTER_TUPLE2, + LDBC_HASH_SYM_CRC), + std::make_tuple("178.89.4.221_to_31.13.70.49_asym_mpls_ipv4.pcap", + LDBC_DIST_OUTER_TUPLE2, + LDBC_HASH_SYM_RSS), }; INSTANTIATE_TEST_CASE_P(TestOuterTuple2, TestFixtureDistributer, ::testing::ValuesIn(testTable)); diff --git a/tunnat/src/tunnel.cc b/tunnat/src/tunnel.cc index 7bfda2d..1af8138 100644 --- a/tunnat/src/tunnel.cc +++ b/tunnat/src/tunnel.cc @@ -358,7 +358,6 @@ int TunnelContainer::PacketParse(const char * pkt, unsigned int pkt_len, else this_layer_type = TUNNEL_TYPE_UNKNOWN; goto out; - guess: ret = tun_vxlan_object_.PacketParse(pkt, pkt_len); if (ret >= 0) |
