summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQiuwen Lu <[email protected]>2018-01-02 14:19:23 +0800
committerQiuwen Lu <[email protected]>2018-01-02 14:19:23 +0800
commit83469405d76980e7c3576474127568e1cedd1af9 (patch)
tree76b56f64be90be1e99232200fc7ea4cb5fa4cc9b
parent807ec9b870a9e1b28f4176d92fcdd8dfe052148f (diff)
增加负载均衡模块对内层为PPP、HDLC帧格式的报文的解析功能,支持两种格式的内层二元组、四元组同源同宿分流。
-rw-r--r--infra/src/ldbc.c44
-rw-r--r--infra/test/TestPacketParser.cc169
2 files changed, 202 insertions, 11 deletions
diff --git a/infra/src/ldbc.c b/infra/src/ldbc.c
index 7684843..91780cf 100644
--- a/infra/src/ldbc.c
+++ b/infra/src/ldbc.c
@@ -13,11 +13,13 @@
#include <rte_tcp.h>
#include <rte_udp.h>
#include <string.h>
-#include <common.h>
#include <assert.h>
+#include <stdint.h>
#include <linux/if_ether.h>
+#include <linux/ppp_defs.h>
+
#include <ldbc.h>
-#include <stdint.h>
+#include <common.h>
static inline int __parser_exit_or_continue(struct pkt_parser * handler,
const void * data, enum complex_layer this_layer_type)
@@ -242,12 +244,50 @@ static const void * __complex_parser_vlan8021q(struct pkt_parser * handler,
static const void * __complex_parser_hdlc(struct pkt_parser * handler,
const void * data, enum complex_layer this_layer_type)
{
+ if (__parser_exit_or_continue(handler, data, this_layer_type) == PARSE_STOP)
+ return data;
+
+ uint16_t hdlc_proto = *(const uint16_t *)(data + 2);
+ const void * data_next_layer = (const char *)data + 4;
+
+ /* HDLC的协议字段与以太网的类似,对于IPv4,为0x0800 */
+ switch (ntohs(hdlc_proto))
+ {
+ case ETHER_TYPE_IPv4:
+ return __complex_parser_ipv4(handler, data_next_layer, LAYER_TYPE_IPV4);
+
+ case ETHER_TYPE_IPv6:
+ return __complex_parser_ipv6(handler, data_next_layer, LAYER_TYPE_IPV6);
+
+ default:
+ break;
+ }
+
return NULL;
}
static const void * __complex_parser_ppp(struct pkt_parser * handler,
const void * data, enum complex_layer this_layer_type)
{
+ if (__parser_exit_or_continue(handler, data, this_layer_type) == PARSE_STOP)
+ return data;
+
+ const void * data_next_layer = (const char *)data + PPP_HDRLEN;
+
+ switch (PPP_PROTOCOL(data))
+ {
+ case PPP_IP:
+ return __complex_parser_ipv4(handler, data_next_layer, LAYER_TYPE_IPV4);
+ break;
+
+ case PPP_IPV6:
+ return __complex_parser_ipv6(handler, data_next_layer, LAYER_TYPE_IPV6);
+ break;
+
+ default:
+ break;
+ }
+
return NULL;
}
diff --git a/infra/test/TestPacketParser.cc b/infra/test/TestPacketParser.cc
index d09f4eb..ac79228 100644
--- a/infra/test/TestPacketParser.cc
+++ b/infra/test/TestPacketParser.cc
@@ -1,4 +1,4 @@
-
+
extern "C"
{
#include <rte_mbuf.h>
@@ -13,7 +13,7 @@ extern "C"
/*31 Ether/IPv4/TCP
192.168.11.169 202.157.180.190 TCP 78
- 64161��1443[SYN] Seq = 2421401215 Win = 65535 Len = 0 MSS = 1460 WS = 16
+ 64161→1443[SYN] Seq = 2421401215 Win = 65535 Len = 0 MSS = 1460 WS = 16
TSval = 1409022517 TSecr = 0 SACK_PERM = 1
*/
@@ -32,7 +32,7 @@ static const unsigned char pkt_031[78] = {
/* 16 Ether/IPv6/TCP
16.124364 3ffe:507:0:1:200:86ff:fe05:80da 3ffe:501:410:0:2c0:dfff:fe47:33e TCP 94
- 1022��22[SYN] Seq = 3598119713 Win = 8192 Len = 0 MSS = 1440 WS = 1 TSval = 576087 TSecr = 0
+ 1022→22[SYN] Seq = 3598119713 Win = 8192 Len = 0 MSS = 1440 WS = 1 TSval = 576087 TSecr = 0
*/
/* Frame (94 bytes) */
static const unsigned char pkt_16[94] = {
@@ -53,7 +53,7 @@ static const unsigned char pkt_16[94] = {
/*200 Ether/IPv4/IPv6/TCP
2001:410:90ff::6 2401:8d00:1::1 TCP 106
- 40527��53[SYN] Seq = 2032252526 Win = 28800 Len = 0 MSS = 1440 SACK_PERM = 1 WS = 128
+ 40527→53[SYN] Seq = 2032252526 Win = 28800 Len = 0 MSS = 1440 SACK_PERM = 1 WS = 128
*/
/* Frame (106 bytes) */
@@ -103,7 +103,7 @@ static const unsigned char pkt30[87] = {
Inner IPv4
125.33.49.137 39.66.162.89 TCP 114
- 28402��11235[ACK] Seq = 2772490367 Ack = 2640082106 Win = 64440 Len = 0
+ 28402→11235[ACK] Seq = 2772490367 Ack = 2640082106 Win = 64440 Len = 0
*/
/* Frame (114 bytes) */
@@ -123,6 +123,64 @@ static const unsigned char pkt73[114] = {
0x9d, 0x5c, 0x74, 0xba, 0x50, 0x10, 0xfb, 0xb8, /* .\t.P... */
0x11, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* .)...... */
0x00, 0x00 /* .. */
+};
+
+/*47 Ether/IPv4/UDP/G-Vxlan/Cisco HDLC/IPv4/TCP
+
+ Outer IPv4
+ 172.26.127.189->172.26.78.1 UDP
+ User Datagram Protocol, Src Port: 50909 (50909), Dst Port: 4789 (4789)
+
+ 173.194.31.248 36.149.130.101 TCP 114 I->C
+ 443 → 21274[SYN, ACK] Seq = 0 Ack = 1 Win = 28400 Len = 0 MSS = 1432
+ SACK_PERM = 1 TSval = 3227044076 TSecr = 33726894 WS = 256 cert_Vxlan
+
+*/
+
+static const unsigned char pkt47[114] = {
+ 0xa0, 0x8c, 0xf8, 0xa9, 0x50, 0x3c, 0x74, 0x4a, /* ....P<tJ */
+ 0xa4, 0x1f, 0xf1, 0xc0, 0x08, 0x00, 0x45, 0x00, /* ......E. */
+ 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x11, /* .d...... */
+ 0x97, 0x95, 0xac, 0x1a, 0x7f, 0xbd, 0xac, 0x1a, /* ........ */
+ 0x4e, 0x01, 0xc6, 0xdd, 0x12, 0xb5, 0x00, 0x50, /* N......P */
+ 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x07, 0x3c, /* .......< */
+ 0x07, 0x00, 0x0f, 0x00, 0x08, 0x00, 0x45, 0x04, /* ......E. */
+ 0x00, 0x3c, 0x38, 0xbd, 0x00, 0x00, 0x33, 0x06, /* .<8...3. */
+ 0xda, 0x46, 0xad, 0xc2, 0x1f, 0xf8, 0x24, 0x95, /* .F....$. */
+ 0x82, 0x65, 0x01, 0xbb, 0x53, 0x1a, 0xd4, 0x51, /* .e..S..Q */
+ 0xaa, 0x9f, 0x1d, 0x0a, 0x08, 0x5c, 0xa0, 0x12, /* .....\.. */
+ 0x6e, 0xf0, 0x3e, 0x43, 0x00, 0x00, 0x02, 0x04, /* n.>C.... */
+ 0x05, 0x98, 0x04, 0x02, 0x08, 0x0a, 0xc0, 0x58, /* .......X */
+ 0xc8, 0xec, 0x02, 0x02, 0xa1, 0xae, 0x01, 0x03, /* ........ */
+ 0x03, 0x08 /* .. */
+};
+
+/*
+94 Ether/IPv4/UDP/G-Vxlan/PPP/IPv4/TCP
+
+ Outer IPv4
+ Internet Protocol Version 4, Src: 172.30.127.188 (172.30.127.188), Dst: NFJD302_V78.9 (172.30.78.9)
+ User Datagram Protocol, Src Port: 10000 (10000), Dst Port: 4789 (4789)
+
+ Inner IPv4
+ Internet Protocol Version 4, Src: 160.16.206.51 (160.16.206.51), Dst: 117.143.73.98 (117.143.73.98)
+ Transmission Control Protocol, Src Port: 443 (443), Dst Port: 18470 (18470), Seq: 0, Ack: 1, Len: 0
+*/
+
+static const unsigned char pkt94[98] = {
+ 0x48, 0x7b, 0x6b, 0xac, 0xe9, 0x2d, 0xb0, 0xf9, /* H{k..-.. */
+ 0x63, 0xd3, 0xb8, 0x01, 0x08, 0x00, 0x45, 0x00, /* c.....E. */
+ 0x00, 0x54, 0x64, 0x0f, 0x00, 0x00, 0xfe, 0x11, /* .Td..... */
+ 0x32, 0x87, 0xac, 0x1e, 0x7f, 0xbc, 0xac, 0x1e, /* 2....... */
+ 0x4e, 0x09, 0x27, 0x10, 0x12, 0xb5, 0x00, 0x40, /* N.'....@ */
+ 0xba, 0x8d, 0x08, 0x00, 0x00, 0x00, 0x08, 0x48, /* .......H */
+ 0x03, 0x00, 0xff, 0x03, 0x00, 0x21, 0x45, 0x04, /* .....!E. */
+ 0x00, 0x2c, 0x00, 0x00, 0x40, 0x00, 0x35, 0x06, /* .,[email protected]. */
+ 0x18, 0x93, 0xa0, 0x10, 0xce, 0x33, 0x75, 0x8f, /* .....3u. */
+ 0x49, 0x62, 0x01, 0xbb, 0x48, 0x26, 0xe2, 0xc5, /* Ib..H&.. */
+ 0xc9, 0xf6, 0x07, 0xed, 0x28, 0x5c, 0x60, 0x12, /* ....(\`. */
+ 0x39, 0x08, 0x0a, 0xf2, 0x00, 0x00, 0x02, 0x04, /* 9....... */
+ 0x05, 0xb4 /* .. */
};
#define TestCheckIPv4Addr(__result, __str_src_addr, __str_dst_addr) \
@@ -280,10 +338,103 @@ TEST(PacketParseInnerL4, EtherIPv4UDPVxlanEther)
EXPECT_TRUE(result->data != NULL);
TestCheckTCPPort(result, 28402, 11235);
+}
+
+TEST(PacketParseInnerL3, EtherIPv4UDPVxlanCHDLC)
+{
+ struct pkt_parser _pkt_47_handler;
+ _pkt_47_handler.expect_layer_type = LAYER_TYPE_L3;
+ _pkt_47_handler.nr_expect_results = 2;
+ _pkt_47_handler.nr_results = 0;
+
+ ASSERT_TRUE(complex_parser_ether(&_pkt_47_handler, pkt47) != NULL);
+ EXPECT_EQ(_pkt_47_handler.nr_results, 2);
+
+ struct pkt_parser_result * result = &_pkt_47_handler.results[0];
+ EXPECT_EQ(result->this_layer_type, LAYER_TYPE_IPV4);
+ EXPECT_TRUE(result->data != NULL);
+
+ TestCheckIPv4Addr(result, "172.26.127.189", "172.26.78.1");
+
+ result = &_pkt_47_handler.results[1];
+ EXPECT_EQ(result->this_layer_type, LAYER_TYPE_IPV4);
+ EXPECT_TRUE(result->data != NULL);
+
+ TestCheckIPv4Addr(result, "173.194.31.248", "36.149.130.101");
+}
+
+TEST(PacketParserInnerL4, EtherIPv4UDPVxlanCHDLC)
+{
+ struct pkt_parser _pkt_47_handler;
+ _pkt_47_handler.expect_layer_type = LAYER_TYPE_L4;
+ _pkt_47_handler.nr_expect_results = 2;
+ _pkt_47_handler.nr_results = 0;
+
+ ASSERT_TRUE(complex_parser_ether(&_pkt_47_handler, pkt47) != NULL);
+ EXPECT_EQ(_pkt_47_handler.nr_results, 2);
+
+ struct pkt_parser_result * result = &_pkt_47_handler.results[0];
+ EXPECT_EQ(result->this_layer_type, LAYER_TYPE_UDP);
+ EXPECT_TRUE(result->data != NULL);
+
+ TestCheckUDPPort(result, 50909, 4789);
+
+ result = &_pkt_47_handler.results[1];
+ EXPECT_EQ(result->this_layer_type, LAYER_TYPE_TCP);
+ EXPECT_TRUE(result->data != NULL);
+
+ TestCheckTCPPort(result, 443, 21274);
+}
+
+
+TEST(PacketParseInnerL3, EtherIPv4UDPVxlanPPP)
+{
+ struct pkt_parser _pkt_94_handler;
+ _pkt_94_handler.expect_layer_type = LAYER_TYPE_L3;
+ _pkt_94_handler.nr_expect_results = 2;
+ _pkt_94_handler.nr_results = 0;
+
+ ASSERT_TRUE(complex_parser_ether(&_pkt_94_handler, pkt94) != NULL);
+ EXPECT_EQ(_pkt_94_handler.nr_results, 2);
+
+ struct pkt_parser_result * result = &_pkt_94_handler.results[0];
+ EXPECT_EQ(result->this_layer_type, LAYER_TYPE_IPV4);
+ EXPECT_TRUE(result->data != NULL);
+
+ TestCheckIPv4Addr(result, "172.30.127.188", "172.30.78.9");
+
+ result = &_pkt_94_handler.results[1];
+ EXPECT_EQ(result->this_layer_type, LAYER_TYPE_IPV4);
+ EXPECT_TRUE(result->data != NULL);
+
+ TestCheckIPv4Addr(result, "160.16.206.51", "117.143.73.98");
+}
+
+TEST(PacketParserInnerL4, EtherIPv4UDPVxlanPPP)
+{
+ struct pkt_parser _pkt_94_handler;
+ _pkt_94_handler.expect_layer_type = LAYER_TYPE_L4;
+ _pkt_94_handler.nr_expect_results = 2;
+ _pkt_94_handler.nr_results = 0;
+
+ ASSERT_TRUE(complex_parser_ether(&_pkt_94_handler, pkt94) != NULL);
+ EXPECT_EQ(_pkt_94_handler.nr_results, 2);
+
+ struct pkt_parser_result * result = &_pkt_94_handler.results[0];
+ EXPECT_EQ(result->this_layer_type, LAYER_TYPE_UDP);
+ EXPECT_TRUE(result->data != NULL);
+
+ TestCheckUDPPort(result, 10000, 4789);
+
+ result = &_pkt_94_handler.results[1];
+ EXPECT_EQ(result->this_layer_type, LAYER_TYPE_TCP);
+ EXPECT_TRUE(result->data != NULL);
+
+ TestCheckTCPPort(result, 443, 18470);
}
-/* �����㷨���� */
-/* ��������1�� Ether/IPv4�������IP��ַ���� */
+/* 分流算法测试 */
+/* 测试用例1: Ether/IPv4,按外层IP地址分流 */
static const unsigned char stream_ipv4_pkt_0[78] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdc, 0x9b, /* ........ */
0x9c, 0xb2, 0x90, 0x51, 0x08, 0x00, 0x45, 0x00, /* ...Q..E. */
@@ -450,7 +601,7 @@ TEST(DistributerOuter4, EtherIPv4TCPOffloadIPv4)
}
-/* ��������2�� Ether/IPv6�������IP��ַ���� */
+/* 测试用例2: Ether/IPv6,按外层IP地址分流 */
/* Frame (94 bytes) */
static const unsigned char stream_ipv6_pkt_0[94] = {
0x00, 0x60, 0x97, 0x07, 0x69, 0xea, 0x00, 0x00, /* .`..i... */
@@ -616,7 +767,7 @@ TEST(DistributerOuter4, EtherIPv6TCPOffloadIPv4)
}
-/* ������������ Ether/IPv4/UDP/VxLAN��ר���豸��/Ether/IPv4 Ƕ�������ڲ�IP����
+/* 测试用例三: Ether/IPv4/UDP/VxLAN(专用设备)/Ether/IPv4 嵌套隧道内层IP分流
*/
/* Frame (114 bytes) */