summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluqiuwen <[email protected]>2018-12-15 14:47:17 +0600
committerluqiuwen <[email protected]>2018-12-15 14:48:49 +0600
commit4ba447f6fd1612347ea72ed0f81ac03d09f95d38 (patch)
tree683e5df08d73321f1472f6de4626b27f5f2c05fc
parent48d78609a0df91ed344e61a86d02758a97a08fcc (diff)
修正报文带有MPLS标签时分流错误的问题,增补非对称MPLS标签的分流单元测试用例v4.3.2-20181222
* 原实现在解析带有MPLS标签报文时,使用了硬件提供的报文类型标志。此时,报文类型标志为IPv4,未区分是否具有MPLS标签。因此,原实现认为该报文为不带标签的IPv4包,直接计算报文哈希值,导致分流错误。 * 现修正,默认不读取硬件提供报文类型标志,软件再次解析报文确定报文类型。 * 增补非对称MPLS标签的分流单元测试用例。
-rw-r--r--infra/src/ldbc.c52
-rw-r--r--infra/test/178.89.4.221_to_31.13.70.49_asym_mpls_ipv4.pcapbin0 -> 497623 bytes
-rw-r--r--infra/test/178.89.4.221_to_31.13.70.49_mpls_ipv4.pcapbin0 -> 121053 bytes
-rw-r--r--infra/test/TestDistributer.cc15
-rw-r--r--tunnat/src/tunnel.cc1
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
new file mode 100644
index 0000000..6972721
--- /dev/null
+++ b/infra/test/178.89.4.221_to_31.13.70.49_asym_mpls_ipv4.pcap
Binary files differ
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
new file mode 100644
index 0000000..932a3dc
--- /dev/null
+++ b/infra/test/178.89.4.221_to_31.13.70.49_mpls_ipv4.pcap
Binary files differ
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)