diff options
| author | Qiuwen Lu <[email protected]> | 2017-07-19 14:19:35 +0800 |
|---|---|---|
| committer | Qiuwen Lu <[email protected]> | 2017-07-19 14:19:35 +0800 |
| commit | 208f4023e98d24daf33723807f2eeb3968e6817c (patch) | |
| tree | c6544e697edb43efcd8e21f80dc299f99f5c5589 /tunnat | |
| parent | 0639f75a2bcd4bd39834e0d2e5706827f52c07c5 (diff) | |
增加TUNNAT网关主动发包功能,目前仅支持内层是以太网、外层是VXLAN的隧道主动发包。
Diffstat (limited to 'tunnat')
| -rw-r--r-- | tunnat/include/tunnat.h | 2 | ||||
| -rw-r--r-- | tunnat/include/tunnel.h | 8 | ||||
| -rw-r--r-- | tunnat/src/runtime.cc | 53 | ||||
| -rw-r--r-- | tunnat/src/tunnel.cc | 58 |
4 files changed, 120 insertions, 1 deletions
diff --git a/tunnat/include/tunnat.h b/tunnat/include/tunnat.h index 172785f..e999219 100644 --- a/tunnat/include/tunnat.h +++ b/tunnat/include/tunnat.h @@ -90,6 +90,7 @@ public: TUNNAT_STAT_DROP_OUTPUT, TUNNAT_STAT_FORWARD_RAW_OUTPUT, TUNNAT_STAT_FORWARD_TUNNEL_OUTPUT, + TUNNAT_STAT_NO_SESSION_OUTPUT, /* 统计,会话表表项计数 */ TUNNAT_STAT_SESSION_ADD, TUNNAT_STAT_SESSION_REMOVE, @@ -161,6 +162,7 @@ public: [TUNNAT_STAT_DROP_OUTPUT] ="TUNNAT_STAT_DROP_OUTPUT", [TUNNAT_STAT_FORWARD_RAW_OUTPUT] = "TUNNAT_STAT_FORWARD_RAW_OUTPUT", [TUNNAT_STAT_FORWARD_TUNNEL_OUTPUT] = "TUNNAT_STAT_FORWARD_TUNNEL_OUTPUT", + [TUNNAT_STAT_NO_SESSION_OUTPUT] = "TUNNAT_STAT_NO_SESSION_OUTPUT", [TUNNAT_STAT_SESSION_ADD] = "TUNNAT_STAT_SESSION_ADD", [TUNNAT_STAT_SESSION_REMOVE] = "TUNNAT_STAT_SESSION_REMOVE", [TUNNAT_STAT_ENCAP_FAIL_NO_SESSION] = "TUNNAT_STAT_ENCAP_FAIL_NO_SESSION", diff --git a/tunnat/include/tunnel.h b/tunnat/include/tunnel.h index 10449e5..5f95a85 100644 --- a/tunnat/include/tunnel.h +++ b/tunnat/include/tunnel.h @@ -11,6 +11,7 @@ extern "C" #include <assert.h> #include <common.h> #include <marsio.h> +#include <mrtunnat.h> } struct AddressInfo @@ -61,6 +62,11 @@ public: return this_layer_length; } + virtual int CtrlZoneParse(struct mr_tunnat_ctrlzone * ctrlzone) + { + return RT_ERR; + } + virtual int PacketParse(const char * pkt, unsigned int pkt_len) { return RT_ERR; @@ -103,7 +109,9 @@ protected: public: int PacketParse(const char * pkt, unsigned int pkt_len); + int CtrlZoneParse(struct mr_tunnat_ctrlzone * ctrlzone); int PacketConstruct(const char * pkt, unsigned int pkt_len); + int GetAddressInfo(struct AddressInfo & addr_info) { return 0; diff --git a/tunnat/src/runtime.cc b/tunnat/src/runtime.cc index 7baf945..610c99a 100644 --- a/tunnat/src/runtime.cc +++ b/tunnat/src/runtime.cc @@ -275,6 +275,45 @@ static int __virt_to_phy_pkt_encap(TunnatInstance * instance, TunnatThreadInstan return RT_SUCCESS; } +static int __virt_to_phy_pkt_no_session(TunnatInstance * instance, TunnatThreadInstance * th_instance, + marsio_buff_t * mbuf) +{ + mr_tunnat_ctrlzone * ctrlzone = static_cast<mr_tunnat_ctrlzone *>( + marsio_buff_ctrlzone(mbuf, g_ctrlzone_id)); + + assert(ctrlzone != NULL); + + /* 直接构建报文,不查会话表 */ + if (!(ctrlzone->action & TUNNAT_CZ_ACTION_ENCAP_NO_SESSION)) + return RT_ERR; + + /* 对于内层是以太报文的 */ + if (ctrlzone->g_device_inner_encap_type == TUNNEL_TYPE_ETHER) + { + Tunnel OuterVXLAN; + int ret = OuterVXLAN.CtrlZoneParse(ctrlzone); + if (ret < 0) return RT_ERR; + + char * pkt_ptr = marsio_buff_prepend(mbuf, OuterVXLAN.ThisTunLength()); + unsigned int pkt_len = marsio_buff_datalen(mbuf); + + assert(pkt_ptr != NULL); + OuterVXLAN.PacketConstruct(pkt_ptr, pkt_len); + + return RT_SUCCESS; + } + else if (ctrlzone->g_device_inner_encap_type == TUNNEL_TYPE_PPP) + { + assert(0); + } + else if (ctrlzone->g_device_inner_encap_type == TUNNEL_TYPE_HDLC) + { + assert(0); + } + + return RT_ERR; +} + static void __virt_to_phy_one_device(TunnatInstance * instance, TunnatThreadInstance * th_instance, TunnatInstance::_devs * phy_device_hand, TunnatInstance::_devs * virt_device_hand) { @@ -292,6 +331,9 @@ static void __virt_to_phy_one_device(TunnatInstance * instance, TunnatThreadInst marsio_buff_t * encap_bufs[MR_BURST_MAX]; unsigned int nr_encap_bufs = 0; + marsio_buff_t * no_session_bufs[MR_BURST_MAX]; + unsigned int nr_no_session_bufs = 0; + marsio_buff_t * drop_bufs[MR_BURST_MAX]; unsigned int nr_drop_bufs = 0; @@ -309,16 +351,25 @@ static void __virt_to_phy_one_device(TunnatInstance * instance, TunnatThreadInst continue; } + if (__virt_to_phy_pkt_no_session(instance, th_instance, mbufs[i]) == RT_SUCCESS) + { + no_session_bufs[nr_no_session_bufs++] = mbufs[i]; + continue; + } + drop_bufs[nr_drop_bufs++] = mbufs[i]; } marsio_send_burst(phy_device_hand->vdev_sendpath, tid, fwd_mbufs, nr_fwd_mbufs); - marsio_send_burst(phy_device_hand->vdev_sendpath, tid, encap_bufs, nr_encap_bufs); + marsio_send_burst(phy_device_hand->vdev_sendpath, tid, encap_bufs, nr_encap_bufs); + marsio_send_burst(phy_device_hand->vdev_sendpath, tid, no_session_bufs, nr_no_session_bufs); marsio_buff_free(instance->mr_instance, drop_bufs, nr_drop_bufs, MARSIO_SOCKET_ID_ANY, tid); TUNNAT_THREAD_STAT_ADD(TUNNAT_STAT_FORWARD_OUTPUT, nr_fwd_mbufs); TUNNAT_THREAD_STAT_ADD(TUNNAT_STAT_ENCAP_OUTPUT, nr_encap_bufs); TUNNAT_THREAD_STAT_ADD(TUNNAT_STAT_DROP_OUTPUT, nr_drop_bufs); + TUNNAT_THREAD_STAT_ADD(TUNNAT_STAT_NO_SESSION_OUTPUT, nr_no_session_bufs); + return; } diff --git a/tunnat/src/tunnel.cc b/tunnat/src/tunnel.cc index 1172b4f..da3d22f 100644 --- a/tunnat/src/tunnel.cc +++ b/tunnat/src/tunnel.cc @@ -75,6 +75,64 @@ int TunVxlan::PacketParse(const char * pkt, unsigned int pkt_len) return RT_SUCCESS; } +#define __IP_VERSION_IHL(version, len) (version << 4 | len << 0) +#define __IP_TTL 64
+
+int TunVxlan::CtrlZoneParse(struct mr_tunnat_ctrlzone * ctrlzone)
+{ + /* 以太头填充,暂时不考虑VLAN的情况 */ + ether_addr_copy((const struct ether_addr *)&ctrlzone->g_device_mac, + ðer_hdr_.d_addr); + ether_addr_copy((const struct ether_addr *)&ctrlzone->l_device_mac, + ðer_hdr_.s_addr); + ether_hdr_.ether_type = htons(ETHER_TYPE_IPv4); + + /* IP头部填充 */ + ipv4_hdr_.version_ihl = __IP_VERSION_IHL(4, sizeof(struct ipv4_hdr) / 4); + ipv4_hdr_.type_of_service = 0; + ipv4_hdr_.total_length = 0; + ipv4_hdr_.packet_id = 0; + ipv4_hdr_.fragment_offset = 0; + ipv4_hdr_.time_to_live = __IP_TTL; + ipv4_hdr_.dst_addr = ctrlzone->g_device_in_addr; + ipv4_hdr_.src_addr = ctrlzone->l_device_in_addr; + ipv4_hdr_.next_proto_id = IPPROTO_UDP; + + /* UDP头部填充 */ + udp_hdr_.dst_port = htons(G_VXLAN_DPORT); + udp_hdr_.src_port = ctrlzone->l_device_l4_port; + udp_hdr_.dgram_cksum = 0; + + /* VXLAN头部 */ + vxlan_hdr_.dir = ctrlzone->route_dir; + vxlan_hdr_.link_id = ctrlzone->g_device_linkpair; + vxlan_hdr_.vlan_id_half_low = ctrlzone->g_device_vpn_id; + + /* 内层封装形式 */ + switch (ctrlzone->g_device_inner_encap_type) + { + case TUNNEL_TYPE_ETHER: + vxlan_hdr_.link_layer_type = G_VXLAN_INNER_LINK_TYPE_ETH; + break; + case TUNNEL_TYPE_HDLC: + vxlan_hdr_.link_layer_type = G_VXLAN_INNER_LINK_TYPE_HDLC; + break; + case TUNNEL_TYPE_PPP: + vxlan_hdr_.link_layer_type = G_VXLAN_INNER_LINK_TYPE_PPP; + break; + default: + assert(0); + return RT_ERR; + } + + 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 g_vxlan_hdr); +
+ return 0;
+} + int TunVxlan::PacketConstruct(const char * pkt, unsigned int pkt_len) { unsigned int offset = 0; |
