From 3ce5ed11dbda2d6adf86f6e5333b6592d8377829 Mon Sep 17 00:00:00 2001 From: luwenpeng Date: Wed, 5 Jun 2024 14:36:04 +0800 Subject: [PATCH] Add VXLAN utils --- src/packet/packet.cpp | 10 +--- src/packet/test/CMakeLists.txt | 4 ++ src/packet/test/gtest_vxlan_utils.cpp | 43 ++++++++++++++++ src/packet/vxlan_utils.h | 74 +++++++++++++++++++++++++++ 4 files changed, 123 insertions(+), 8 deletions(-) create mode 100644 src/packet/test/gtest_vxlan_utils.cpp create mode 100644 src/packet/vxlan_utils.h diff --git a/src/packet/packet.cpp b/src/packet/packet.cpp index b8b4035..4ed8cf6 100644 --- a/src/packet/packet.cpp +++ b/src/packet/packet.cpp @@ -13,6 +13,7 @@ #include "mpls_utils.h" #include "eth_utils.h" #include "vlan_utils.h" +#include "vxlan_utils.h" #define likely(expr) __builtin_expect((expr), 1) #define unlikely(expr) __builtin_expect((expr), 0) @@ -1222,14 +1223,6 @@ static inline const char *parse_icmp6(struct packet *pkt, const char *data, uint static inline const char *parse_vxlan(struct packet *pkt, const char *data, uint16_t len) { - struct vxlan_hdr - { - uint8_t flags[2]; - uint16_t gdp; - uint8_t vni[3]; - uint8_t reserved; - } __attribute__((__packed__)); - if (unlikely(len < sizeof(struct vxlan_hdr))) { PACKET_LOG_DATA_INSUFFICIENCY(pkt, LAYER_TYPE_VXLAN); @@ -1403,6 +1396,7 @@ void packet_print_str(const struct packet *pkt) case LAYER_TYPE_ICMP6: break; case LAYER_TYPE_VXLAN: + used = vxlan_hdr_to_str((const struct vxlan_hdr *)layer->hdr_ptr, buffer, sizeof(buffer)); break; case LAYER_TYPE_GTPV1_U: break; diff --git a/src/packet/test/CMakeLists.txt b/src/packet/test/CMakeLists.txt index c0bb9da..867022b 100644 --- a/src/packet/test/CMakeLists.txt +++ b/src/packet/test/CMakeLists.txt @@ -22,6 +22,9 @@ target_link_libraries(gtest_eth_utils packet gtest) add_executable(gtest_vlan_utils gtest_vlan_utils.cpp) target_link_libraries(gtest_vlan_utils packet gtest) +add_executable(gtest_vxlan_utils gtest_vxlan_utils.cpp) +target_link_libraries(gtest_vxlan_utils packet gtest) + add_executable(gtest_packet_frag gtest_packet_frag.cpp) target_link_libraries(gtest_packet_frag packet gtest) @@ -34,4 +37,5 @@ gtest_discover_tests(gtest_ipv6_utils) gtest_discover_tests(gtest_mpls_utils) gtest_discover_tests(gtest_eth_utils) gtest_discover_tests(gtest_vlan_utils) +gtest_discover_tests(gtest_vxlan_utils) gtest_discover_tests(gtest_packet_frag) \ No newline at end of file diff --git a/src/packet/test/gtest_vxlan_utils.cpp b/src/packet/test/gtest_vxlan_utils.cpp new file mode 100644 index 0000000..5e22f2a --- /dev/null +++ b/src/packet/test/gtest_vxlan_utils.cpp @@ -0,0 +1,43 @@ +#include + +#include "vxlan_utils.h" + +/* + * Virtual eXtensible Local Area Network + * Flags: 0x0800, VXLAN Network ID (VNI) + * 0... .... .... .... = GBP Extension: Not defined + * .... 1... .... .... = VXLAN Network ID (VNI): True + * .... .... .0.. .... = Don't Learn: False + * .... .... .... 0... = Policy Applied: False + * .000 .000 0.00 .000 = Reserved(R): 0x0000 + * Group Policy ID: 0 + * VXLAN Network Identifier (VNI): 461829 + * Reserved: 0 + */ + +unsigned char data[] = { + 0x08, 0x00, 0x00, 0x00, 0x07, 0x0c, 0x05, 0x00}; + +TEST(VXLAN_UTILS, GET) +{ + const struct vxlan_hdr *hdr = (struct vxlan_hdr *)data; + + EXPECT_TRUE(vxlan_hdr_get_flags(hdr) == 0x08); + EXPECT_TRUE(vxlan_hdr_get_vni(hdr) == 461829); +} + +TEST(VXLAN_UTILS, SET) +{ + char buff[8] = {0}; + struct vxlan_hdr *hdr = (struct vxlan_hdr *)buff; + + vxlan_hdr_set_flags(hdr, 0x08); + vxlan_hdr_set_vni(hdr, 461829); + EXPECT_TRUE(memcmp(buff, data, 8) == 0); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/packet/vxlan_utils.h b/src/packet/vxlan_utils.h new file mode 100644 index 0000000..57a9c9e --- /dev/null +++ b/src/packet/vxlan_utils.h @@ -0,0 +1,74 @@ +#ifndef _VXLAN_UTILS_H +#define _VXLAN_UTILS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include +#include +#include + +/* + * 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 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | VXLAN Network Identifier (VNI) | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +struct vxlan_hdr +{ + uint32_t vxlan_flags; + uint32_t vxlan_vni; +}; + +/****************************************************************************** + * get + ******************************************************************************/ + +static inline uint8_t vxlan_hdr_get_flags(const struct vxlan_hdr *hdr) +{ + return (ntohl(hdr->vxlan_flags) & 0xff000000) >> 24; +} + +static inline uint32_t vxlan_hdr_get_vni(const struct vxlan_hdr *hdr) +{ + return (ntohl(hdr->vxlan_vni) & 0xffffff00) >> 8; +} + +/****************************************************************************** + * set + ******************************************************************************/ + +static inline void vxlan_hdr_set_flags(struct vxlan_hdr *hdr, uint8_t flags) +{ + hdr->vxlan_flags = htonl((ntohl(hdr->vxlan_flags) & ~0xff000000) | (flags << 24)); +} + +static inline void vxlan_hdr_set_vni(struct vxlan_hdr *hdr, uint32_t vni) +{ + hdr->vxlan_vni = htonl((ntohl(hdr->vxlan_vni) & ~0xffffff00) | (vni << 8)); +} + +/****************************************************************************** + * print + ******************************************************************************/ + +static inline int vxlan_hdr_to_str(const struct vxlan_hdr *hdr, char *buf, size_t size) +{ + memset(buf, 0, size); + return snprintf(buf, size, "VXLAN: flags=%u vni=%u", + vxlan_hdr_get_flags(hdr), vxlan_hdr_get_vni(hdr)); +} + +#ifdef __cplusplus +} +#endif + +#endif