diff options
| author | Lu Qiuwen <[email protected]> | 2018-11-09 19:55:26 +0800 |
|---|---|---|
| committer | Lu Qiuwen <[email protected]> | 2018-11-09 19:55:26 +0800 |
| commit | a57aea97a0c039b22891a6b6f266f239d5f3563a (patch) | |
| tree | c8d71e2f0347e5fb2740f96e74d70ddee097a613 | |
| parent | fb6561733bb5be0e12d3ee8201b5f7711d0198bd (diff) | |
增加MPLS标签Offload功能v4.2.40-20181109
* vxlan内部有mpls标签时,剥去该标签,为上层应用提供纯以太报文。
| -rw-r--r-- | tunnat/CMakeLists.txt | 7 | ||||
| -rw-r--r-- | tunnat/include/tunnel.h | 45 | ||||
| -rw-r--r-- | tunnat/src/tunnel.cc | 99 |
3 files changed, 74 insertions, 77 deletions
diff --git a/tunnat/CMakeLists.txt b/tunnat/CMakeLists.txt index efcb064..eb7e656 100644 --- a/tunnat/CMakeLists.txt +++ b/tunnat/CMakeLists.txt @@ -9,7 +9,7 @@ add_definitions(${DPDK_C_PREDEFINED}) add_executable(mrtunnat src/core.cc src/runtime.cc src/tunnel.cc src/session.cc src/monit.cc) target_link_libraries(mrtunnat MESA_prof_load_static MESA_htable marsio infra) -target_link_libraries(mrtunnat rt pthread dl ${SYSTEMD_LIBRARIES}) +target_link_libraries(mrtunnat rt pthread dl ${SYSTEMD_LIBRARIES} ${DPDK_LIBRARY}) target_include_directories(mrtunnat PRIVATE ${SYSTEMD_INCLUDE_DIRS}) target_include_directories(mrtunnat PRIVATE include) @@ -18,5 +18,6 @@ install(TARGETS mrtunnat RUNTIME DESTINATION bin COMPONENT Program) # test add_executable(TestSession test/TestSession.cc src/session.cc src/tunnel.cc) -target_link_libraries(TestSession gtest infra ${SYSTEMD_LIBRARIES} MESA_htable MESA_prof_load_static) -target_include_directories(TestSession PRIVATE include)
\ No newline at end of file +target_link_libraries(TestSession gtest infra ${SYSTEMD_LIBRARIES} ${DPDK_LIBRARY}) +target_link_libraries(TestSession MESA_htable MESA_prof_load_static) +target_include_directories(TestSession PRIVATE include) diff --git a/tunnat/include/tunnel.h b/tunnat/include/tunnel.h index 0aef4d4..30b6c6d 100644 --- a/tunnat/include/tunnel.h +++ b/tunnat/include/tunnel.h @@ -58,7 +58,7 @@ enum tunnel_type TUNNEL_TYPE_PPP, TUNNEL_TYPE_HDLC, TUNNEL_TYPE_IPV4, - TUNNEL_TYPE_IPV6 + TUNNEL_TYPE_IPV6, }; class Tunnel @@ -143,9 +143,7 @@ public: memcpy(&(addr_info.addr.ipv4_addr), &ipv4_addr_, sizeof(struct ipv4_addr_t)); addr_info.s_port = udp_hdr_.src_port; addr_info.d_port = udp_hdr_.dst_port; - addr_info.vpn_id = (vxlan_hdr_.vlan_id_half_low & 0xf) | - (vxlan_hdr_.vlan_id_half_high & 0xff) << 4; - + addr_info.vpn_id = (vxlan_hdr_.vlan_id_half_low & 0xf) | (vxlan_hdr_.vlan_id_half_high & 0xff) << 4; return 0; } @@ -160,25 +158,22 @@ public: class TunQMac : public Tunnel {}; + +#include <memory> class TunInnerEther : public Tunnel { protected: + constexpr static int SZ_ETHER_TUNNEL_STORAGE = 64; struct ether_hdr ether_hdr_; - struct vlan_hdr vlan_hdr_; + char ether_tunnel_on_stack_[SZ_ETHER_TUNNEL_STORAGE]; + char * ether_tunnel_; + size_t ether_tunnel_len_; public: - int PacketParse(const char * pkt, unsigned int pkt_len); - int PacketConstruct(const char * pkt, unsigned int pkt_len); - - void ReverseAddress() - { - std::swap<ether_addr>(ether_hdr_.s_addr, ether_hdr_.d_addr); - } - - static int PacketForwardModify(const char * pkt, unsigned int pkt_len) - { - return 0; - } + int PacketParse(const char * pkt, unsigned int pkt_len) override; + int PacketConstruct(const char * pkt, unsigned int pkt_len) override; + void ReverseAddress() override { std::swap<ether_addr>(ether_hdr_.s_addr, ether_hdr_.d_addr); } + static int PacketForwardModify(const char * pkt, unsigned int pkt_len) { return 0; } }; class TunInnerIPv4 : public Tunnel @@ -187,7 +182,6 @@ protected: struct ipv4_addr_t ipv4_addr; public: int PacketParse(const char * pkt, unsigned int pkt_len); - int GetAddressInfo(struct AddressInfo & addr_info) { addr_info.type = IPV4_ADDR; @@ -223,22 +217,15 @@ public: class TunInnerPPP : public Tunnel { public: - int PacketParse(const char * pkt, unsigned int pkt_len); - int PacketConstruct(const char * pkt, unsigned int pkt_len) + int PacketParse(const char * pkt, unsigned int pkt_len) override; + int PacketConstruct(const char * pkt, unsigned int pkt_len) override { *(uint32_t *)pkt = ppp_header_; return 0; } - static int PacketForwardModify(const char * pkt, unsigned int pkt_len) - { - return 0; - } - - void ReverseAddress() - { - return; - } + static int PacketForwardModify(const char * pkt, unsigned int pkt_len) { return 0; } + void ReverseAddress(){} protected: uint32_t ppp_header_; diff --git a/tunnat/src/tunnel.cc b/tunnat/src/tunnel.cc index f7038c9..ed9b2c6 100644 --- a/tunnat/src/tunnel.cc +++ b/tunnat/src/tunnel.cc @@ -64,7 +64,7 @@ int TunVxlan::PacketParse(const char * pkt, unsigned int pkt_len) ipv4_hdr_ = *ipv4_hdr; vxlan_hdr_ = *vxlan_hdr; udp_hdr_ = *udp_hdr; - + ipv4_addr_.src_in_addr.s_addr = ipv4_hdr->src_addr; ipv4_addr_.dst_in_addr.s_addr = ipv4_hdr->dst_addr; @@ -112,7 +112,7 @@ int TunVxlan::CtrlZoneParse(struct mr_tunnat_ctrlzone * ctrlzone) vxlan_hdr_.link_id = ctrlzone->g_device_linkpair; vxlan_hdr_.vlan_id_half_high = ((ctrlzone->g_device_vpn_id & 0x0ff0) >> 4) & 0xff; vxlan_hdr_.vlan_id_half_low = ctrlzone->g_device_vpn_id & 0xf; - + /* 内层封装形式 */ switch (ctrlzone->g_device_inner_encap_type) { @@ -132,7 +132,7 @@ int TunVxlan::CtrlZoneParse(struct mr_tunnat_ctrlzone * ctrlzone) this->this_layer_type = TUNNEL_TYPE_G_VXLAN; this->this_layer_length = sizeof(struct ether_hdr) + - sizeof(struct ipv4_hdr) + sizeof(struct udp_hdr) + + sizeof(struct ipv4_hdr) + sizeof(struct udp_hdr) + sizeof(struct g_vxlan_hdr); return 0; @@ -205,48 +205,69 @@ int TunVxlan::PacketForwardModify(const char * pkt, unsigned int pkt_len) ether_addr_copy(ð_hdr->s_addr, &__swap_ether_addr); ether_addr_copy(ð_hdr->d_addr, ð_hdr->s_addr); ether_addr_copy(&__swap_ether_addr, ð_hdr->d_addr); - + // 交换外层IP地址 struct ipv4_hdr * ipv4_hdr = (struct ipv4_hdr *)pkt; struct in_addr __swap_in_addr; __swap_in_addr.s_addr = ipv4_hdr->src_addr; ipv4_hdr->src_addr = ipv4_hdr->dst_addr; ipv4_hdr->dst_addr = __swap_in_addr.s_addr; - + return 0; } -int TunInnerEther::PacketParse(const char * pkt, unsigned int len) +extern "C" { - unsigned int offset = 0; +#include <ldbc.h> +} +int TunInnerEther::PacketParse(const char * pkt, unsigned int len) +{ struct ether_hdr * eth_hdr = (struct ether_hdr *)pkt; - uint16_t proto = eth_hdr->ether_type; - - /* 保存以太网层信息 */ ether_hdr_ = *eth_hdr; - - pkt += sizeof(struct ether_hdr); - offset += sizeof(struct ether_hdr); - /* 处理VLAN、IPv4,其他协议不处理 */ - if (proto == ntohs(ETHER_TYPE_IPv4)) goto l3; - else if (eth_hdr->ether_type == ntohs(ETHER_TYPE_VLAN)) + struct pkt_parser __pkt_parser; + pkt_parser_init(&__pkt_parser, LAYER_TYPE_L3, 1); + + const char * ptr_l3 = (const char *)complex_parser_ether(&__pkt_parser, pkt); + const char * ptr_ether_tunnel = pkt + sizeof(struct ether_hdr); + + /* 只解析到外层IPv4或IPv6,没有找到则报错 */ + if (ptr_l3 == nullptr) { - struct vlan_hdr * vlan_hdr = (struct vlan_hdr *)pkt; - vlan_hdr_ = *vlan_hdr; - proto = vlan_hdr->eth_proto; + return RT_ERR; + } - pkt += sizeof(struct vlan_hdr); - offset += sizeof(struct vlan_hdr); + /* 外层不是IPv4或者IPv6,报错 */ + if (__pkt_parser.results[0].this_layer_type != LAYER_TYPE_IPV4 && + __pkt_parser.results[0].this_layer_type != LAYER_TYPE_IPV6) + { + return RT_ERR; + } + + assert(ptr_l3 >= ptr_ether_tunnel); + ether_tunnel_len_ = ptr_l3 - ptr_ether_tunnel; + + /* TODO: 超过栈上存储空间大小,在堆上分配内存 */ + assert(ether_tunnel_len_ <= SZ_ETHER_TUNNEL_STORAGE); + ether_tunnel_ = ether_tunnel_on_stack_; + + /* 复制Ether-Tunnel(包括VLAN, MPLS等等) */ + if (ether_tunnel_len_ > 0) + { + memcpy(ether_tunnel_, ptr_ether_tunnel, ether_tunnel_len_); + } + + /* 三层 */ + switch (__pkt_parser.results[0].this_layer_type) + { + case LAYER_TYPE_IPV4: { next_layer_type = TUNNEL_TYPE_IPV4; break; } + case LAYER_TYPE_IPV6: { next_layer_type = TUNNEL_TYPE_IPV6; break; } + default: assert(0); } - -l3: - if (proto == ntohs(ETHER_TYPE_IPv4)) next_layer_type = TUNNEL_TYPE_IPV4; - else if (proto == ntohs(ETHER_TYPE_IPv6)) next_layer_type = TUNNEL_TYPE_IPV6; this_layer_type = TUNNEL_TYPE_ETHER; - this_layer_length = offset; + this_layer_length = sizeof(struct ether_hdr) + ether_tunnel_len_; TUNNAT_THREAD_STAT_ADD(TUNNAT_STAT_INNER_ETHER_INPUT, 1); return RT_SUCCESS; @@ -257,24 +278,12 @@ int TunInnerEther::PacketConstruct(const char * pkt, unsigned int pkt_len) struct ether_hdr * eth_hdr = (struct ether_hdr *)pkt; *eth_hdr = ether_hdr_; - unsigned int offset = 0; pkt += sizeof(struct ether_hdr); - offset += sizeof(struct ether_hdr); + pkt_len -= sizeof(struct ether_hdr); - uint16_t proto = eth_hdr->ether_type; - - /* 处理VLAN、IPv4,其他协议不处理 */ - if (proto == ntohs(ETHER_TYPE_IPv4)) - return RT_SUCCESS; - - else if (eth_hdr->ether_type == ntohs(ETHER_TYPE_VLAN)) - { - struct vlan_hdr * vlan_hdr = (struct vlan_hdr *)pkt; - *vlan_hdr = vlan_hdr_; - return RT_SUCCESS; - } - - return RT_ERR; + assert(pkt_len >= ether_tunnel_len_); + if(ether_tunnel_len_ > 0) memcpy((char *)pkt, ether_tunnel_, ether_tunnel_len_); + return RT_SUCCESS; } int TunInnerPPP::PacketParse(const char * pkt, unsigned int pkt_len) @@ -298,7 +307,7 @@ int TunInnerPPP::PacketParse(const char * pkt, unsigned int pkt_len) return 0; } -int TunnelContainer::PacketParse(const char * pkt, unsigned int pkt_len, +int TunnelContainer::PacketParse(const char * pkt, unsigned int pkt_len, tunnel_type tunnel_type) { int ret = 0; @@ -352,14 +361,14 @@ guess: this_layer_type = TUNNEL_TYPE_G_VXLAN; goto out; } - + ret = tun_qmac_object_.PacketParse(pkt, pkt_len); if (ret >= 0) { this_layer_type = TUNNEL_TYPE_G_MAC_IN_MAC; goto out; } - + goto out; out: |
