summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQiuwen Lu <[email protected]>2019-04-09 16:15:25 +0800
committerQiuwen Lu <[email protected]>2019-06-15 11:25:42 +0800
commit248c9861ab765239834e1512384d9eabb48aa39e (patch)
tree8b0575682e3e8ec8455291822eb74532567d7598
parent4e79871b6477d4c62db8c20e4ccaed729b040469 (diff)
增加对VLAN二层回流的支持
-rw-r--r--tunnat/include/tunnat.h16
-rw-r--r--tunnat/include/tunnel.h28
-rw-r--r--tunnat/src/core.cc56
-rw-r--r--tunnat/src/runtime.cc139
-rw-r--r--tunnat/src/tunnel.cc104
-rw-r--r--tunnat/test/TestSession.cc5
6 files changed, 267 insertions, 81 deletions
diff --git a/tunnat/include/tunnat.h b/tunnat/include/tunnat.h
index 99bda31..6d43514 100644
--- a/tunnat/include/tunnat.h
+++ b/tunnat/include/tunnat.h
@@ -4,6 +4,7 @@
#include <vector>
#include <cassert>
#include <tunnel.h>
+#include <map>
extern "C"
{
@@ -54,6 +55,13 @@ struct TunnatThreadInstance;
#define MR_TUNNAT_DEFAULT_SESSION_EXPIRE_TIME 0
#endif
+enum bridge_mode
+{
+ MR_TUNNAT_BRIDGE_MODE_DISABLE,
+ MR_TUNNAT_BRIDGE_MODE_ONE_ARM,
+ MR_TUNNAT_BRIDGE_MODE_TWO_ARM,
+};
+
/* 全局句柄 */
struct TunnatInstance
{
@@ -98,6 +106,11 @@ struct TunnatInstance
/* 虚拟设备列表(应用侧)*/
std::vector<struct _devs> virtdevs;
+ /* 桥接模式 */
+ enum bridge_mode bridge_mode;
+ /* 单臂桥接VLAN映射表 */
+ std::map<uint16_t, uint16_t> one_arm_bridge_vlan_map;
+
/* 线程运行句柄 */
TunnatThreadInstance * thread_instances[MR_SID_MAX];
@@ -110,6 +123,9 @@ struct TunnatInstance
TunnatInstance() = default;
~TunnatInstance() = default;
+
+public:
+ static struct TunnatInstance * TunnatInstanceGet();
};
class SessionTable;
diff --git a/tunnat/include/tunnel.h b/tunnat/include/tunnel.h
index b804fd9..9f1ee01 100644
--- a/tunnat/include/tunnel.h
+++ b/tunnat/include/tunnel.h
@@ -59,6 +59,7 @@ enum tunnel_type
TUNNEL_TYPE_UNKNOWN,
TUNNEL_TYPE_G_VXLAN,
TUNNEL_TYPE_G_MAC_IN_MAC,
+ TUNNEL_TYPE_VLAN_BRIDGE,
TUNNEL_TYPE_ETHER,
TUNNEL_TYPE_PPP,
TUNNEL_TYPE_HDLC,
@@ -78,17 +79,17 @@ protected:
public:
- enum tunnel_type NextTunType()
+ virtual enum tunnel_type NextTunType()
{
return next_layer_type;
}
- enum tunnel_type ThisTunType()
+ virtual enum tunnel_type ThisTunType()
{
return this_layer_type;
}
- unsigned int ThisTunLength()
+ virtual unsigned int ThisTunLength()
{
return this_layer_length;
}
@@ -167,6 +168,24 @@ public:
class TunQMac : public Tunnel
{};
+class TunVlanBridge : public Tunnel
+{
+public:
+ tunnel_type NextTunType() override { return TUNNEL_TYPE_ETHER; }
+ tunnel_type ThisTunType() override { return TUNNEL_TYPE_VLAN_BRIDGE; }
+ unsigned int ThisTunLength() override { return 0; }
+
+ int PacketParse(const char * pkt, unsigned int pkt_len) override;
+ int PacketConstruct(const char * pkt, unsigned int pkt_len) override;
+ size_t ToHashKey(char * out_hashkey, size_t sz_hash_key) const override { return 0; }
+ cJSON * ToJSON() const override { return nullptr; }
+
+public:
+ static int PacketForwardModify(const char * pkt, unsigned int pkt_len);
+
+private:
+ unsigned int vlan_id_;
+};
class TunInnerEther : public Tunnel
{
@@ -287,6 +306,7 @@ public:
protected:
TunVxlan tun_vxlan_object_;
TunQMac tun_qmac_object_;
+ TunVlanBridge tun_vlan_bridge_object_;
TunInnerEther tun_inner_ether_;
TunInnerHDLC tun_inner_hdlc_;
TunInnerPPP tun_inner_ppp_;
@@ -301,6 +321,7 @@ public:
TunnelContainer(const TunnelContainer & orin) :
tun_vxlan_object_(orin.tun_vxlan_object_),
tun_qmac_object_(orin.tun_qmac_object_),
+ tun_vlan_bridge_object_(orin.tun_vlan_bridge_object_),
tun_inner_ether_(orin.tun_inner_ether_),
tun_inner_hdlc_(orin.tun_inner_hdlc_),
tun_inner_ppp_(orin.tun_inner_ppp_),
@@ -314,6 +335,7 @@ public:
{
this->tun_vxlan_object_ = orin.tun_vxlan_object_;
this->tun_qmac_object_ = orin.tun_qmac_object_;
+ this->tun_vlan_bridge_object_ = orin.tun_vlan_bridge_object_;
this->tun_inner_ether_ = orin.tun_inner_ether_;
this->tun_inner_hdlc_ = orin.tun_inner_hdlc_;
this->tun_inner_ppp_ = orin.tun_inner_ppp_;
diff --git a/tunnat/src/core.cc b/tunnat/src/core.cc
index d980602..9de6b91 100644
--- a/tunnat/src/core.cc
+++ b/tunnat/src/core.cc
@@ -24,6 +24,11 @@ uint8_t g_ctrlzone_id = 0;
__thread TunnatThreadStat * TunnatThreadStat::thread_stat_object_;
struct TunnatInstance * g_instance = NULL;
+struct TunnatInstance * TunnatInstance::TunnatInstanceGet()
+{
+ return g_instance;
+}
+
/* 字符串拆分,根据字符拆分字符串 */
std::vector<std::string> __strsplit(const std::string & s, char seperator)
{
@@ -118,6 +123,55 @@ int tunnat_devices_setup(TunnatInstance * instance)
return RT_SUCCESS;
}
+#define C_I_VLAN_PAIR_MAX 64
+
+int tunnat_bridge_setup(TunnatInstance * instance)
+{
+ const char * cfgfile = instance->cfgfile.c_str();
+ unsigned int __bridge_mode = MR_TUNNAT_BRIDGE_MODE_DISABLE;
+
+ MESA_load_profile_uint_def(cfgfile, "bridge", "mode", &__bridge_mode, __bridge_mode);
+ instance->bridge_mode = static_cast<enum bridge_mode>(__bridge_mode);
+
+ for(unsigned int i = 0; i < C_I_VLAN_PAIR_MAX; i++)
+ {
+ char __c_router_cfg_name[MR_SYMBOL_MAX] = {};
+ char __i_router_cfg_name[MR_SYMBOL_MAX] = {};
+ unsigned int __c_router_cfg_value{};
+ unsigned int __i_router_cfg_value{};
+
+ snprintf(__c_router_cfg_name, sizeof(__c_router_cfg_name), "c_router_vlan_id_%u", i);
+ snprintf(__i_router_cfg_name, sizeof(__i_router_cfg_name), "i_router_vlan_id_%u", i);
+
+ if (MESA_load_profile_uint_nodef(cfgfile, "bridge", __c_router_cfg_name, &__c_router_cfg_value) < 0)
+ {
+ break;
+ }
+
+ if (MESA_load_profile_uint_nodef(cfgfile, "bridge", __i_router_cfg_name, &__i_router_cfg_value) < 0)
+ {
+ break;
+ }
+
+ auto __u16_c_router_vlan_id = static_cast<uint16_t>(__c_router_cfg_value);
+ auto __u16_i_router_vlan_id = static_cast<uint16_t>(__i_router_cfg_value);
+
+ auto vlan_map_item = instance->one_arm_bridge_vlan_map.find(__u16_c_router_vlan_id);
+ if (vlan_map_item != instance->one_arm_bridge_vlan_map.end())
+ {
+ MR_WARNING("Duplicated vlan-id-map found, id = %u, ignore it.", i);
+ continue;
+ }
+
+ instance->one_arm_bridge_vlan_map[__u16_c_router_vlan_id] = __u16_i_router_vlan_id;
+
+ MR_INFO("One-arm bridge vlan-id map %u: c-subnet-vlan-id %u, i-subnet-vlan-id %u",
+ i, __u16_c_router_vlan_id, __u16_i_router_vlan_id);
+ }
+
+ return RT_SUCCESS;
+}
+
int tunnat_session_setup(TunnatInstance * instance)
{
/* 最大会话数 */
@@ -338,6 +392,8 @@ int main(int argc, char * argv[])
goto err_out;
if (tunnat_session_setup(g_instance) != RT_SUCCESS)
goto err_out;
+ if (tunnat_bridge_setup(g_instance) != RT_SUCCESS)
+ goto err_out;
for (unsigned int i = 0; i < g_instance->nr_thread; i++)
{
diff --git a/tunnat/src/runtime.cc b/tunnat/src/runtime.cc
index 6a26014..0fead79 100644
--- a/tunnat/src/runtime.cc
+++ b/tunnat/src/runtime.cc
@@ -73,12 +73,6 @@ static int __phy_to_virt_pkt_decap(TunnatInstance * instance, TunnatThreadInstan
if (tun_array.sz_array == 0)
return RT_ERR;
- tunnel_type inner_tun_type = tun_array.GetInnerTunContainer().ThisTunType();
-
- /* 内层不是IPv4和IPv6的,无法处理,转到应用解析 */
- if (inner_tun_type != TUNNEL_TYPE_IPV4 && inner_tun_type != TUNNEL_TYPE_IPV6)
- return RT_ERR;
-
return RT_SUCCESS;
}
@@ -104,8 +98,19 @@ static int __phy_to_virt_session_check(TunnatInstance * instance, TunnatThreadIn
struct SessionKey session_key;
struct AddressInfo addr_info;
- int ret = tun_array.GetInnerTunContainer().GetAddressInfo(addr_info);
- if (ret < 0) return RT_ERR;
+ auto inner_tun_container = tun_array.GetInnerTunContainer();
+ if (inner_tun_container.ThisTunType() != TUNNEL_TYPE_IPV4 &&
+ inner_tun_container.ThisTunType() != TUNNEL_TYPE_IPV6)
+ {
+ return RT_ERR;
+ }
+
+ int ret = inner_tun_container.GetAddressInfo(addr_info);
+ if (ret < 0)
+ {
+ return RT_ERR;
+ }
+
switch(addr_info.type)
{
case IPV4_ADDR:
@@ -125,7 +130,7 @@ static int __phy_to_virt_session_check(TunnatInstance * instance, TunnatThreadIn
/* 查询当前会话表 */
SessionEntry * ss_entry = th_instance->ss_table->Query(session_key);
- if (ss_entry != NULL) return RT_SUCCESS;
+ if (ss_entry != nullptr) return RT_SUCCESS;
SessionEntry _temp_entry;
_temp_entry.tun_array = tun_array;
@@ -137,11 +142,11 @@ static int __phy_to_virt_session_check(TunnatInstance * instance, TunnatThreadIn
static int __phy_to_virt_clear_cz(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));
+ auto * ctrlzone = static_cast<mr_tunnat_ctrlzone *>(marsio_buff_ctrlzone(mbuf, g_ctrlzone_id));
ctrlzone->__encap_type = 0;
ctrlzone->__encap_len = 0;
- ctrlzone->action = TUNNAT_CZ_ACTION_FORWARD;
+ ctrlzone->action = 0;
return RT_SUCCESS;
}
@@ -182,10 +187,8 @@ static void __phy_to_virt_check_bfd_and_rehash(TunnatInstance * instance,
static int __phy_to_virt_pkt_modify(TunnatInstance * instance, TunnatThreadInstance * th_instance,
marsio_buff_t * mbuf, TunnelContainerArray & tun_array)
{
- mr_tunnat_ctrlzone * ctrlzone = static_cast<mr_tunnat_ctrlzone *>(
- marsio_buff_ctrlzone(mbuf, g_ctrlzone_id));
-
- assert(ctrlzone != NULL);
+ auto * ctrlzone = static_cast<mr_tunnat_ctrlzone *>(marsio_buff_ctrlzone(mbuf, g_ctrlzone_id));
+ assert(ctrlzone != nullptr);
/* 控制域内填写封装报文类型 */
TunnelContainer & outer_tunnel = tun_array.GetOuterTunContainer();
@@ -203,25 +206,36 @@ static int __phy_to_virt_pkt_modify(TunnatInstance * instance, TunnatThreadInsta
ctrlzone->g_device_linkpair = outer_tunnel_addrinfo.link_id;
}
+ /* 对于内层隧道不是IPv4或IPv6的,不剥离外层隧道,直接送入应用 */
+ if (inner_tunnel.ThisTunType() != TUNNEL_TYPE_IPV4 &&
+ inner_tunnel.ThisTunType() != TUNNEL_TYPE_IPV6)
+ {
+ ctrlzone->__encap_len = 0;
+ }
+ else
+ {
+ ctrlzone->__encap_len = (uint16_t)(tun_array.sz_total_len - inner_tunnel.ThisTunLength());
+ }
+
ctrlzone->__encap_type = outer_tunnel.ThisTunType();
- ctrlzone->__encap_len = tun_array.sz_total_len - inner_tunnel.ThisTunLength();
ctrlzone->action = TUNNAT_CZ_ACTION_FORWARD;
- assert(ctrlzone->__encap_len != 0);
+ /* 没有封装格式的,不执行剥离动作,送入应用 */
+ if (ctrlzone->__encap_len == 0)
+ {
+ return RT_SUCCESS;
+ }
/* 去掉封装报文头部 */
void * __adj_check = marsio_buff_adj(mbuf, ctrlzone->__encap_len);
- assert(__adj_check != NULL);
-
-
-#if MR_TUNNAT_USE_PHONY_ETHER_HEADER /* 构造伪以太网头部 */
- struct ether_hdr * p_ether_hdr = (struct ether_hdr *)
- marsio_buff_prepend(mbuf, sizeof(struct ether_hdr));
+ assert(__adj_check != nullptr);
- assert(p_ether_hdr != NULL);
+ /* 构造伪以太网头部 */
+ auto * p_ether_hdr = (struct ether_hdr *)marsio_buff_prepend(mbuf, sizeof(struct ether_hdr));
+ assert(p_ether_hdr != nullptr);
ctrlzone->__p_ether_type = p_ether_hdr->ether_type;
- switch (tun_array.GetInnerTunContainer().ThisTunType())
+ switch (inner_tunnel.ThisTunType())
{
case TUNNEL_TYPE_IPV4:
p_ether_hdr->ether_type = htons(ETHER_TYPE_IPv4);
@@ -233,8 +247,6 @@ static int __phy_to_virt_pkt_modify(TunnatInstance * instance, TunnatThreadInsta
assert(0);
}
-#endif
-
(void)__adj_check;
return RT_SUCCESS;
}
@@ -297,55 +309,52 @@ static void __phy_to_virt_one_device(TunnatInstance * instance, TunnatThreadInst
static int __virt_to_phy_pkt_forward(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);
+ auto * ctrlzone = static_cast<mr_tunnat_ctrlzone *>(marsio_buff_ctrlzone(mbuf, g_ctrlzone_id));
+ assert(ctrlzone != nullptr);
/* 需要回注的报文全部携带forward标记,这个标记是送入应用时标记的 */
- if (!(ctrlzone->action & TUNNAT_CZ_ACTION_FORWARD)) return RT_ERR;
-
- /* 对于没有封装的报文,如专用设备的保活报文,其隧道长度为0,不做任何处理 */
- if (ctrlzone->__encap_len == 0) return RT_ERR;
+ if (!(ctrlzone->action & TUNNAT_CZ_ACTION_FORWARD))
+ {
+ return RT_ERR;
+ }
-#if MR_TUNNAT_USE_PHONY_ETHER_HEADER
-
- /* 恢复伪以太网头部修改的数据,去掉以太网头部 */
- struct ether_hdr * p_eth_hdr = (struct ether_hdr *)marsio_buff_mtod(mbuf);
- p_eth_hdr->ether_type = ctrlzone->__p_ether_type;
+ /* 对于有封装长度的,恢复伪以太网头部修改的数据,去掉以太网头部 */
+ if (ctrlzone->__encap_len)
+ {
+ struct ether_hdr * p_eth_hdr = (struct ether_hdr *)marsio_buff_mtod(mbuf);
+ p_eth_hdr->ether_type = ctrlzone->__p_ether_type;
- void * __adj_check = marsio_buff_adj(mbuf, sizeof(struct ether_hdr));
- assert(__adj_check != NULL);
+ void * __adj_check = marsio_buff_adj(mbuf, sizeof(struct ether_hdr));
+ assert(__adj_check != nullptr);
+ marsio_buff_prepend(mbuf, ctrlzone->__encap_len);
-#endif
+ (void)__adj_check;
+ }
- marsio_buff_prepend(mbuf, ctrlzone->__encap_len);
+ /* 回注前原始报文修正 */
char * tun_start = marsio_buff_mtod(mbuf);
- tunnel_type tun_type = static_cast<tunnel_type>(ctrlzone->__encap_type);
+ auto tun_type = static_cast<tunnel_type>(ctrlzone->__encap_type);
TunnelContainer::PacketForwardModify(tun_start, ctrlzone->__encap_len, tun_type);
TUNNAT_THREAD_STAT_ADD(TUNNAT_STAT_FORWARD_TUNNEL_OUTPUT, 1);
-
- (void)__adj_check;
return RT_SUCCESS;
}
static int __virt_to_phy_pkt_encap(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);
+ auto * ctrlzone = static_cast<mr_tunnat_ctrlzone *>(marsio_buff_ctrlzone(mbuf, g_ctrlzone_id));
+ assert(ctrlzone != nullptr);
/* 封装标记,内外层都不封装 */
- if (!((ctrlzone->action & TUNNAT_CZ_ACTION_ENCAP_INNER) &&
- (ctrlzone->action & TUNNAT_CZ_ACTION_ENCAP_OUTER))) return RT_ERR;
-
-#if MR_TUNNAT_USE_PHONY_ETHER_HEADER
+ if (!((ctrlzone->action & TUNNAT_CZ_ACTION_ENCAP_INNER)
+ && (ctrlzone->action & TUNNAT_CZ_ACTION_ENCAP_OUTER)))
+ {
+ return RT_ERR;
+ }
SessionKey ss_key;
- struct ether_hdr *ether_hdr=(struct ether_hdr *)marsio_buff_mtod(mbuf);
+ auto *ether_hdr=(struct ether_hdr *)marsio_buff_mtod(mbuf);
switch(ntohs(ether_hdr->ether_type))
{
case ETHER_TYPE_IPv4:
@@ -368,8 +377,6 @@ static int __virt_to_phy_pkt_encap(TunnatInstance * instance, TunnatThreadInstan
assert(__adj_check != NULL);
assert(mbuf != NULL);
-#endif
-
switch(ss_key.type)
{
case KEY_TYPE_IPV4:
@@ -403,7 +410,10 @@ static int __virt_to_phy_pkt_encap(TunnatInstance * instance, TunnatThreadInstan
}
//fprintf(stderr, "query src %s dst %s, result is %p\n", str_in_addr_src, str_in_addr_dst, ss_entry);
- if (ss_entry != NULL) goto session_ready;
+ if (ss_entry != nullptr)
+ {
+ goto session_ready;
+ }
/* 没有查询到,使用最近的一次隧道数据,随便找到一个专用设备回注 */
if (instance->is_use_recent_tunnel)
@@ -411,7 +421,7 @@ static int __virt_to_phy_pkt_encap(TunnatInstance * instance, TunnatThreadInstan
ss_entry = th_instance->ss_table->QueryRecent(ss_key.type);
}
- if (ss_entry != NULL)
+ if (ss_entry != nullptr)
{
TUNNAT_THREAD_STAT_ADD(TUNNAT_STAT_ENCAP_USE_RECENT_SESSION, 1);
goto session_ready;
@@ -431,7 +441,8 @@ session_ready:
{
TunnelContainer & __tun_container = tun_array.tun_array[i];
- const char * pkt_ptr = marsio_buff_prepend(mbuf, __tun_container.ThisTunLength());
+ auto __this_tun_length = static_cast<uint16_t>(__tun_container.ThisTunLength());
+ const char * pkt_ptr = marsio_buff_prepend(mbuf, __this_tun_length);
unsigned int pkt_len = marsio_buff_datalen(mbuf);
tun_array.tun_array[i].PacketConstruct(pkt_ptr, pkt_len);
}
@@ -466,8 +477,6 @@ static int __virt_to_phy_pkt_virtual_link_id(TunnatInstance * instance, TunnatTh
return RT_ERR;
}
-#if MR_TUNNAT_USE_PHONY_ETHER_HEADER
-
/* 去掉以太网头部,因为是应用自己造的包,所以没有备份的以太网类型数据 */
/* 使用写时复制的报文修改接口,因为此时报文可能被其他人引用 */
@@ -477,13 +486,11 @@ static int __virt_to_phy_pkt_virtual_link_id(TunnatInstance * instance, TunnatTh
assert(__adj_check != nullptr);
assert(mbuf != nullptr);
-#endif
-
/* 逆序构建报文隧道,最内层隧道不构建 */
for (int i = tun_array->sz_array - 2; i >= 0; i--)
{
TunnelContainer & __tun_container = tun_array->tun_array[i];
- uint16_t __this_tun_length = (uint16_t)__tun_container.ThisTunLength();
+ auto __this_tun_length = static_cast<uint16_t>(__tun_container.ThisTunLength());
const char * pkt_ptr = marsio_buff_prepend(mbuf, __this_tun_length);
unsigned int pkt_len = marsio_buff_datalen(mbuf);
diff --git a/tunnat/src/tunnel.cc b/tunnat/src/tunnel.cc
index 94bd8d6..d2f98a0 100644
--- a/tunnat/src/tunnel.cc
+++ b/tunnat/src/tunnel.cc
@@ -330,6 +330,66 @@ cJSON * TunVxlan::ToJSON() const
return j_object;
}
+int TunVlanBridge::PacketParse(const char * pkt, unsigned int pkt_len)
+{
+ /* 以太网头部 */
+ auto * eth_hdr = (struct ether_hdr *) pkt;
+ if (eth_hdr->ether_type != htons(ETHER_TYPE_VLAN))
+ {
+ return RT_ERR;
+ }
+
+ unsigned int offset = 0;
+ pkt += sizeof(struct ether_hdr);
+ offset += sizeof(struct ether_hdr);
+
+ /* 外层IP头部 */
+ auto * vlan_hdr = (struct vlan_hdr *) pkt;
+ vlan_id_ = rte_cpu_to_le_16(vlan_hdr->vlan_tci);
+
+ /* 本节为虚拟隧道,不真正剥去头部,只记住vlan-id */
+ this->next_layer_type = TUNNEL_TYPE_ETHER;
+ this->this_layer_type = TUNNEL_TYPE_VLAN_BRIDGE;
+ this->this_layer_length = 0;
+
+ /* 成功 */
+ return RT_SUCCESS;
+}
+
+int TunVlanBridge::PacketConstruct(const char * pkt, unsigned int pkt_len)
+{
+ return PacketForwardModify(pkt, pkt_len);
+}
+
+int TunVlanBridge::PacketForwardModify(const char * pkt, unsigned int pkt_len)
+{
+ /* 不启用VLAN查表翻转时,直接返回不变更vlan-id */
+ auto * instance = TunnatInstance::TunnatInstanceGet();
+
+ /* 以太网头部 */
+ auto * eth_hdr = (struct ether_hdr *) pkt;
+ if (eth_hdr->ether_type != htons(ETHER_TYPE_VLAN)) return RT_ERR;
+
+ unsigned int offset = 0;
+ pkt += sizeof(struct ether_hdr);
+ offset += sizeof(struct ether_hdr);
+
+ /* 外层IP头部 */
+ auto * vlan_hdr = (struct vlan_hdr *) pkt;
+ uint16_t vlan_id = ntohs(vlan_hdr->vlan_tci);
+
+ auto target_vlan_ld_iter = instance->one_arm_bridge_vlan_map.find(vlan_id);
+ if (target_vlan_ld_iter == instance->one_arm_bridge_vlan_map.end())
+ {
+ return RT_ERR;
+ }
+
+ uint16_t map_vlan_id = target_vlan_ld_iter->second;
+ vlan_hdr->vlan_tci = htons(map_vlan_id);
+
+ return RT_SUCCESS;
+}
+
extern "C"
{
#include <ldbc.h>
@@ -515,27 +575,39 @@ int TunnelContainer::PacketParse(const char * pkt, unsigned int pkt_len,
switch (tunnel_type)
{
- case TUNNEL_TYPE_UNKNOWN:goto guess;
+ case TUNNEL_TYPE_UNKNOWN:
+ goto guess;
+
+ case TUNNEL_TYPE_G_VXLAN:
+ ret = tun_vxlan_object_.PacketParse(pkt, pkt_len);
+ break;
- case TUNNEL_TYPE_G_VXLAN:ret = tun_vxlan_object_.PacketParse(pkt, pkt_len);
+ case TUNNEL_TYPE_G_MAC_IN_MAC:
+ ret = tun_qmac_object_.PacketParse(pkt, pkt_len);
break;
- case TUNNEL_TYPE_G_MAC_IN_MAC:ret = tun_qmac_object_.PacketParse(pkt, pkt_len);
+ case TUNNEL_TYPE_VLAN_BRIDGE:
+ ret = tun_vlan_bridge_object_.PacketParse(pkt, pkt_len);
break;
- case TUNNEL_TYPE_ETHER:ret = tun_inner_ether_.PacketParse(pkt, pkt_len);
+ case TUNNEL_TYPE_ETHER:
+ ret = tun_inner_ether_.PacketParse(pkt, pkt_len);
break;
- case TUNNEL_TYPE_PPP:ret = tun_inner_ppp_.PacketParse(pkt, pkt_len);
+ case TUNNEL_TYPE_PPP:
+ ret = tun_inner_ppp_.PacketParse(pkt, pkt_len);
break;
- case TUNNEL_TYPE_HDLC:ret = tun_inner_hdlc_.PacketParse(pkt, pkt_len);
+ case TUNNEL_TYPE_HDLC:
+ ret = tun_inner_hdlc_.PacketParse(pkt, pkt_len);
break;
- case TUNNEL_TYPE_IPV4:ret = tun_inner_ipv4_.PacketParse(pkt, pkt_len);
+ case TUNNEL_TYPE_IPV4:
+ ret = tun_inner_ipv4_.PacketParse(pkt, pkt_len);
break;
- case TUNNEL_TYPE_IPV6:ret = tun_inner_ipv6_.PacketParse(pkt, pkt_len);
+ case TUNNEL_TYPE_IPV6:
+ ret = tun_inner_ipv6_.PacketParse(pkt, pkt_len);
break;
}
@@ -544,10 +616,10 @@ int TunnelContainer::PacketParse(const char * pkt, unsigned int pkt_len,
goto out;
guess:
- ret = tun_vxlan_object_.PacketParse(pkt, pkt_len);
+ ret = tun_vlan_bridge_object_.PacketParse(pkt, pkt_len);
if (ret >= 0)
{
- this_layer_type = TUNNEL_TYPE_G_VXLAN;
+ this_layer_type = TUNNEL_TYPE_VLAN_BRIDGE;
goto out;
}
@@ -558,6 +630,13 @@ guess:
goto out;
}
+ ret = tun_vxlan_object_.PacketParse(pkt, pkt_len);
+ if (ret >= 0)
+ {
+ this_layer_type = TUNNEL_TYPE_G_VXLAN;
+ goto out;
+ }
+
goto out;
out:
@@ -571,6 +650,7 @@ Tunnel * TunnelContainer::tun_object_get()
{
case TUNNEL_TYPE_G_VXLAN:return &tun_vxlan_object_;
case TUNNEL_TYPE_G_MAC_IN_MAC:return &tun_qmac_object_;
+ case TUNNEL_TYPE_VLAN_BRIDGE: return &tun_vlan_bridge_object_;
case TUNNEL_TYPE_ETHER:return &tun_inner_ether_;
case TUNNEL_TYPE_PPP:return &tun_inner_ppp_;
case TUNNEL_TYPE_HDLC:return &tun_inner_hdlc_;
@@ -601,10 +681,10 @@ int TunnelContainer::PacketForwardModify(const char * pkt, unsigned int pkt_len,
{
case TUNNEL_TYPE_G_VXLAN:return TunVxlan::PacketForwardModify(pkt, pkt_len);
case TUNNEL_TYPE_G_MAC_IN_MAC:return TunQMac::PacketForwardModify(pkt, pkt_len);
+ case TUNNEL_TYPE_VLAN_BRIDGE: return TunVlanBridge::PacketForwardModify(pkt, pkt_len);
case TUNNEL_TYPE_ETHER:return TunInnerEther::PacketForwardModify(pkt, pkt_len);
case TUNNEL_TYPE_HDLC:return TunInnerHDLC::PacketForwardModify(pkt, pkt_len);
case TUNNEL_TYPE_PPP:return TunInnerPPP::PacketForwardModify(pkt, pkt_len);
-
default:assert(0);
}
@@ -691,4 +771,4 @@ int TunInnerHDLC::PacketParse(const char * pkt, unsigned int pkt_len)
TUNNAT_THREAD_STAT_ADD(TUNNAT_STAT_INNER_HDLC_INPUT, 1);
return 0;
-}
+} \ No newline at end of file
diff --git a/tunnat/test/TestSession.cc b/tunnat/test/TestSession.cc
index c8e33df..f745821 100644
--- a/tunnat/test/TestSession.cc
+++ b/tunnat/test/TestSession.cc
@@ -9,6 +9,11 @@ uint8_t g_ctrlzone_id = 0;
__thread TunnatThreadStat * TunnatThreadStat::thread_stat_object_;
+struct TunnatInstance * TunnatInstance::TunnatInstanceGet()
+{
+ return nullptr;
+}
+
class TestSessionEnv : public testing::Environment
{
public: