summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQiuwen Lu <[email protected]>2016-11-07 16:37:07 +0800
committerQiuwen Lu <[email protected]>2016-11-07 16:37:07 +0800
commite3d37338024044f71d39c9ffe268d0f718af6b86 (patch)
tree9a38dd26511f683863f5a7a029e18d1e639b82d3
parent1ab83329c1f6a55c486449328b5cc92a37934a9e (diff)
重构负载分担计算部分代码,支持二层隧道解析计算。
-rw-r--r--service/include/sc_common.h4
-rw-r--r--service/src/config.c2
-rw-r--r--service/src/ldbc.c222
3 files changed, 94 insertions, 134 deletions
diff --git a/service/include/sc_common.h b/service/include/sc_common.h
index 61d4394..e629873 100644
--- a/service/include/sc_common.h
+++ b/service/include/sc_common.h
@@ -48,9 +48,9 @@ TAILQ_HEAD(sc_app_list, sc_app);
enum _e_dist_mode
{
/* ������Ԫ���ϣ */
- LDBC_DIST_SIMPLE_TUPLE2 = 0,
+ LDBC_DIST_OUTER_TUPLE2 = 0,
/* ������Ԫ���ϣ */
- LDBC_DIST_SIMPLE_TUPLE4 = 1,
+ LDBC_DIST_OUTER_TUPLE4 = 1,
/* ʹ��Ӳ�������� */
LDBC_DIST_HARDWARE = 2
};
diff --git a/service/src/config.c b/service/src/config.c
index b121f07..8193d39 100644
--- a/service/src/config.c
+++ b/service/src/config.c
@@ -39,7 +39,7 @@
#endif
#ifndef MR_SERVICE_DEFAULT_DIST_MODE
-#define MR_SERVICE_DEFAULT_DIST_MODE LDBC_DIST_SIMPLE_TUPLE2
+#define MR_SERVICE_DEFAULT_DIST_MODE LDBC_DIST_OUTER_TUPLE2
#endif
#if MR_SERVICE_DEFAULT_SZ_RX_BURST > MR_BURST_MAX
diff --git a/service/src/ldbc.c b/service/src/ldbc.c
index 8e9f016..754e7af 100644
--- a/service/src/ldbc.c
+++ b/service/src/ldbc.c
@@ -18,46 +18,6 @@
#include <assert.h>
#include <linux/if_ether.h>
-#if RTE_VERSION <= RTE_VERSION_NUM(16,04,0,0) // CRC32 2byte is not defined in DPDK 2.1, Port from 16.04
-
-#define CRC32_UPD(crc, n) \
- (crc32c_tables[(n)][(crc) & 0xFF] ^ \
- crc32c_tables[(n)-1][((crc) >> 8) & 0xFF])
-
-// CRC32 2Bytes in SSE
-static inline uint32_t crc32c_sse42_u16(uint16_t data, uint32_t init_val)
-{
- __asm__ volatile(
- "crc32w %[data], %[init_val];"
- : [init_val] "+r" (init_val)
- : [data] "rm" (data));
- return init_val;
-}
-
-static inline uint32_t crc32c_2bytes(uint16_t data, uint32_t init_val)
-{
- uint32_t crc;
- crc = init_val;
- crc ^= data;
-
- crc = CRC32_UPD(crc, 1) ^ (crc >> 16);
-
- return crc;
-}
-
-// CRC32 2Bytes
-static inline uint32_t rte_hash_crc_2byte(uint16_t data, uint32_t init_val)
-{
-#if defined RTE_ARCH_I686 || defined RTE_ARCH_X86_64
- if (likely(crc32_alg & CRC32_SSE42))
- return crc32c_sse42_u16(data, init_val);
-#endif
-
- return crc32c_2bytes(data, init_val);
-}
-
-#endif
-
enum
{
/* 以太网头 */
@@ -108,8 +68,8 @@ static void * __complex_parser_pppoe_ses(void * data, int this_layer_type,
return data;
}
-#define PPPOE_TYPE_IPV4 0x0021
-#define PPPOE_TYPE_IPV6 0x0057
+#define PPPOE_TYPE_IPV4 0x2100
+#define PPPOE_TYPE_IPV6 0x5700
uint16_t pppoe_type = *((uint16_t *)data + 3);
void * data_next_layer = (uint8_t *)data + 8;
@@ -170,7 +130,7 @@ static void * __complex_parser_mpls_uc(void * data, int this_layer_type,
}
}
-static void * __complex_parser_vlan8021q(void * data, int this_layer_type,
+static const void * __complex_parser_vlan8021q(const void * data, int this_layer_type,
int expect_layer_type, int * layer_type_out)
{
if (expect_layer_type == LAYER_TYPE_VLAN || expect_layer_type == LAYER_TYPE_L2TUN)
@@ -211,7 +171,7 @@ static void * __complex_parser_vlan8021q(void * data, int this_layer_type,
return NULL;
}
-static void * __complex_parser_ether(void * data, int this_layer_type,
+static const void * __complex_parser_ether(const void * data, int this_layer_type,
int expect_layer_type, int * layer_type_out)
{
if (expect_layer_type == LAYER_TYPE_ETHER)
@@ -252,128 +212,128 @@ static void * __complex_parser_ether(void * data, int this_layer_type,
return NULL;
}
-static void * complex_parser_ether(void * data, int this_layer_type,
+static const void * complex_parser_ether(const void * data, int this_layer_type,
int expect_layer_type, int * layer_type_out)
{
return __complex_parser_ether(data, this_layer_type, expect_layer_type, layer_type_out);
}
-static uint32_t __hash_simple_tuple2(struct rte_mbuf * mbuf, uint32_t orin_hash __rte_unused)
+static inline uint32_t hash_l4_layer(const void * data, int layer_type, uint32_t orin_hash)
{
- const char * data = NULL;
- const char * p_str_ip = NULL;
- const char * p_dst_ip = NULL;
+ const char * p_src_port;
+ const char * p_dst_port;
+ uint8_t port_len = 0;
- uint8_t ip_len = 0;
- uint32_t src_hash = 0;
- uint32_t dst_hash = 0;
+ if (data == NULL) return 0;
- // IPv4 Header
- if (RTE_ETH_IS_IPV4_HDR(mbuf->packet_type))
+ if (layer_type == LAYER_TYPE_TCP)
{
- data = rte_pktmbuf_mtod_offset(mbuf, const char *, sizeof(struct ether_hdr));
- const struct ipv4_hdr * ether_hdr = (const struct ipv4_hdr *)data;
- p_str_ip = (const char *)&(ether_hdr->src_addr);
- p_dst_ip = (const char *)&(ether_hdr->dst_addr);
- ip_len = 4;
- }
-
- // IPv6 Header
- else if (RTE_ETH_IS_IPV4_HDR(mbuf->packet_type))
- {
- data = rte_pktmbuf_mtod_offset(mbuf, const char *, sizeof(struct ether_hdr));
- const struct ipv6_hdr * ipv6_hdr = (const struct ipv6_hdr *)data;
- p_str_ip = (const char *)&(ipv6_hdr->src_addr);
- p_dst_ip = (const char *)&(ipv6_hdr->dst_addr);
- ip_len = 16;
+ const struct tcp_hdr * tcp_hdr = (const struct tcp_hdr *)data;
+ p_src_port = (const char *)&tcp_hdr->src_port;
+ p_dst_port = (const char *)&tcp_hdr->dst_port;
+ port_len = sizeof(struct tcp_hdr);
}
- else
+ else if(layer_type == LAYER_TYPE_UDP)
{
- return 0;
+ const struct udp_hdr * udp_hdr = (const struct udp_hdr *)data;
+ p_src_port = (const char *)&udp_hdr->src_port;
+ p_dst_port = (const char *)&udp_hdr->dst_port;
+ port_len = sizeof(struct tcp_hdr);
}
+ else return 0;
- src_hash = rte_hash_crc(p_str_ip, ip_len, src_hash);
- dst_hash = rte_hash_crc(p_dst_ip, ip_len, dst_hash);
+ uint32_t src_hash = rte_hash_crc(p_src_port, port_len, orin_hash);
+ uint32_t dst_hash = rte_hash_crc(p_dst_port, port_len, orin_hash);
return src_hash ^ dst_hash;
}
-static uint32_t __hash_simple_tuple4(struct rte_mbuf * mbuf, uint32_t orin_hash __rte_unused)
+static inline uint32_t hash_ip_layer(const void * data, int layer_type, uint32_t orin_hash)
{
- const char * data = NULL;
- const char * p_str_ip = NULL;
- const char * p_dst_ip = NULL;
- const char * p_src_port = NULL;
- const char * p_dst_port = NULL;
- const char * p_proto = NULL;
-
+ const char * p_str_ip;
+ const char * p_dst_ip;
uint8_t ip_len = 0;
- uint8_t port_len = 2;
- uint32_t src_hash = 0;
- uint32_t dst_hash = 0;
- if (RTE_ETH_IS_IPV4_HDR(mbuf->packet_type))
+ if (data == NULL) return 0;
+
+ if(layer_type == LAYER_TYPE_IPV4)
{
- data = rte_pktmbuf_mtod_offset(mbuf, const char *, sizeof(struct ether_hdr));
const struct ipv4_hdr * ether_hdr = (const struct ipv4_hdr *)data;
p_str_ip = (const char *)&(ether_hdr->src_addr);
p_dst_ip = (const char *)&(ether_hdr->dst_addr);
- p_proto = (const char *)&(ether_hdr->next_proto_id);
ip_len = 4;
-
- data += sizeof(struct ipv4_hdr);
}
-
- else if (RTE_ETH_IS_IPV6_HDR(mbuf->packet_type))
+ else if(layer_type == LAYER_TYPE_IPV6)
{
- data = rte_pktmbuf_mtod_offset(mbuf, const char *, sizeof(struct ether_hdr));
const struct ipv6_hdr * ipv6_hdr = (const struct ipv6_hdr *)data;
p_str_ip = (const char *)&(ipv6_hdr->src_addr);
p_dst_ip = (const char *)&(ipv6_hdr->dst_addr);
- p_proto = (const char *)&(ipv6_hdr->proto);
ip_len = 16;
-
- data += sizeof(struct ipv6_hdr);
}
+ else return 0;
- // Not IPv4 or IPv6, cannot parse.
- else
- {
- return 0;
- }
+ uint32_t src_hash = rte_hash_crc(p_str_ip, ip_len, orin_hash);
+ uint32_t dst_hash = rte_hash_crc(p_dst_ip, ip_len, orin_hash);
+ return src_hash ^ dst_hash;
+}
- // Now Data is jumped from ether header and ip header;
- // Try to parse transport layer.
- // TCP Packets
- if (mbuf->packet_type & RTE_PTYPE_L4_TCP)
+static inline uint32_t __distributer_outer_tuple2(struct rte_mbuf * mbuf, uint32_t orin_hash)
+{
+ const char * data;
+ int layer_type;
+
+ if(RTE_ETH_IS_IPV4_HDR(mbuf->packet_type))
{
- const struct tcp_hdr * tcp_hdr = (const struct tcp_hdr *)data;
- p_src_port = (const char *)&tcp_hdr->src_port;
- p_dst_port = (const char *)&tcp_hdr->dst_port;
- data += sizeof(struct tcp_hdr);
+ data = rte_pktmbuf_mtod_offset(mbuf, const char *, sizeof(struct ether_hdr));
+ return hash_ip_layer(data, LAYER_TYPE_IPV4, orin_hash);
}
- // UDP Packets
- else if (mbuf->packet_type & RTE_PTYPE_L4_UDP)
+ else if(RTE_ETH_IS_IPV6_HDR(mbuf->packet_type))
{
- const struct udp_hdr * udp_hdr = (const struct udp_hdr *)data;
- p_src_port = (const char *)&udp_hdr->src_port;
- p_dst_port = (const char *)&udp_hdr->dst_port;
- data += sizeof(struct tcp_hdr);
+ data = rte_pktmbuf_mtod_offset(mbuf, const char *, sizeof(struct ether_hdr));
+ return hash_ip_layer(data, LAYER_TYPE_IPV6, orin_hash);
}
- // Not TCP or UDP Packets
else
{
- return 0;
+ data = complex_parser_ether(rte_pktmbuf_mtod(mbuf, const void *), LAYER_TYPE_ETHER,
+ LAYER_TYPE_IP, &layer_type);
+ return hash_ip_layer(data, layer_type, orin_hash);
}
+}
- // We have the address of necessory information,
- // caculate the hash value;
- src_hash = rte_hash_crc(p_str_ip, ip_len, src_hash);
- src_hash = rte_hash_crc(p_src_port, port_len, src_hash);
- dst_hash = rte_hash_crc(p_dst_ip, ip_len, dst_hash);
- dst_hash = rte_hash_crc(p_dst_port, port_len, dst_hash);
+static inline uint32_t __distributer_outer_tuple4(struct rte_mbuf * mbuf, uint32_t orin_hash)
+{
+ const char * data = NULL;
+ int layer_type = 0;
+ int layer_len = 0;
+
+ 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;
+ }
+ else 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_IPV6;
+ }
- return src_hash ^ dst_hash;
+ if (layer_type == LAYER_TYPE_IPV4) layer_len = sizeof(struct ipv4_hdr);
+ else if (layer_type == LAYER_TYPE_IPV6) layer_len = sizeof(struct ipv6_hdr);
+ else return 0;
+
+ uint32_t ip_hash = hash_ip_layer(data, layer_type, orin_hash);
+ if (ip_hash == 0) return 0;
+
+ if(mbuf->packet_type & RTE_PTYPE_L4_TCP)
+ {
+ return hash_l4_layer(data + layer_len, LAYER_TYPE_TCP, ip_hash);
+ }
+ else if(mbuf->packet_type & RTE_PTYPE_L4_TCP)
+ {
+ return hash_l4_layer(data + layer_len, LAYER_TYPE_UDP, ip_hash);
+ }
+
+ return ip_hash;
}
//TODO: SSE/SSE2/AVX/AVX2加速
@@ -381,19 +341,19 @@ static uint32_t __hash_simple_tuple4(struct rte_mbuf * mbuf, uint32_t orin_hash
//TODO: 为0,也许有更好的处理方法。
//TODO: 缓存预取
-static inline int distributer_simple_tuple2(struct rte_mbuf * mbufs[],
+static inline int distributer_outer_tuple2(struct rte_mbuf * mbufs[],
unsigned int nr_mbufs, hash_t result[])
{
for (int i = 0; i < nr_mbufs; i++)
- result[i] = __hash_simple_tuple2(mbufs[i], 0);
+ result[i] = __distributer_outer_tuple2(mbufs[i], 0);
return 0;
}
-static inline int distributer_simple_tuple4(struct rte_mbuf * mbufs[],
+static inline int distributer_outer_tuple4(struct rte_mbuf * mbufs[],
unsigned int nr_mbufs, hash_t result[])
{
for (int i = 0; i < nr_mbufs; i++)
- result[i] = __hash_simple_tuple4(mbufs[i], 0);
+ result[i] = __distributer_outer_tuple2(mbufs[i], 0);
return 0;
}
@@ -423,10 +383,10 @@ int distributer_hash_caculate(unsigned int distmode, struct rte_mbuf * mbufs[],
{
switch (distmode)
{
- case LDBC_DIST_SIMPLE_TUPLE2:
- return distributer_simple_tuple2(mbufs, nr_mbufs, result);
- case LDBC_DIST_SIMPLE_TUPLE4:
- return distributer_simple_tuple4(mbufs, nr_mbufs, result);
+ case LDBC_DIST_OUTER_TUPLE2:
+ return distributer_outer_tuple2(mbufs, nr_mbufs, result);
+ case LDBC_DIST_OUTER_TUPLE4:
+ return distributer_outer_tuple4(mbufs, nr_mbufs, result);
case LDBC_DIST_HARDWARE:
return distributer_hardware(mbufs, nr_mbufs, result);
default: