TSG-17749 tsg-service-chaining-engine更改VXLAN Frame源端口的计算方式

This commit is contained in:
luwenpeng
2023-11-20 10:31:21 +08:00
parent 83f9880ff0
commit 134d2c82b7
14 changed files with 327 additions and 271 deletions

View File

@@ -1,4 +1,4 @@
add_library(common src/session_table.cpp src/packet.cpp src/control_packet.cpp src/bfd.cpp src/utils.cpp src/g_vxlan.cpp src/log.cpp src/timestamp.cpp src/mpack.cpp)
add_library(common src/session_table.cpp src/packet.cpp src/control_packet.cpp src/bfd.cpp src/utils.cpp src/vxlan.cpp src/log.cpp src/timestamp.cpp src/mpack.cpp)
target_link_libraries(common PUBLIC cjson)
target_link_libraries(common PUBLIC MESA_handle_logger)

View File

@@ -1,52 +0,0 @@
#ifndef _G_VXLAN_H
#define _G_VXLAN_H
#ifdef __cpluscplus
extern "C"
{
#endif
struct g_vxlan
{
unsigned char flags;
unsigned char reserved[3];
// VNI 3 Bytes
unsigned char vlan_id_half_high;
unsigned char link_layer_type : 4; // 二层报文封装格式
unsigned char vlan_id_half_low : 4;
unsigned int dir_is_e2i : 1;
unsigned int traffic_is_decrypted : 1;
unsigned int sf_index : 5; // max value 32
unsigned int online_test : 1;
// Reserved 1 Bytes
unsigned int r7 : 1;
unsigned int r6 : 1;
unsigned int r5 : 1;
unsigned int r4 : 1;
unsigned int vni_flag : 1;
unsigned int r2 : 1;
unsigned int r1 : 1;
unsigned int r0 : 1;
} __attribute__((__packed__));
void g_vxlan_set_packet_dir(struct g_vxlan *hdr, int dir_is_e2i);
void g_vxlan_set_sf_index(struct g_vxlan *hdr, int sf_index);
void g_vxlan_set_traffic_type(struct g_vxlan *hdr, int traffic_is_decrypted);
int g_vxlan_get_packet_dir(struct g_vxlan *hdr);
int g_vxlan_get_sf_index(struct g_vxlan *hdr);
int g_vxlan_get_traffic_type(struct g_vxlan *hdr);
// return 0 : success
// return -1 : error
int g_vxlan_decode(struct g_vxlan **g_vxlan_hd, const char *raw_data, int raw_len);
#ifdef __cpluscplus
}
#endif
#endif

View File

@@ -10,6 +10,8 @@ extern "C"
#include <string.h>
#include <arpa/inet.h>
#include "uthash.h"
enum address_type
{
ADDR_TYPE_IPV4,
@@ -349,6 +351,13 @@ inline char *four_tuple_tostring(const struct four_tuple *tuple)
return str_ret;
}
inline uint64_t four_tuple_hash(const struct four_tuple *tuple)
{
uint64_t hash_value = 0;
HASH_VALUE(tuple, sizeof(struct four_tuple), hash_value);
return hash_value;
}
#ifdef __cpluscplus
}
#endif

View File

@@ -22,7 +22,6 @@ extern "C"
#define ATOMIC_INC(x) __atomic_fetch_add(x, 1, __ATOMIC_RELAXED)
#define ATOMIC_DEC(x) __atomic_fetch_sub(x, 1, __ATOMIC_RELAXED)
//#define ATOMIC_READ(x) __atomic_fetch_add(x, 0, __ATOMIC_RELAXED)
#define ATOMIC_READ(x) __atomic_load_n(x, __ATOMIC_RELAXED)
#define ATOMIC_ZERO(x) __atomic_fetch_and(x, 0, __ATOMIC_RELAXED)
#define ATOMIC_ADD(x, y) __atomic_fetch_add(x, y, __ATOMIC_RELAXED)
@@ -95,22 +94,6 @@ struct throughput_metrics
void throughput_metrics_inc(struct throughput_metrics *iterm, uint64_t n_pkts, uint64_t n_bytes);
/******************************************************************************
* protocol
******************************************************************************/
struct udp_hdr
{
uint16_t uh_sport; /* source port */
uint16_t uh_dport; /* destination port */
uint16_t uh_ulen; /* udp length */
uint16_t uh_sum; /* udp checksum */
} __attribute__((__packed__));
void build_udp_header(const char *l3_hdr, int l3_hdr_len, struct udp_hdr *udp_hdr, uint16_t udp_sport, uint16_t udp_dport, int payload_len);
void build_ip_header(struct ip *ip_hdr, uint8_t next_protocol, uint16_t ipid, const in_addr_t src_ip, const in_addr_t dst_ip, uint16_t payload_len);
void build_ether_header(struct ethhdr *eth_hdr, uint16_t next_protocol, const u_char src_mac[], const u_char dst_mac[]);
/******************************************************************************
* device
******************************************************************************/
@@ -119,10 +102,6 @@ int get_ip_by_device_name(const char *dev_name, char *ip_str);
int get_mac_by_device_name(const char *dev_name, char *mac_str);
int str_to_mac(const char *mac_str, u_char mac[]);
#define CHECKSUM_CARRY(x) (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff))
int checksum(uint16_t *addr, int len);
#ifdef __cpluscplus
}
#endif

89
common/include/vxlan.h Normal file
View File

@@ -0,0 +1,89 @@
#ifndef _VXLAN_H
#define _VXLAN_H
#ifdef __cpluscplus
extern "C"
{
#endif
#define __FAVOR_BSD 1
#include <netinet/udp.h>
#include "tuple.h"
/*
* VXLAN Header:
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |R|R|R|R|I|R|R|R| Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | VXLAN Network Identifier (VNI) | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
* Flags (8 bits):
* where the I flag MUST be set to 1 for a valid VXLAN Network ID (VNI).
* The other 7 bits (designated "R") are reserved fields and MUST be set
* to zero on transmission and ignored on receipt.
* Reserved fields (24 bits and 8 bits):
* MUST be set to zero on transmission and ignored on receipt.
*/
struct vxlan_hdr
{
uint8_t flags;
uint8_t reserved[3];
// VNI 3 Bytes
uint8_t vlan_id_half_high;
uint8_t link_layer_type : 4; // 二层报文封装格式
uint8_t vlan_id_half_low : 4;
uint8_t dir : 1;
uint8_t traffic : 1;
uint8_t sf_index : 5; // max value 32
uint8_t online_test : 1;
// Reserved 1 Bytes
uint8_t r7 : 1;
uint8_t r6 : 1;
uint8_t r5 : 1;
uint8_t r4 : 1;
uint8_t vni_flag : 1;
uint8_t r2 : 1;
uint8_t r1 : 1;
uint8_t r0 : 1;
} __attribute__((__packed__));
enum vni_opt
{
VNI_OPT_DIR = 0x80,
VNI_OPT_TRAFFIC = 0x40,
VNI_OPT_SFINDEX = 0x3f,
};
#define VXLAN_FLAGS 0x8
#define VXLAN_DST_PORT 4789
#define VXLAN_FRAME_HDR_LEN (sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udphdr) + sizeof(struct vxlan_hdr))
void vxlan_set_opt(struct vxlan_hdr *hdr, enum vni_opt opt, uint8_t val);
uint8_t vxlan_get_opt(struct vxlan_hdr *hdr, enum vni_opt opt);
// return 0 : success
// return -1 : error
int vxlan_frame_decode(struct vxlan_hdr **vxlan_hdr, const char *data, uint16_t len);
void vxlan_frame_encode(char *buff,
const u_char eth_src_mac[], const u_char eth_dst_mac[],
const in_addr_t ip_src_addr, const in_addr_t ip_dst_addr, uint16_t ip_id,
uint16_t udp_src_port, uint16_t udp_pld_len,
uint8_t vni_opt_dir, uint8_t vni_opt_traffic, uint8_t vni_opt_sf_index);
uint16_t calculate_vxlan_source_port(struct four_tuple *innermost_tuple4);
#ifdef __cpluscplus
}
#endif
#endif

View File

@@ -1,67 +0,0 @@
#include <netinet/ip.h>
#include <netinet/ether.h>
#include "utils.h"
#include "g_vxlan.h"
void g_vxlan_set_packet_dir(struct g_vxlan *hdr, int dir_is_e2i)
{
hdr->dir_is_e2i = (!!dir_is_e2i);
}
void g_vxlan_set_sf_index(struct g_vxlan *hdr, int sf_index)
{
hdr->sf_index = (0x1f & sf_index);
}
void g_vxlan_set_traffic_type(struct g_vxlan *hdr, int traffic_is_decrypted)
{
hdr->traffic_is_decrypted = (!!traffic_is_decrypted);
}
int g_vxlan_get_packet_dir(struct g_vxlan *hdr)
{
return (!!hdr->dir_is_e2i);
}
int g_vxlan_get_sf_index(struct g_vxlan *hdr)
{
return hdr->sf_index;
}
int g_vxlan_get_traffic_type(struct g_vxlan *hdr)
{
return (!!hdr->traffic_is_decrypted);
}
// return 0 : success
// return -1 : error
int g_vxlan_decode(struct g_vxlan **g_vxlan_hdr, const char *raw_data, int raw_len)
{
if (raw_len <= (int)(sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udp_hdr) + sizeof(struct g_vxlan)))
{
return -1;
}
struct ethhdr *eth_hdr = (struct ethhdr *)raw_data;
if (eth_hdr->h_proto != htons(ETH_P_IP))
{
return -1;
}
struct ip *ip_hdr = (struct ip *)((char *)eth_hdr + sizeof(struct ethhdr));
if (ip_hdr->ip_p != IPPROTO_UDP)
{
return -1;
}
struct udp_hdr *udp_hdr = (struct udp_hdr *)((char *)ip_hdr + sizeof(struct ip));
if (udp_hdr->uh_dport != htons(4789))
{
return -1;
}
*g_vxlan_hdr = (struct g_vxlan *)((char *)udp_hdr + sizeof(struct udp_hdr));
return 0;
}

View File

@@ -4,6 +4,7 @@
#include <netinet/ip6.h>
#define __FAVOR_BSD 1
#include <netinet/tcp.h>
#include <netinet/udp.h>
#include <netinet/ether.h>
#include <linux/ppp_defs.h>
@@ -26,14 +27,6 @@
LOG_PACKET, (tag), (next_proto)); \
}
struct udp_hdr
{
uint16_t uh_sport; /* source port */
uint16_t uh_dport; /* destination port */
uint16_t uh_ulen; /* udp length */
uint16_t uh_sum; /* udp checksum */
} __attribute__((__packed__));
/******************************************************************************
* Static API
******************************************************************************/
@@ -349,7 +342,7 @@ static inline void set_four_tuple(const char *data, enum layer_type type, struct
const struct ip *ipv4 = NULL;
const struct ip6_hdr *ipv6 = NULL;
const struct tcphdr *tcp = NULL;
const struct udp_hdr *udp = NULL;
const struct udphdr *udp = NULL;
switch (type)
{
@@ -358,7 +351,7 @@ static inline void set_four_tuple(const char *data, enum layer_type type, struct
four_tuple_set_port(tuple, tcp->th_sport, tcp->th_dport);
break;
case LAYER_TYPE_UDP:
udp = (const struct udp_hdr *)data;
udp = (const struct udphdr *)data;
four_tuple_set_port(tuple, udp->uh_sport, udp->uh_dport);
break;
case LAYER_TYPE_IPV4:
@@ -856,7 +849,7 @@ static inline const char *parse_gre(struct packet *handler, const char *data, ui
static inline const char *parse_udp(struct packet *handler, const char *data, uint16_t len)
{
if (unlikely(len < sizeof(struct udp_hdr)))
if (unlikely(len < sizeof(struct udphdr)))
{
PACKET_LOG_DATA_INSUFFICIENCY(LAYER_TYPE_UDP);
return data;
@@ -867,8 +860,8 @@ static inline const char *parse_udp(struct packet *handler, const char *data, ui
{
return data;
}
struct udp_hdr *hdr = (struct udp_hdr *)data;
SET_LAYER(handler, layer, LAYER_TYPE_UDP, sizeof(struct udp_hdr), data, len);
struct udphdr *hdr = (struct udphdr *)data;
SET_LAYER(handler, layer, LAYER_TYPE_UDP, sizeof(struct udphdr), data, len);
switch (ntohs(hdr->uh_dport))
{

View File

@@ -153,79 +153,6 @@ void throughput_metrics_inc(struct throughput_metrics *iterm, uint64_t n_pkts, u
iterm->n_pkts += n_pkts;
}
/******************************************************************************
* protocol
******************************************************************************/
int checksum(uint16_t *addr, int len)
{
int sum = 0;
int nleft = len;
uint16_t ans = 0;
uint16_t *w = addr;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*(char *)(&ans) = *(char *)w;
sum += ans;
}
return sum;
}
void build_udp_header(const char *l3_hdr, int l3_hdr_len, struct udp_hdr *udp_hdr, uint16_t udp_sport, uint16_t udp_dport, int payload_len)
{
memset(udp_hdr, 0, sizeof(struct udp_hdr));
int udp_hlen = sizeof(struct udp_hdr) + payload_len;
udp_hdr->uh_sport = htons(udp_sport);
udp_hdr->uh_dport = htons(udp_dport);
udp_hdr->uh_ulen = htons(udp_hlen);
udp_hdr->uh_sum = 0;
int sum = checksum((uint16_t *)l3_hdr, l3_hdr_len);
sum += ntohs(IPPROTO_UDP + udp_hlen);
sum += checksum((uint16_t *)udp_hdr, udp_hlen);
udp_hdr->uh_sum = CHECKSUM_CARRY(sum);
}
void build_ip_header(struct ip *ip_hdr, uint8_t next_protocol, uint16_t ipid, const in_addr_t src_ip, const in_addr_t dst_ip, uint16_t payload_len)
{
memset(ip_hdr, 0, sizeof(struct ip));
ip_hdr->ip_hl = 5; /* 20 byte header */
ip_hdr->ip_v = 4; /* version 4 */
ip_hdr->ip_tos = 0; /* IP tos */
ip_hdr->ip_id = htons(ipid); /* IP ID */
ip_hdr->ip_ttl = 80; /* time to live */
ip_hdr->ip_p = next_protocol; /* transport protocol */
ip_hdr->ip_src.s_addr = src_ip;
ip_hdr->ip_dst.s_addr = dst_ip;
ip_hdr->ip_len = htons(sizeof(struct ip) + payload_len); /* total length */
ip_hdr->ip_off = htons(0); /* fragmentation flags */
ip_hdr->ip_sum = 0; /* do this later */
int sum = checksum((uint16_t *)ip_hdr, 20);
ip_hdr->ip_sum = CHECKSUM_CARRY(sum);
}
// l3_protocol: ETH_P_IPV6/ETH_P_IP
void build_ether_header(struct ethhdr *eth_hdr, uint16_t next_protocol, const u_char src_mac[], const u_char dst_mac[])
{
memset(eth_hdr, 0, sizeof(struct ethhdr));
memcpy(eth_hdr->h_source, src_mac, ETH_ALEN);
memcpy(eth_hdr->h_dest, dst_mac, ETH_ALEN);
eth_hdr->h_proto = htons(next_protocol);
}
/******************************************************************************
* device
******************************************************************************/

169
common/src/vxlan.cpp Normal file
View File

@@ -0,0 +1,169 @@
#include <string.h>
#include <netinet/ip.h>
#include <netinet/in.h>
#include <netinet/ether.h>
#include "vxlan.h"
#define CHECKSUM_CARRY(x) (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff))
static inline int checksum(uint16_t *data, int len)
{
int sum = 0;
int nleft = len;
uint16_t ans = 0;
uint16_t *w = data;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*(char *)(&ans) = *(char *)w;
sum += ans;
}
return sum;
}
static inline void eth_header_encode(struct ethhdr *eth_hdr, const u_char src_mac[], const u_char dst_mac[], uint16_t proto)
{
memcpy(eth_hdr->h_source, src_mac, ETH_ALEN);
memcpy(eth_hdr->h_dest, dst_mac, ETH_ALEN);
eth_hdr->h_proto = htons(proto);
}
static inline void ip_header_encode(struct ip *ip_hdr, const in_addr_t src_ip, const in_addr_t dst_ip, uint16_t ipid, uint8_t proto, uint16_t pld_len)
{
ip_hdr->ip_v = 4; /* version 4 */
ip_hdr->ip_hl = 5; /* 20 byte header */
ip_hdr->ip_tos = 0; /* IP tos */
ip_hdr->ip_len = htons(sizeof(struct ip) + pld_len); /* total length */
ip_hdr->ip_id = htons(ipid); /* IP ID */
ip_hdr->ip_off = htons(0); /* fragmentation flags */
ip_hdr->ip_ttl = 80; /* time to live */
ip_hdr->ip_p = proto; /* transport protocol */
ip_hdr->ip_sum = 0; /* do this later */
ip_hdr->ip_src.s_addr = src_ip;
ip_hdr->ip_dst.s_addr = dst_ip;
int sum = checksum((uint16_t *)ip_hdr, 20);
ip_hdr->ip_sum = CHECKSUM_CARRY(sum);
}
static inline void udp_header_encode(struct udphdr *udp_hdr, uint16_t udp_sport, uint16_t udp_dport, uint16_t pld_len)
{
int udp_hlen = sizeof(struct udphdr) + pld_len;
udp_hdr->uh_sport = htons(udp_sport);
udp_hdr->uh_dport = htons(udp_dport);
udp_hdr->uh_ulen = htons(udp_hlen);
/*
* UDP Checksum: It SHOULD be transmitted as zero
* https://datatracker.ietf.org/doc/html/rfc7348#section-5
*/
udp_hdr->uh_sum = 0;
}
void vxlan_set_opt(struct vxlan_hdr *hdr, enum vni_opt opt, uint8_t val)
{
switch (opt)
{
case VNI_OPT_DIR:
hdr->dir = (!!val);
break;
case VNI_OPT_TRAFFIC:
hdr->traffic = (!!val);
break;
case VNI_OPT_SFINDEX:
hdr->sf_index = (0x1f & val);
break;
default:
break;
}
}
uint8_t vxlan_get_opt(struct vxlan_hdr *hdr, enum vni_opt opt)
{
switch (opt)
{
case VNI_OPT_DIR:
return (!!hdr->dir);
case VNI_OPT_TRAFFIC:
return (!!hdr->traffic);
case VNI_OPT_SFINDEX:
return hdr->sf_index;
default:
return 0;
}
}
// return 0 : success
// return -1 : error
int vxlan_frame_decode(struct vxlan_hdr **vxlan_hdr, const char *data, uint16_t len)
{
if (len < VXLAN_FRAME_HDR_LEN)
{
return -1;
}
struct ethhdr *eth_hdr = (struct ethhdr *)data;
if (eth_hdr->h_proto != htons(ETH_P_IP))
{
return -1;
}
struct ip *ip_hdr = (struct ip *)((char *)eth_hdr + sizeof(struct ethhdr));
if (ip_hdr->ip_p != IPPROTO_UDP)
{
return -1;
}
struct udphdr *udp_hdr = (struct udphdr *)((char *)ip_hdr + sizeof(struct ip));
if (udp_hdr->uh_dport != htons(4789))
{
return -1;
}
*vxlan_hdr = (struct vxlan_hdr *)((char *)udp_hdr + sizeof(struct udphdr));
return 0;
}
void vxlan_frame_encode(char *buff,
const u_char eth_src_mac[], const u_char eth_dst_mac[],
const in_addr_t ip_src_addr, const in_addr_t ip_dst_addr, uint16_t ip_id,
uint16_t udp_src_port, uint16_t udp_pld_len,
uint8_t vni_opt_dir, uint8_t vni_opt_traffic, uint8_t vni_opt_sf_index)
{
struct ethhdr *eth_hdr = (struct ethhdr *)buff;
struct ip *ip_hdr = (struct ip *)((char *)eth_hdr + sizeof(struct ethhdr));
struct udphdr *udp_hdr = (struct udphdr *)((char *)ip_hdr + sizeof(struct ip));
struct vxlan_hdr *vxlan_hdr = (struct vxlan_hdr *)((char *)udp_hdr + sizeof(struct udphdr));
// MUST be set to zero
memset(vxlan_hdr, 0, sizeof(struct vxlan_hdr));
vxlan_hdr->flags = VXLAN_FLAGS;
vxlan_set_opt(vxlan_hdr, VNI_OPT_DIR, vni_opt_dir);
vxlan_set_opt(vxlan_hdr, VNI_OPT_TRAFFIC, vni_opt_traffic);
vxlan_set_opt(vxlan_hdr, VNI_OPT_SFINDEX, vni_opt_sf_index);
eth_header_encode(eth_hdr, eth_src_mac, eth_dst_mac, ETH_P_IP);
ip_header_encode(ip_hdr, ip_src_addr, ip_dst_addr, ip_id, IPPROTO_UDP, sizeof(struct udphdr) + sizeof(struct vxlan_hdr) + udp_pld_len);
udp_header_encode(udp_hdr, udp_src_port, VXLAN_DST_PORT, sizeof(struct vxlan_hdr) + udp_pld_len);
}
uint16_t calculate_vxlan_source_port(struct four_tuple *innermost_tuple4)
{
/*
* When calculating the UDP source port number in this manner, it
* is RECOMMENDED that the value be in the dynamic/private port
* range 49152-65535 [RFC6335].
*/
uint64_t hash = four_tuple_hash(innermost_tuple4);
uint16_t port = (uint16_t)(hash % (65535 - 49152) + 49152);
return port;
}

View File

@@ -35,7 +35,7 @@ struct device_metrics
struct throughput_metrics endpoint_vlan_drop; // 累计值
};
// data_pkt_metrics 不包含 g_vxlan 所占的字节
// data_pkt_metrics 不包含 vxlan frame 所占的字节
struct data_pkt_metrics
{
struct throughput_metrics mirr_bypass; // 累计值

View File

@@ -74,6 +74,7 @@ struct session_ctx
{
uint64_t session_id;
char *session_addr;
uint16_t vxlan_src_port;
struct four_tuple inner_tuple4;
struct mutable_array rule_ids;

View File

@@ -161,6 +161,29 @@ static int health_check_method_table_add(struct session_table_addr *table, char
return 0;
}
#define CHECKSUM_CARRY(x) (x = (x >> 16) + (x & 0xffff), (~(x + (x >> 16)) & 0xffff))
static inline int checksum(uint16_t *data, int len)
{
int sum = 0;
int nleft = len;
uint16_t ans = 0;
uint16_t *w = data;
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
if (nleft == 1)
{
*(char *)(&ans) = *(char *)w;
sum += ans;
}
return sum;
}
static int send_icmp_pkt(char *addr)
{
int sockfd;

View File

@@ -11,7 +11,7 @@
#include "log.h"
#include "sce.h"
#include "utils.h"
#include "g_vxlan.h"
#include "vxlan.h"
#include "packet_io.h"
#include "sf_metrics.h"
#include "control_packet.h"
@@ -322,7 +322,7 @@ static int is_uplink_keepalive_packet(marsio_buff_t *rx_buff)
{
int raw_len = marsio_buff_datalen(rx_buff);
char *raw_data = marsio_buff_mtod(rx_buff);
if (raw_data == NULL || raw_len < (int)(sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udp_hdr)))
if (raw_data == NULL || raw_len < (int)(sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udphdr)))
{
return 0;
}
@@ -339,7 +339,7 @@ static int is_uplink_keepalive_packet(marsio_buff_t *rx_buff)
return 0;
}
struct udp_hdr *udp_hdr = (struct udp_hdr *)((char *)ip_hdr + sizeof(struct ip));
struct udphdr *udp_hdr = (struct udphdr *)((char *)ip_hdr + sizeof(struct ip));
if (udp_hdr->uh_dport != htons(3784))
{
return 0;
@@ -408,26 +408,6 @@ static struct session_ctx *inject_packet_search_session(struct session_table *ta
* action bypass/block/forward
******************************************************************************/
static void vxlan_encapsulate(marsio_buff_t *mbuff,
const u_char src_mac[], const u_char dst_mac[],
const in_addr_t src_ip, const in_addr_t dst_ip, uint16_t ipid,
uint16_t src_port, int payload_len, int is_e2i, int is_decrypted, int sf_index)
{
struct ethhdr *eth_hdr = (struct ethhdr *)marsio_buff_prepend(mbuff, sizeof(struct ethhdr) + sizeof(struct ip) + sizeof(struct udp_hdr) + sizeof(struct g_vxlan));
struct ip *ip_hdr = (struct ip *)((char *)eth_hdr + sizeof(struct ethhdr));
struct udp_hdr *udp_hdr = (struct udp_hdr *)((char *)ip_hdr + sizeof(struct ip));
struct g_vxlan *g_vxlan_hdr = (struct g_vxlan *)((char *)udp_hdr + sizeof(struct udp_hdr));
memset(g_vxlan_hdr, 0, sizeof(struct g_vxlan));
g_vxlan_set_packet_dir(g_vxlan_hdr, is_e2i);
g_vxlan_set_sf_index(g_vxlan_hdr, sf_index);
g_vxlan_set_traffic_type(g_vxlan_hdr, is_decrypted);
build_ether_header(eth_hdr, ETH_P_IP, src_mac, dst_mac);
build_ip_header(ip_hdr, IPPROTO_UDP, ipid, src_ip, dst_ip, sizeof(struct udp_hdr) + sizeof(struct g_vxlan) + payload_len);
build_udp_header((const char *)&ip_hdr->ip_src, 8, udp_hdr, src_port, 4789, sizeof(struct g_vxlan) + payload_len);
}
struct vlan_hdr
{
uint16_t vlan_cfi;
@@ -507,10 +487,11 @@ void vlan_encapsulate(marsio_buff_t *mbuff, int vlan_id, int replace_orig_vlan_h
}
}
static int send_packet_to_sf(marsio_buff_t *mbuff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx)
static int send_packet_to_sf(struct session_ctx *session_ctx, marsio_buff_t *mbuff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx)
{
thread_ctx->tx_packets_ipid++;
int nsend = 0;
char *buffer = NULL;
struct packet_io *packet_io = thread_ctx->ref_io;
struct thread_metrics *thread_metrics = &thread_ctx->thread_metrics;
@@ -518,9 +499,12 @@ static int send_packet_to_sf(marsio_buff_t *mbuff, struct metadata *meta, struct
switch (sf->sf_connectivity.method)
{
case ENCAPSULATE_METHOD_VXLAN_G:
vxlan_encapsulate(mbuff, packet_io->config.dev_endpoint_l3_mac, sf->sf_dst_mac,
packet_io->config.dev_endpoint_l3_ip, sf->sf_dst_ip, thread_ctx->tx_packets_ipid % 65535,
meta->session_id % (65535 - 49152) + 49152, meta->raw_len, meta->is_e2i_dir, meta->is_decrypted, sf->sf_index);
buffer = marsio_buff_prepend(mbuff, VXLAN_FRAME_HDR_LEN);
vxlan_frame_encode(buffer,
packet_io->config.dev_endpoint_l3_mac, sf->sf_dst_mac,
packet_io->config.dev_endpoint_l3_ip, sf->sf_dst_ip, thread_ctx->tx_packets_ipid % 65535,
session_ctx->vxlan_src_port, meta->raw_len,
meta->is_e2i_dir, meta->is_decrypted, sf->sf_index);
nsend = marsio_buff_datalen(mbuff);
marsio_send_burst_with_options(packet_io->dev_endpoint_l3.mr_path, thread_ctx->thread_index, &mbuff, 1, MARSIO_SEND_OPT_REHASH);
throughput_metrics_inc(&(thread_metrics->device.endpoint_vxlan_tx), 1, nsend);
@@ -603,7 +587,7 @@ static void action_mirr_block(marsio_buff_t *rx_buff, struct metadata *meta, str
throughput_metrics_inc(&(thread_metrics->data_pkt.mirr_block), 1, raw_len);
}
static void action_mirr_forward(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx)
static void action_mirr_forward(struct session_ctx *session_ctx, marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx)
{
struct thread_metrics *thread_metrics = &thread_ctx->thread_metrics;
struct packet_io *packet_io = thread_ctx->ref_io;
@@ -622,7 +606,7 @@ static void action_mirr_forward(marsio_buff_t *rx_buff, struct metadata *meta, s
char *copy_ptr = marsio_buff_append(new_buff, raw_len);
memcpy(copy_ptr, raw_data, raw_len);
int nsend = send_packet_to_sf(new_buff, meta, sf, thread_ctx);
int nsend = send_packet_to_sf(session_ctx, new_buff, meta, sf, thread_ctx);
throughput_metrics_inc(&(thread_metrics->data_pkt.mirr_tx), 1, raw_len);
throughput_metrics_inc(&sf->tx, 1, nsend);
sf_metrics_inc(thread_ctx->sf_metrics, sf->rule_vsys_id, sf->rule_id, sf->sff_profile_id, sf->sf_profile_id, 0, 0, 1, nsend);
@@ -647,12 +631,12 @@ static void action_stee_block(marsio_buff_t *rx_buff, struct metadata *meta, str
marsio_buff_free(packet_io->instance, &rx_buff, 1, 0, thread_index);
}
static void action_stee_forward(marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx)
static void action_stee_forward(struct session_ctx *session_ctx, marsio_buff_t *rx_buff, struct metadata *meta, struct selected_sf *sf, struct thread_ctx *thread_ctx)
{
struct thread_metrics *thread_metrics = &thread_ctx->thread_metrics;
int raw_len = marsio_buff_datalen(rx_buff);
int nsend = send_packet_to_sf(rx_buff, meta, sf, thread_ctx);
int nsend = send_packet_to_sf(session_ctx, rx_buff, meta, sf, thread_ctx);
throughput_metrics_inc(&(thread_metrics->data_pkt.stee_tx), 1, raw_len);
throughput_metrics_inc(&sf->tx, 1, nsend);
sf_metrics_inc(thread_ctx->sf_metrics, sf->rule_vsys_id, sf->rule_id, sf->sff_profile_id, sf->sf_profile_id, 0, 0, 1, nsend);
@@ -707,12 +691,12 @@ static void action_sf_chaining(struct thread_ctx *thread_ctx, struct session_ctx
if (sf->sff_forward_type == FORWARD_TYPE_STEERING)
{
action_stee_forward(rx_buff, meta, sf, thread_ctx);
action_stee_forward(session_ctx, rx_buff, meta, sf, thread_ctx);
return;
}
else
{
action_mirr_forward(rx_buff, meta, sf, thread_ctx);
action_mirr_forward(session_ctx, rx_buff, meta, sf, thread_ctx);
continue;
}
}
@@ -962,6 +946,7 @@ static void handle_session_opening(struct metadata *meta, struct control_packet
struct session_ctx *session_ctx = session_ctx_new();
session_ctx->session_id = meta->session_id;
session_ctx->session_addr = four_tuple_tostring(&inner_tuple4);
session_ctx->vxlan_src_port = calculate_vxlan_source_port(&inner_tuple4);
four_tuple_copy(&session_ctx->inner_tuple4, &inner_tuple4);
metadata_deep_copy(session_ctx->ctrl_meta, meta);
session_ctx->chainings.chaining_raw = selected_chaining_create(chaining_size, session_ctx->session_id, session_ctx->session_addr);
@@ -1164,7 +1149,7 @@ static void handle_inject_vxlan_packet(marsio_buff_t *rx_buff, struct thread_ctx
struct thread_metrics *thread_metrics = &thread_ctx->thread_metrics;
struct metadata meta;
struct g_vxlan *g_vxlan_hdr = NULL;
struct vxlan_hdr *vxlan_hdr = NULL;
struct session_ctx *session_ctx = NULL;
struct selected_chaining *chaining = NULL;
memset(&meta, 0, sizeof(struct metadata));
@@ -1172,20 +1157,20 @@ static void handle_inject_vxlan_packet(marsio_buff_t *rx_buff, struct thread_ctx
int sf_index = 0;
int raw_len = marsio_buff_datalen(rx_buff);
char *raw_data = marsio_buff_mtod(rx_buff);
if (g_vxlan_decode(&g_vxlan_hdr, raw_data, raw_len) == -1)
if (vxlan_frame_decode(&vxlan_hdr, raw_data, raw_len) == -1)
{
throughput_metrics_inc(&(thread_metrics->device.endpoint_vxlan_drop), 1, raw_len);
action_err_block(rx_buff, &meta, NULL, thread_ctx);
return;
}
meta.raw_data = (char *)g_vxlan_hdr + sizeof(struct g_vxlan);
meta.raw_len = raw_len - sizeof(struct ethhdr) - sizeof(struct ip) - sizeof(struct udp_hdr) - sizeof(struct g_vxlan);
meta.raw_data = (char *)vxlan_hdr + sizeof(struct vxlan_hdr);
meta.raw_len = raw_len - VXLAN_FRAME_HDR_LEN;
meta.l7offset = 0;
meta.is_e2i_dir = g_vxlan_get_packet_dir(g_vxlan_hdr);
meta.is_ctrl_pkt = 0;
meta.is_decrypted = g_vxlan_get_traffic_type(g_vxlan_hdr);
sf_index = g_vxlan_get_sf_index(g_vxlan_hdr);
sf_index = vxlan_get_opt(vxlan_hdr, VNI_OPT_SFINDEX);
meta.is_e2i_dir = vxlan_get_opt(vxlan_hdr, VNI_OPT_DIR);
meta.is_decrypted = vxlan_get_opt(vxlan_hdr, VNI_OPT_TRAFFIC);
session_ctx = inject_packet_search_session(session_table, meta.raw_data, meta.raw_len);
if (session_ctx == NULL)

View File

@@ -12,7 +12,7 @@ extern "C"
#include "sce.h"
#include "log.h"
#include "marsio.h"
#include "g_vxlan.h"
#include "vxlan.h"
#include "packet_io.h"
#include "sf_metrics.h"
#include "health_check.h"
@@ -206,7 +206,7 @@ inline void gtest_frame_log(struct gtest_frame *instance)
inline int mbuff_cmp_payload(marsio_buff_t *buff, marsio_buff_t *vxlan_pkt)
{
struct g_vxlan *g_vxlan_hdr = NULL;
struct vxlan_hdr *vxlan_hdr = NULL;
int buff_len = marsio_buff_datalen(buff);
char *buff_data = marsio_buff_mtod(buff);
@@ -218,7 +218,7 @@ inline int mbuff_cmp_payload(marsio_buff_t *buff, marsio_buff_t *vxlan_pkt)
goto error_out;
}
if (g_vxlan_decode(&g_vxlan_hdr, vxlan_pkt_data, vxlan_pkt_len) != 0)
if (vxlan_frame_decode(&vxlan_hdr, vxlan_pkt_data, vxlan_pkt_len) != 0)
{
goto error_out;
}