summaryrefslogtreecommitdiff
path: root/tunnat
diff options
context:
space:
mode:
authorQiuwen Lu <[email protected]>2017-07-19 14:19:35 +0800
committerQiuwen Lu <[email protected]>2017-07-19 14:19:35 +0800
commit208f4023e98d24daf33723807f2eeb3968e6817c (patch)
treec6544e697edb43efcd8e21f80dc299f99f5c5589 /tunnat
parent0639f75a2bcd4bd39834e0d2e5706827f52c07c5 (diff)
增加TUNNAT网关主动发包功能,目前仅支持内层是以太网、外层是VXLAN的隧道主动发包。
Diffstat (limited to 'tunnat')
-rw-r--r--tunnat/include/tunnat.h2
-rw-r--r--tunnat/include/tunnel.h8
-rw-r--r--tunnat/src/runtime.cc53
-rw-r--r--tunnat/src/tunnel.cc58
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,
+ &ether_hdr_.d_addr);
+ ether_addr_copy((const struct ether_addr *)&ctrlzone->l_device_mac,
+ &ether_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;