增加解密流量转发中计算IP校验和、TCP校验和的功能
This commit is contained in:
@@ -217,7 +217,7 @@ void profile_table_ex_data_new_cb(int table_id, const char * key, const char * t
|
|||||||
goto success;
|
goto success;
|
||||||
}
|
}
|
||||||
|
|
||||||
json_item = cJSON_GetObjectItem(json_item, "mac");
|
json_item = cJSON_GetObjectItem(json_root, "mac");
|
||||||
if (json_item)
|
if (json_item)
|
||||||
{
|
{
|
||||||
if (unlikely(!cJSON_IsArray(json_item)))
|
if (unlikely(!cJSON_IsArray(json_item)))
|
||||||
|
|||||||
@@ -43,6 +43,84 @@ struct tcp_hdr {
|
|||||||
#define TCP_FIN_FLAG 0x01
|
#define TCP_FIN_FLAG 0x01
|
||||||
#define TCP_FLAG_ALL 0x3F
|
#define TCP_FLAG_ALL 0x3F
|
||||||
|
|
||||||
|
static inline uint32_t __rte_raw_cksum(const void *buf, size_t len, uint32_t sum)
|
||||||
|
{
|
||||||
|
/* workaround gcc strict-aliasing warning */
|
||||||
|
uintptr_t ptr = (uintptr_t) buf;
|
||||||
|
typedef uint16_t __attribute__((__may_alias__)) u16_p;
|
||||||
|
const u16_p * u16 = (const u16_p *) ptr;
|
||||||
|
|
||||||
|
while (len >= (sizeof(*u16) * 4))
|
||||||
|
{
|
||||||
|
sum += u16[0];
|
||||||
|
sum += u16[1];
|
||||||
|
sum += u16[2];
|
||||||
|
sum += u16[3];
|
||||||
|
len -= sizeof(*u16) * 4;
|
||||||
|
u16 += 4;
|
||||||
|
}
|
||||||
|
while (len >= sizeof(*u16))
|
||||||
|
{
|
||||||
|
sum += *u16;
|
||||||
|
len -= sizeof(*u16);
|
||||||
|
u16 += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if length is in odd bytes */
|
||||||
|
if (len == 1)
|
||||||
|
sum += *((const uint8_t *) u16);
|
||||||
|
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t __rte_raw_cksum_reduce(uint32_t sum)
|
||||||
|
{
|
||||||
|
sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff);
|
||||||
|
sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff);
|
||||||
|
return (uint16_t) sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t rte_raw_cksum(const void *buf, size_t len)
|
||||||
|
{
|
||||||
|
uint32_t sum = __rte_raw_cksum(buf, len, 0);
|
||||||
|
return __rte_raw_cksum_reduce(sum);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t __ipv4_cksum(const struct iphdr * ipv4_hdr)
|
||||||
|
{
|
||||||
|
uint16_t cksum = rte_raw_cksum(ipv4_hdr, sizeof(struct iphdr));
|
||||||
|
return (cksum == 0xffff) ? cksum : ~cksum;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint16_t __tcpudp_cksum_by_stream_addr_v4(const struct tfe_stream_addr * addr,
|
||||||
|
const void *l4_hdr, unsigned int l4_len)
|
||||||
|
{
|
||||||
|
struct ipv4_psd_header
|
||||||
|
{
|
||||||
|
uint32_t src_addr; /* IP address of source host. */
|
||||||
|
uint32_t dst_addr; /* IP address of destination host. */
|
||||||
|
uint8_t zero; /* zero. */
|
||||||
|
uint8_t proto; /* L4 protocol type. */
|
||||||
|
uint16_t len; /* L4 length. */
|
||||||
|
} psd_hdr;
|
||||||
|
|
||||||
|
psd_hdr.src_addr = addr->tuple4_v4->saddr.s_addr;
|
||||||
|
psd_hdr.dst_addr = addr->tuple4_v4->daddr.s_addr;
|
||||||
|
psd_hdr.zero = 0;
|
||||||
|
psd_hdr.proto = IPPROTO_TCP;
|
||||||
|
psd_hdr.len = htons(l4_len);
|
||||||
|
|
||||||
|
uint32_t cksum = rte_raw_cksum(l4_hdr, l4_len);
|
||||||
|
cksum += rte_raw_cksum(&psd_hdr, sizeof(psd_hdr));
|
||||||
|
|
||||||
|
cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
|
||||||
|
cksum = (~cksum) & 0xffff;
|
||||||
|
if (cksum == 0)
|
||||||
|
cksum = 0xffff;
|
||||||
|
|
||||||
|
return cksum;
|
||||||
|
}
|
||||||
|
|
||||||
static int tcp_header_construct(unsigned char *buf, unsigned short sp,
|
static int tcp_header_construct(unsigned char *buf, unsigned short sp,
|
||||||
unsigned short dp, unsigned int seq, unsigned int ack,
|
unsigned short dp, unsigned int seq, unsigned int ack,
|
||||||
unsigned char flags, unsigned short win, unsigned short urg)
|
unsigned char flags, unsigned short win, unsigned short urg)
|
||||||
@@ -63,10 +141,13 @@ static int tcp_header_construct(unsigned char *buf, unsigned short sp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int tcp_header_construct_by_stream_addr(struct tfe_stream_addr * addr, unsigned char *buf,
|
static int tcp_header_construct_by_stream_addr(struct tfe_stream_addr * addr, unsigned char *buf,
|
||||||
unsigned int seq, unsigned int ack, unsigned char flags, unsigned short win, unsigned short urg)
|
unsigned int seq, unsigned int ack, unsigned char flags, unsigned short win, unsigned short urg,
|
||||||
|
unsigned int payload_len)
|
||||||
{
|
{
|
||||||
unsigned short sport;
|
unsigned short sport;
|
||||||
unsigned short dport;
|
unsigned short dport;
|
||||||
|
unsigned short cksum;
|
||||||
|
unsigned int tcphdr_len;
|
||||||
|
|
||||||
if (addr->addrtype == TFE_ADDR_STREAM_TUPLE4_V4)
|
if (addr->addrtype == TFE_ADDR_STREAM_TUPLE4_V4)
|
||||||
{
|
{
|
||||||
@@ -83,7 +164,23 @@ static int tcp_header_construct_by_stream_addr(struct tfe_stream_addr * addr, un
|
|||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tcp_header_construct(buf, sport, dport, seq, ack, flags, win, urg);
|
tcphdr_len = tcp_header_construct(buf, sport, dport, seq, ack, flags, win, urg);
|
||||||
|
if (addr->addrtype == TFE_ADDR_STREAM_TUPLE4_V4)
|
||||||
|
{
|
||||||
|
cksum = __tcpudp_cksum_by_stream_addr_v4(addr, (void *)buf, tcphdr_len + payload_len);
|
||||||
|
}
|
||||||
|
else if (addr->addrtype == TFE_ADDR_STREAM_TUPLE4_V6)
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct tcp_hdr * tcp_hdr = (struct tcp_hdr *)buf;
|
||||||
|
tcp_hdr->cksum = cksum;
|
||||||
|
return tcphdr_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ipv4_header_construct(unsigned char *buf, unsigned short carry_layer_len,
|
static int ipv4_header_construct(unsigned char *buf, unsigned short carry_layer_len,
|
||||||
@@ -103,6 +200,8 @@ static int ipv4_header_construct(unsigned char *buf, unsigned short carry_layer_
|
|||||||
ip_hdr->saddr = src;
|
ip_hdr->saddr = src;
|
||||||
ip_hdr->daddr = dst;
|
ip_hdr->daddr = dst;
|
||||||
|
|
||||||
|
/* checksum */
|
||||||
|
ip_hdr->check = __ipv4_cksum(ip_hdr);
|
||||||
return sizeof(struct iphdr);
|
return sizeof(struct iphdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +296,7 @@ static void tcp_segment_send_to_target_group(struct tfe_stream_addr * addr, stru
|
|||||||
|
|
||||||
sz_pkt_prepend -= sizeof(struct tcp_hdr);
|
sz_pkt_prepend -= sizeof(struct tcp_hdr);
|
||||||
header_len += tcp_header_construct_by_stream_addr(addr, (unsigned char *)pkt + sz_pkt_prepend,
|
header_len += tcp_header_construct_by_stream_addr(addr, (unsigned char *)pkt + sz_pkt_prepend,
|
||||||
seq, ack, flags, 0xffff, 0);
|
seq, ack, flags, 0xffff, 0, payload_len);
|
||||||
|
|
||||||
sz_pkt_prepend -= sizeof(struct iphdr);
|
sz_pkt_prepend -= sizeof(struct iphdr);
|
||||||
header_len += ip_header_construct_by_stream_addr(addr, (unsigned char *)pkt + sz_pkt_prepend,
|
header_len += ip_header_construct_by_stream_addr(addr, (unsigned char *)pkt + sz_pkt_prepend,
|
||||||
|
|||||||
Reference in New Issue
Block a user