diff options
| author | luwenpeng <[email protected]> | 2024-04-20 11:40:00 +0800 |
|---|---|---|
| committer | luwenpeng <[email protected]> | 2024-06-05 09:42:29 +0800 |
| commit | a0f1eca0ce6d481d79112926e56ddd3e1afe9fe0 (patch) | |
| tree | f01babe2a41094fc3f8d3181710402b9e8d83fd9 /common | |
| parent | 6b03470739e3f6b395af44c79218a3a285056339 (diff) | |
TSG-20717 Service Chaining增加全局链路号以支持无历史状态发包v1.3.2-20240628
Diffstat (limited to 'common')
| -rw-r--r-- | common/include/vxlan.h | 160 | ||||
| -rw-r--r-- | common/src/vxlan.cpp | 13 | ||||
| -rw-r--r-- | common/test/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | common/test/gtest_vxlan.cpp | 84 |
4 files changed, 199 insertions, 67 deletions
diff --git a/common/include/vxlan.h b/common/include/vxlan.h index 942c2f3..14e7548 100644 --- a/common/include/vxlan.h +++ b/common/include/vxlan.h @@ -12,7 +12,9 @@ extern "C" #include "tuple.h" /* - * VXLAN Header: + ****************************************************************************** + * Standard VXLAN Header: + ****************************************************************************** * * 0 1 2 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 @@ -28,87 +30,123 @@ extern "C" * to zero on transmission and ignored on receipt. * Reserved fields (24 bits and 8 bits): * MUST be set to zero on transmission and ignored on receipt. + * + ****************************************************************************** + * SCE VXLAN Header: + ****************************************************************************** + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |R|R|R|R|I|R|R|R| Reserved |S| Traffic Link ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | high | type | low |D|T|SF index |T| Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Flags : 8 bits + * Reserved : 7 bits + * S (StateLess) : 1 bit + * + * Traffic Link ID : 16 bits + * + * vlan_id_half_high : 8 bits + * link_layer_type : 4 bits // 二层报文封装格式 + * vlan_id_half_low : 4 bits + * + * dir : 1 bit + * traffic : 1 bit + * sf_index : 5 bits // max value 32 + * online_test : 1 bit + * + * Reserved : 8 bit */ struct vxlan_hdr { - uint8_t flags; - uint8_t reserved[3]; - - // VNI 3 Bytes - uint8_t vlan_id_half_high; - - uint8_t link_layer_type : 4; // 二层报文封装格式 - uint8_t vlan_id_half_low : 4; - - uint8_t dir : 1; - uint8_t traffic : 1; - uint8_t sf_index : 5; // max value 32 - uint8_t online_test : 1; - - // Reserved 1 Bytes - uint8_t r7 : 1; - uint8_t r6 : 1; - uint8_t r5 : 1; - uint8_t r4 : 1; - uint8_t vni_flag : 1; - uint8_t r2 : 1; - uint8_t r1 : 1; - uint8_t r0 : 1; + uint16_t flags_reserved; + uint16_t link_id; + uint16_t vlan_id; + uint16_t user_ctx; } __attribute__((__packed__)); -enum vni_opt +#define VXLAN_DEFAULT_FLAGS 0x8 +#define VXLAN_DST_PORT 4789 +#define VXLAN_FRAME_HDR_LEN ((int)(sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udphdr) + sizeof(struct vxlan_hdr))) + +#define VXLAN_FLAGS_MASK 0xFF00 +#define VXLAN_STATELESS_MASK 0x0001 +#define VXLAN_DIR_MASK 0x8000 +#define VXLAN_TRAFFIC_MASK 0x4000 +#define VXLAN_SF_INDEX_MASK 0x3E00 + +static inline void vxlan_set_flags(struct vxlan_hdr *hdr, uint8_t flags) { - VNI_OPT_DIR = 0x80, - VNI_OPT_TRAFFIC = 0x40, - VNI_OPT_SFINDEX = 0x3f, -}; + hdr->flags_reserved = htons((ntohs(hdr->flags_reserved) & ~VXLAN_FLAGS_MASK) | (flags << 8)); +} -#define VXLAN_FLAGS 0x8 -#define VXLAN_DST_PORT 4789 -#define VXLAN_FRAME_HDR_LEN (sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udphdr) + sizeof(struct vxlan_hdr)) +static inline void vxlan_set_dir(struct vxlan_hdr *hdr, uint8_t val) +{ + hdr->user_ctx = htons((ntohs(hdr->user_ctx) & ~VXLAN_DIR_MASK) | ((!!val) << 15)); +} + +static inline void vxlan_set_traffic(struct vxlan_hdr *hdr, uint8_t val) +{ + hdr->user_ctx = htons((ntohs(hdr->user_ctx) & ~VXLAN_TRAFFIC_MASK) | ((!!val) << 14)); +} + +static inline void vxlan_set_sf_index(struct vxlan_hdr *hdr, uint8_t val) +{ + hdr->user_ctx = htons((ntohs(hdr->user_ctx) & ~VXLAN_SF_INDEX_MASK) | ((val & 0x1F) << 9)); +} + +static inline void vxlan_set_link_id(struct vxlan_hdr *hdr, uint16_t val) +{ + hdr->link_id = htons(val); +} + +static inline void vxlan_set_stateless(struct vxlan_hdr *hdr, uint8_t val) +{ + hdr->flags_reserved = htons((ntohs(hdr->flags_reserved) & ~VXLAN_STATELESS_MASK) | (!!val)); +} + +static inline uint8_t vxlan_get_flags(struct vxlan_hdr *hdr) +{ + return ((ntohs(hdr->flags_reserved) & VXLAN_FLAGS_MASK) >> 8); +} + +static inline uint8_t vxlan_get_dir(struct vxlan_hdr *hdr) +{ + return ((ntohs(hdr->user_ctx) & VXLAN_DIR_MASK) >> 15); +} + +static inline uint8_t vxlan_get_traffic(struct vxlan_hdr *hdr) +{ + return ((ntohs(hdr->user_ctx) & VXLAN_TRAFFIC_MASK) >> 14); +} + +static inline uint8_t vxlan_get_sf_index(struct vxlan_hdr *hdr) +{ + return ((ntohs(hdr->user_ctx) & VXLAN_SF_INDEX_MASK) >> 9); +} -static inline void vxlan_set_opt(struct vxlan_hdr *hdr, enum vni_opt opt, uint8_t val) +static inline uint16_t vxlan_get_link_id(struct vxlan_hdr *hdr) { - switch (opt) - { - case VNI_OPT_DIR: - hdr->dir = (!!val); - break; - case VNI_OPT_TRAFFIC: - hdr->traffic = (!!val); - break; - case VNI_OPT_SFINDEX: - hdr->sf_index = (0x1f & val); - break; - default: - break; - } + return ntohs(hdr->link_id); } -static inline uint8_t vxlan_get_opt(struct vxlan_hdr *hdr, enum vni_opt opt) +static inline uint8_t vxlan_get_stateless(struct vxlan_hdr *hdr) { - switch (opt) - { - case VNI_OPT_DIR: - return hdr->dir; - case VNI_OPT_TRAFFIC: - return hdr->traffic; - case VNI_OPT_SFINDEX: - return hdr->sf_index; - default: - return 0; - } + return ntohs(hdr->flags_reserved) & VXLAN_STATELESS_MASK; } // return 0 : success // return -1 : error -int vxlan_frame_decode(struct vxlan_hdr **vxlan_hdr, const char *data, uint16_t len); +int vxlan_frame_decode(struct vxlan_hdr **vxlan_hdr, const char *data, int len); void vxlan_frame_encode(char *buff, const u_char eth_src_mac[], const u_char eth_dst_mac[], const in_addr_t ip_src_addr, const in_addr_t ip_dst_addr, uint16_t ip_id, uint16_t udp_src_port, uint16_t udp_pld_len, - uint8_t vni_opt_dir, uint8_t vni_opt_traffic, uint8_t vni_opt_sf_index); + uint8_t dir, uint8_t traffic, uint8_t sf_index, uint16_t link_id); uint16_t calculate_vxlan_source_port(struct four_tuple *innermost_tuple4); diff --git a/common/src/vxlan.cpp b/common/src/vxlan.cpp index d5c86d7..d53d036 100644 --- a/common/src/vxlan.cpp +++ b/common/src/vxlan.cpp @@ -69,7 +69,7 @@ static inline void udp_header_encode(struct udphdr *udp_hdr, uint16_t udp_sport, // return 0 : success // return -1 : error -int vxlan_frame_decode(struct vxlan_hdr **vxlan_hdr, const char *data, uint16_t len) +int vxlan_frame_decode(struct vxlan_hdr **vxlan_hdr, const char *data, int len) { if (len < VXLAN_FRAME_HDR_LEN) { @@ -103,7 +103,7 @@ void vxlan_frame_encode(char *buff, const u_char eth_src_mac[], const u_char eth_dst_mac[], const in_addr_t ip_src_addr, const in_addr_t ip_dst_addr, uint16_t ip_id, uint16_t udp_src_port, uint16_t udp_pld_len, - uint8_t vni_opt_dir, uint8_t vni_opt_traffic, uint8_t vni_opt_sf_index) + uint8_t dir, uint8_t traffic, uint8_t sf_index, uint16_t link_id) { struct ethhdr *eth_hdr = (struct ethhdr *)buff; struct ip *ip_hdr = (struct ip *)((char *)eth_hdr + sizeof(struct ethhdr)); @@ -112,10 +112,11 @@ void vxlan_frame_encode(char *buff, // MUST be set to zero memset(vxlan_hdr, 0, sizeof(struct vxlan_hdr)); - vxlan_hdr->flags = VXLAN_FLAGS; - vxlan_set_opt(vxlan_hdr, VNI_OPT_DIR, vni_opt_dir); - vxlan_set_opt(vxlan_hdr, VNI_OPT_TRAFFIC, vni_opt_traffic); - vxlan_set_opt(vxlan_hdr, VNI_OPT_SFINDEX, vni_opt_sf_index); + vxlan_set_flags(vxlan_hdr, VXLAN_DEFAULT_FLAGS); + vxlan_set_dir(vxlan_hdr, dir); + vxlan_set_traffic(vxlan_hdr, traffic); + vxlan_set_sf_index(vxlan_hdr, sf_index); + vxlan_set_link_id(vxlan_hdr, link_id); eth_header_encode(eth_hdr, eth_src_mac, eth_dst_mac, ETH_P_IP); ip_header_encode(ip_hdr, ip_src_addr, ip_dst_addr, ip_id, IPPROTO_UDP, sizeof(struct udphdr) + sizeof(struct vxlan_hdr) + udp_pld_len); diff --git a/common/test/CMakeLists.txt b/common/test/CMakeLists.txt index 24073e0..f31c21e 100644 --- a/common/test/CMakeLists.txt +++ b/common/test/CMakeLists.txt @@ -31,6 +31,14 @@ target_include_directories(gtest_utils PUBLIC ${CMAKE_SOURCE_DIR}/common/include target_link_libraries(gtest_utils common gtest) ############################################################################### +# gtest_vxlan +############################################################################### + +add_executable(gtest_vxlan gtest_vxlan.cpp) +target_include_directories(gtest_vxlan PUBLIC ${CMAKE_SOURCE_DIR}/common/include) +target_link_libraries(gtest_vxlan common gtest) + +############################################################################### # gtest_health_check_table ############################################################################### @@ -47,4 +55,5 @@ gtest_discover_tests(gtest_session_table) gtest_discover_tests(gtest_control_packet) gtest_discover_tests(gtest_packet) gtest_discover_tests(gtest_utils) +gtest_discover_tests(gtest_vxlan) gtest_discover_tests(gtest_health_check_table) diff --git a/common/test/gtest_vxlan.cpp b/common/test/gtest_vxlan.cpp new file mode 100644 index 0000000..a6e838b --- /dev/null +++ b/common/test/gtest_vxlan.cpp @@ -0,0 +1,84 @@ +#include <gtest/gtest.h> + +#include "vxlan.h" + +static inline void hexdump(const char *data, int len) +{ + for (int i = 0; i < len; i++) + { + printf("%02x ", data[i]); + } + printf("\n"); +} + +TEST(VXLAN, TEST1) +{ + char buff[8] = {0}; + struct vxlan_hdr *hdr = (struct vxlan_hdr *)buff; + + vxlan_set_flags(hdr, VXLAN_DEFAULT_FLAGS); + vxlan_set_dir(hdr, 0); + vxlan_set_traffic(hdr, 0); + vxlan_set_sf_index(hdr, 0); + vxlan_set_link_id(hdr, 0); + vxlan_set_stateless(hdr, 0); + + EXPECT_TRUE(vxlan_get_flags(hdr) == VXLAN_DEFAULT_FLAGS); + EXPECT_TRUE(vxlan_get_dir(hdr) == 0); + EXPECT_TRUE(vxlan_get_traffic(hdr) == 0); + EXPECT_TRUE(vxlan_get_sf_index(hdr) == 0); + EXPECT_TRUE(vxlan_get_link_id(hdr) == 0); + EXPECT_TRUE(vxlan_get_stateless(hdr) == 0); + + hexdump(buff, 8); +} + +TEST(VXLAN, TEST2) +{ + char buff[8] = {0}; + struct vxlan_hdr *hdr = (struct vxlan_hdr *)buff; + + vxlan_set_flags(hdr, VXLAN_DEFAULT_FLAGS); + vxlan_set_dir(hdr, 1); + vxlan_set_traffic(hdr, 1); + vxlan_set_sf_index(hdr, 1); + vxlan_set_link_id(hdr, 1); + vxlan_set_stateless(hdr, 1); + + EXPECT_TRUE(vxlan_get_flags(hdr) == VXLAN_DEFAULT_FLAGS); + EXPECT_TRUE(vxlan_get_dir(hdr) == 1); + EXPECT_TRUE(vxlan_get_traffic(hdr) == 1); + EXPECT_TRUE(vxlan_get_sf_index(hdr) == 1); + EXPECT_TRUE(vxlan_get_link_id(hdr) == 1); + EXPECT_TRUE(vxlan_get_stateless(hdr) == 1); + + hexdump(buff, 8); +} + +TEST(VXLAN, TEST3) +{ + char buff[8] = {0}; + struct vxlan_hdr *hdr = (struct vxlan_hdr *)buff; + + vxlan_set_flags(hdr, VXLAN_DEFAULT_FLAGS); + vxlan_set_dir(hdr, 1); + vxlan_set_traffic(hdr, 1); + vxlan_set_sf_index(hdr, 31); + vxlan_set_link_id(hdr, 65535); + vxlan_set_stateless(hdr, 1); + + EXPECT_TRUE(vxlan_get_flags(hdr) == VXLAN_DEFAULT_FLAGS); + EXPECT_TRUE(vxlan_get_dir(hdr) == 1); + EXPECT_TRUE(vxlan_get_traffic(hdr) == 1); + EXPECT_TRUE(vxlan_get_sf_index(hdr) == 31); + EXPECT_TRUE(vxlan_get_link_id(hdr) == 65535); + EXPECT_TRUE(vxlan_get_stateless(hdr) == 1); + + hexdump(buff, 8); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}
\ No newline at end of file |
