diff options
| -rw-r--r-- | tunnat/include/tunnat.h | 2 | ||||
| -rw-r--r-- | tunnat/src/runtime.cc | 51 |
2 files changed, 53 insertions, 0 deletions
diff --git a/tunnat/include/tunnat.h b/tunnat/include/tunnat.h index caf606b..99bda31 100644 --- a/tunnat/include/tunnat.h +++ b/tunnat/include/tunnat.h @@ -127,6 +127,7 @@ public: /* 统计,原始报文输入类型 */ TUNNAT_STAT_VXLAN_INPUT, TUNNAT_STAT_QMAC_INPUT, + TUNNAT_STAT_BFD_INPUT, TUNNAT_STAT_INNER_ETHER_INPUT, TUNNAT_STAT_INNER_HDLC_INPUT, TUNNAT_STAT_INNER_PPP_INPUT, @@ -203,6 +204,7 @@ public: [TUNNAT_STAT_PKT_RAW_INPUT] = "TUNNAT_STAT_PKT_RAW_INPUT", [TUNNAT_STAT_VXLAN_INPUT] = "TUNNAT_STAT_VXLAN_INPUT", [TUNNAT_STAT_QMAC_INPUT] = "TUNNAT_STAT_QMAC_INPUT", + [TUNNAT_STAT_BFD_INPUT] = "TUNNAT_STAT_BFD_INPUT", [TUNNAT_STAT_INNER_ETHER_INPUT] = "TUNNAT_STAT_INNER_ETHER_INPUT", [TUNNAT_STAT_INNER_HDLC_INPUT] = "TUNNAT_STAT_INNER_HDLC_INPUT", [TUNNAT_STAT_INNER_PPP_INPUT] = "TUNNAT_STAT_INNER_PPP_INPUT", diff --git a/tunnat/src/runtime.cc b/tunnat/src/runtime.cc index 0ccdb85..6a26014 100644 --- a/tunnat/src/runtime.cc +++ b/tunnat/src/runtime.cc @@ -24,6 +24,24 @@ extern "C" #define IPV6_VERSION 0X06 #endif + +/* 特殊设备使用的保活协议 */ +#define BFD_DEFAULT_PORT (3784) /* 默认端口 */ +struct bfd_header +{ + uint8_t version_diag; + uint8_t flags; + uint8_t detect_time_multiplier; + uint8_t length; + uint8_t my_discriminator[4]; + uint8_t your_discriminator[4]; + uint8_t desired_min_tx_interval[4]; + uint8_t required_min_rx_interval[4]; + uint8_t required_min_echo_interval[4]; +}; + +static uint32_t __bfd_rehash_index = 0; + static int __phy_to_virt_pkt_decap(TunnatInstance * instance, TunnatThreadInstance * th_instance, marsio_buff_t * mbuf, TunnelContainerArray & tun_array) { @@ -128,6 +146,38 @@ static int __phy_to_virt_clear_cz(TunnatInstance * instance, TunnatThreadInstanc return RT_SUCCESS; } +#include <ldbc.h> + +/* 重哈希BFD报文,BFD按Round-Robin方式分配到下个应用的数据面线程 */ +static void __phy_to_virt_check_bfd_and_rehash(TunnatInstance * instance, + TunnatThreadInstance * th_instance, marsio_buff_t * mbuf) +{ + const char * pkt_ptr = marsio_buff_mtod(mbuf); + unsigned int pkt_len = marsio_buff_datalen(mbuf); + + /* 校验长度 */ + if(pkt_len < sizeof(struct ether_hdr) + + sizeof(struct ipv4_hdr) + sizeof(struct udp_hdr)) return; + + const struct ether_hdr * eth_hdr = (const struct ether_hdr *)pkt_ptr; + if(eth_hdr->ether_type != ntohs(ETHER_TYPE_IPv4)) return; + + const struct ipv4_hdr * ipv4_hdr = (const struct ipv4_hdr *)(eth_hdr + 1); + if(ipv4_hdr->next_proto_id != IPPROTO_UDP) return; + + unsigned int ipv4_hdr_len = (ipv4_hdr->version_ihl & 0xfU) * 4; + const struct udp_hdr * udp_hdr = (const struct udp_hdr *)((const char *)ipv4_hdr + ipv4_hdr_len); + if(udp_hdr->dst_port != ntohs(BFD_DEFAULT_PORT)) return; + + /* 设置重哈希值,采用Round-Robin方式 */ + marsio_buff_set_rehash_index(mbuf, __bfd_rehash_index++); + TUNNAT_THREAD_STAT_ADD(TUNNAT_STAT_BFD_INPUT, 1); + + (void)instance; + (void)th_instance; +} + + /* 封装报文修改,去掉封装报文头部 */ static int __phy_to_virt_pkt_modify(TunnatInstance * instance, TunnatThreadInstance * th_instance, marsio_buff_t * mbuf, TunnelContainerArray & tun_array) @@ -230,6 +280,7 @@ static void __phy_to_virt_one_device(TunnatInstance * instance, TunnatThreadInst else { __phy_to_virt_clear_cz(instance, th_instance, mbufs[i]); + __phy_to_virt_check_bfd_and_rehash(instance, th_instance, mbufs[i]); } } |
