summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLu Qiuwen <[email protected]>2018-11-09 19:55:26 +0800
committerLu Qiuwen <[email protected]>2018-11-09 19:55:26 +0800
commita57aea97a0c039b22891a6b6f266f239d5f3563a (patch)
treec8d71e2f0347e5fb2740f96e74d70ddee097a613
parentfb6561733bb5be0e12d3ee8201b5f7711d0198bd (diff)
增加MPLS标签Offload功能v4.2.40-20181109
* vxlan内部有mpls标签时,剥去该标签,为上层应用提供纯以太报文。
-rw-r--r--tunnat/CMakeLists.txt7
-rw-r--r--tunnat/include/tunnel.h45
-rw-r--r--tunnat/src/tunnel.cc99
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(&eth_hdr->s_addr, &__swap_ether_addr);
ether_addr_copy(&eth_hdr->d_addr, &eth_hdr->s_addr);
ether_addr_copy(&__swap_ether_addr, &eth_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: