diff options
| author | Qiuwen Lu <[email protected]> | 2016-11-07 16:37:07 +0800 |
|---|---|---|
| committer | Qiuwen Lu <[email protected]> | 2016-11-07 16:37:07 +0800 |
| commit | e3d37338024044f71d39c9ffe268d0f718af6b86 (patch) | |
| tree | 9a38dd26511f683863f5a7a029e18d1e639b82d3 | |
| parent | 1ab83329c1f6a55c486449328b5cc92a37934a9e (diff) | |
重构负载分担计算部分代码,支持二层隧道解析计算。
| -rw-r--r-- | service/include/sc_common.h | 4 | ||||
| -rw-r--r-- | service/src/config.c | 2 | ||||
| -rw-r--r-- | service/src/ldbc.c | 222 |
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: |
