2019-06-06 18:41:40 +08:00
|
|
|
|
|
|
|
|
#include <tfe_proxy.h>
|
|
|
|
|
#include <tfe_utils.h>
|
|
|
|
|
#include <tfe_types.h>
|
|
|
|
|
#include <traffic_mirror.h>
|
|
|
|
|
|
|
|
|
|
struct traffic_mirror_rebuild
|
|
|
|
|
{
|
2019-06-09 14:53:17 +08:00
|
|
|
struct tfe_stream_addr * c_s_addr;
|
|
|
|
|
struct tfe_stream_addr * s_c_addr;
|
|
|
|
|
|
2019-06-06 18:41:40 +08:00
|
|
|
struct profile_table_ex_data * target;
|
|
|
|
|
struct traffic_mirror_ethdev * ethdev;
|
|
|
|
|
|
|
|
|
|
uint32_t c_seq;
|
|
|
|
|
uint32_t s_seq;
|
|
|
|
|
};
|
|
|
|
|
|
2019-06-08 15:54:35 +08:00
|
|
|
/* The definition of vlan_hdr and tcp_hdr is from DPDK 17.05 */
|
|
|
|
|
struct vlan_hdr
|
|
|
|
|
{
|
|
|
|
|
uint16_t vlan_tci; /**< Priority (3) + CFI (1) + Identifier Code (12) */
|
|
|
|
|
uint16_t eth_proto;/**< Ethernet type of encapsulated frame. */
|
|
|
|
|
} __attribute__((__packed__));
|
|
|
|
|
|
|
|
|
|
struct tcp_hdr {
|
|
|
|
|
uint16_t src_port; /**< TCP source port. */
|
|
|
|
|
uint16_t dst_port; /**< TCP destination port. */
|
|
|
|
|
uint32_t sent_seq; /**< TX data sequence number. */
|
|
|
|
|
uint32_t recv_ack; /**< RX data acknowledgement sequence number. */
|
|
|
|
|
uint8_t data_off; /**< Data offset. */
|
|
|
|
|
uint8_t tcp_flags; /**< TCP flags */
|
|
|
|
|
uint16_t rx_win; /**< RX flow control window. */
|
|
|
|
|
uint16_t cksum; /**< TCP checksum. */
|
|
|
|
|
uint16_t tcp_urp; /**< TCP urgent pointer, if any. */
|
|
|
|
|
} __attribute__((__packed__));
|
|
|
|
|
|
|
|
|
|
#define TCP_URG_FLAG 0x20
|
|
|
|
|
#define TCP_ACK_FLAG 0x10
|
|
|
|
|
#define TCP_PSH_FLAG 0x08
|
|
|
|
|
#define TCP_RST_FLAG 0x04
|
|
|
|
|
#define TCP_SYN_FLAG 0x02
|
|
|
|
|
#define TCP_FIN_FLAG 0x01
|
|
|
|
|
#define TCP_FLAG_ALL 0x3F
|
|
|
|
|
|
2019-06-09 16:32:29 +08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-06 18:41:40 +08:00
|
|
|
static int tcp_header_construct(unsigned char *buf, unsigned short sp,
|
|
|
|
|
unsigned short dp, unsigned int seq, unsigned int ack,
|
|
|
|
|
unsigned char flags, unsigned short win, unsigned short urg)
|
|
|
|
|
{
|
2019-06-08 15:54:35 +08:00
|
|
|
struct tcp_hdr * tcp_hdr = (struct tcp_hdr *) buf;
|
2019-06-06 18:41:40 +08:00
|
|
|
assert(tcp_hdr != NULL);
|
|
|
|
|
|
2019-06-08 15:54:35 +08:00
|
|
|
tcp_hdr->src_port = sp;
|
|
|
|
|
tcp_hdr->dst_port = dp;
|
|
|
|
|
tcp_hdr->sent_seq = htonl(seq);
|
|
|
|
|
tcp_hdr->recv_ack = htonl(ack);
|
2019-06-09 14:53:17 +08:00
|
|
|
tcp_hdr->data_off = 0x50;
|
2019-06-08 15:54:35 +08:00
|
|
|
tcp_hdr->tcp_flags = flags;
|
|
|
|
|
tcp_hdr->rx_win = htons(win);
|
|
|
|
|
tcp_hdr->cksum = 0;
|
|
|
|
|
tcp_hdr->tcp_urp = 0;
|
|
|
|
|
return sizeof(struct tcp_hdr);
|
2019-06-06 18:41:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int tcp_header_construct_by_stream_addr(struct tfe_stream_addr * addr, unsigned char *buf,
|
2019-06-09 16:32:29 +08:00
|
|
|
unsigned int seq, unsigned int ack, unsigned char flags, unsigned short win, unsigned short urg,
|
|
|
|
|
unsigned int payload_len)
|
2019-06-06 18:41:40 +08:00
|
|
|
{
|
|
|
|
|
unsigned short sport;
|
|
|
|
|
unsigned short dport;
|
2019-06-09 16:32:29 +08:00
|
|
|
unsigned short cksum;
|
|
|
|
|
unsigned int tcphdr_len;
|
2019-06-06 18:41:40 +08:00
|
|
|
|
|
|
|
|
if (addr->addrtype == TFE_ADDR_STREAM_TUPLE4_V4)
|
|
|
|
|
{
|
|
|
|
|
sport = addr->tuple4_v4->source;
|
|
|
|
|
dport = addr->tuple4_v4->dest;
|
|
|
|
|
}
|
|
|
|
|
else if (addr->addrtype == TFE_ADDR_STREAM_TUPLE4_V6)
|
|
|
|
|
{
|
|
|
|
|
sport = addr->tuple4_v6->source;
|
|
|
|
|
dport = addr->tuple4_v6->dest;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-09 16:32:29 +08:00
|
|
|
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;
|
2019-06-06 18:41:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int ipv4_header_construct(unsigned char *buf, unsigned short carry_layer_len,
|
|
|
|
|
unsigned char tos, unsigned short id, unsigned short frag, unsigned char ttl,
|
|
|
|
|
unsigned char protocol, unsigned int src, unsigned int dst)
|
|
|
|
|
{
|
|
|
|
|
struct iphdr * ip_hdr = (struct iphdr *) buf;
|
|
|
|
|
ip_hdr->version = 4;
|
|
|
|
|
ip_hdr->ihl = 5;
|
|
|
|
|
ip_hdr->tos = tos;
|
|
|
|
|
ip_hdr->tot_len = htons(sizeof(struct iphdr) + carry_layer_len);
|
|
|
|
|
ip_hdr->id = htons(id);
|
|
|
|
|
ip_hdr->frag_off = 0;
|
|
|
|
|
ip_hdr->ttl = ttl;
|
|
|
|
|
ip_hdr->protocol = protocol;
|
|
|
|
|
ip_hdr->check = 0;
|
|
|
|
|
ip_hdr->saddr = src;
|
|
|
|
|
ip_hdr->daddr = dst;
|
|
|
|
|
|
2019-06-09 16:32:29 +08:00
|
|
|
/* checksum */
|
|
|
|
|
ip_hdr->check = __ipv4_cksum(ip_hdr);
|
2019-06-06 18:41:40 +08:00
|
|
|
return sizeof(struct iphdr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int ip_header_construct_by_stream_addr(struct tfe_stream_addr * addr,
|
|
|
|
|
unsigned char *buf, unsigned short carry_layer_len, unsigned char tos,
|
|
|
|
|
unsigned short id, unsigned short frag, unsigned char ttl, unsigned char protocol)
|
|
|
|
|
{
|
|
|
|
|
if (addr->addrtype == TFE_ADDR_STREAM_TUPLE4_V4)
|
|
|
|
|
{
|
|
|
|
|
return ipv4_header_construct(buf, carry_layer_len, tos, id,
|
|
|
|
|
frag, ttl, protocol, addr->tuple4_v4->saddr.s_addr, addr->tuple4_v4->daddr.s_addr);
|
|
|
|
|
}
|
2019-06-08 15:54:35 +08:00
|
|
|
else if (addr->addrtype == TFE_ADDR_STREAM_TUPLE4_V6)
|
|
|
|
|
{
|
|
|
|
|
/* TODO: IPv6 */
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
2019-06-06 18:41:40 +08:00
|
|
|
|
|
|
|
|
assert(0);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ether_header_construct(unsigned char *buf, unsigned char *dst,
|
|
|
|
|
unsigned char *src, unsigned short type)
|
|
|
|
|
{
|
|
|
|
|
struct ethhdr * eth_hdr = (struct ethhdr *) buf;
|
|
|
|
|
memcpy(eth_hdr->h_dest, dst, ETHER_ADDR_LEN);
|
|
|
|
|
memcpy(eth_hdr->h_source, src, ETHER_ADDR_LEN);
|
|
|
|
|
eth_hdr->h_proto = htons(type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void vlan_tag_construct(unsigned char *buf, unsigned short tci, unsigned short type)
|
|
|
|
|
{
|
|
|
|
|
struct vlan_hdr * vlan_hdr = (struct vlan_hdr *)buf;
|
|
|
|
|
vlan_hdr->vlan_tci = htons(tci);
|
|
|
|
|
vlan_hdr->eth_proto = htons(type);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void l2_send_to_target(struct traffic_mirror_ethdev * ethdev,
|
|
|
|
|
unsigned char * snd_buffer, unsigned int l3_data_offset, unsigned int l3_data_len,
|
|
|
|
|
struct ether_addr * target_addr, unsigned int vlan_tci, unsigned l3_protocol)
|
|
|
|
|
{
|
|
|
|
|
assert(l3_data_offset >= (sizeof(struct ethhdr) + sizeof(struct vlan_hdr)));
|
|
|
|
|
unsigned int header_offset = l3_data_offset;
|
2019-06-08 20:49:31 +08:00
|
|
|
unsigned int header_len = 0;
|
2019-06-06 18:41:40 +08:00
|
|
|
|
|
|
|
|
/* need to construct vlan header */
|
|
|
|
|
if (vlan_tci > 0)
|
|
|
|
|
{
|
|
|
|
|
header_offset -= sizeof(struct vlan_hdr);
|
2019-06-08 20:49:31 +08:00
|
|
|
header_len += sizeof(struct vlan_hdr);
|
2019-06-06 18:41:40 +08:00
|
|
|
vlan_tag_construct(snd_buffer + header_offset, vlan_tci, l3_protocol);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned int eth_protocol = vlan_tci > 0 ? ETH_P_8021Q : l3_protocol;
|
|
|
|
|
header_offset -= sizeof(struct ethhdr);
|
2019-06-08 20:49:31 +08:00
|
|
|
header_len += sizeof(struct ethhdr);
|
2019-06-06 18:41:40 +08:00
|
|
|
|
|
|
|
|
ether_header_construct(snd_buffer + header_offset, (unsigned char *)target_addr->ether_addr_octet,
|
|
|
|
|
(unsigned char *)ethdev->local_ether_addr, eth_protocol);
|
2019-06-08 20:49:31 +08:00
|
|
|
|
|
|
|
|
traffic_mirror_ethdev_inject(ethdev, (char *)snd_buffer + header_offset, header_len + l3_data_len);
|
2019-06-06 18:41:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void l2_send_to_target_group(struct traffic_mirror_ethdev * ethdev, struct profile_table_ex_data * t_group,
|
|
|
|
|
unsigned char * snd_buffer, unsigned int l3_data_offset, unsigned int l3_data_len, unsigned l3_protocol)
|
|
|
|
|
{
|
|
|
|
|
for(unsigned int i = 0; i < t_group->nr_targets; i++)
|
|
|
|
|
{
|
|
|
|
|
l2_send_to_target(ethdev, snd_buffer, l3_data_offset, l3_data_len,
|
|
|
|
|
&t_group->ether_addrs[i], t_group->vlans[i], l3_protocol);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tcp_segment_send_to_target_group(struct tfe_stream_addr * addr, struct traffic_mirror_ethdev * ethdev,
|
|
|
|
|
struct profile_table_ex_data * t_group, const char * payload, unsigned int payload_len,
|
|
|
|
|
unsigned int seq, unsigned int ack, char flags)
|
|
|
|
|
{
|
|
|
|
|
char pkt[ETHER_MAX_LEN];
|
|
|
|
|
|
2019-06-09 14:53:17 +08:00
|
|
|
unsigned sz_pkt_prepend = sizeof(struct ethhdr) + sizeof(struct vlan_hdr) +
|
|
|
|
|
sizeof(struct iphdr) + sizeof(struct tcphdr);
|
2019-06-06 18:41:40 +08:00
|
|
|
|
2019-06-09 14:53:17 +08:00
|
|
|
unsigned header_len = 0;
|
2019-06-08 20:49:31 +08:00
|
|
|
|
2019-06-09 14:53:17 +08:00
|
|
|
assert(sizeof(pkt) - sz_pkt_prepend >= payload_len);
|
|
|
|
|
memcpy(pkt + sz_pkt_prepend, payload, payload_len);
|
2019-06-06 18:41:40 +08:00
|
|
|
|
2019-06-09 14:53:17 +08:00
|
|
|
sz_pkt_prepend -= sizeof(struct tcp_hdr);
|
|
|
|
|
header_len += tcp_header_construct_by_stream_addr(addr, (unsigned char *)pkt + sz_pkt_prepend,
|
2019-06-09 16:32:29 +08:00
|
|
|
seq, ack, flags, 0xffff, 0, payload_len);
|
2019-06-09 14:53:17 +08:00
|
|
|
|
|
|
|
|
sz_pkt_prepend -= sizeof(struct iphdr);
|
|
|
|
|
header_len += ip_header_construct_by_stream_addr(addr, (unsigned char *)pkt + sz_pkt_prepend,
|
|
|
|
|
header_len + payload_len, 0, 0x1000, 0, 128, IPPROTO_TCP);
|
2019-06-06 18:41:40 +08:00
|
|
|
|
2019-06-08 20:49:31 +08:00
|
|
|
l2_send_to_target_group(ethdev, t_group, (unsigned char *)pkt, sz_pkt_prepend,
|
2019-06-09 14:53:17 +08:00
|
|
|
header_len + payload_len, ETHERTYPE_IP);
|
2019-06-06 18:41:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tcp_send_to_target_group(struct tfe_stream_addr * addr, struct traffic_mirror_ethdev * ethdev,
|
|
|
|
|
struct profile_table_ex_data * t_group, const char * payload,
|
|
|
|
|
unsigned int payload_len, unsigned int seq, unsigned int ack, char flags)
|
|
|
|
|
{
|
|
|
|
|
unsigned int payload_offset = 0;
|
|
|
|
|
unsigned mss = ethdev->mtu - (sizeof(struct iphdr) + sizeof(struct tcphdr));
|
|
|
|
|
|
2019-06-09 14:53:17 +08:00
|
|
|
/* Handshake or farewall */
|
|
|
|
|
if (payload == NULL || payload_len == 0)
|
2019-06-06 18:41:40 +08:00
|
|
|
{
|
2019-06-09 14:53:17 +08:00
|
|
|
tcp_segment_send_to_target_group(addr, ethdev, t_group, NULL, 0, seq, ack, flags);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while(payload_offset < payload_len)
|
|
|
|
|
{
|
|
|
|
|
unsigned int payload_sz_seg = MIN(payload_len - payload_offset, mss);
|
2019-06-06 18:41:40 +08:00
|
|
|
const char * payload_ptr_seg = payload + payload_offset;
|
|
|
|
|
|
|
|
|
|
tcp_segment_send_to_target_group(addr, ethdev, t_group, payload_ptr_seg, payload_sz_seg, seq, ack, flags);
|
|
|
|
|
seq += payload_sz_seg;
|
|
|
|
|
payload_offset += payload_sz_seg;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct traffic_mirror_rebuild * traffic_mirror_rebuild_create(struct tfe_stream_addr * addr,
|
|
|
|
|
struct profile_table_ex_data * target, struct traffic_mirror_ethdev * ethdev)
|
|
|
|
|
{
|
|
|
|
|
struct traffic_mirror_rebuild * instance = ALLOC(struct traffic_mirror_rebuild, 1);
|
2019-06-09 14:53:17 +08:00
|
|
|
instance->c_s_addr = addr;
|
|
|
|
|
instance->s_c_addr = tfe_stream_addr_reverse(addr);
|
2019-06-06 18:41:40 +08:00
|
|
|
instance->target = target;
|
|
|
|
|
instance->ethdev = ethdev;
|
|
|
|
|
|
|
|
|
|
/* the c_seq, s_seq, c_ipid, s_ipid is random
|
|
|
|
|
* TODO: use the fast random algorithm like Linux TCP/IP stack */
|
|
|
|
|
instance->c_seq = random();
|
|
|
|
|
instance->s_seq = random();
|
|
|
|
|
return instance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void traffic_mirror_rebuild_destroy(struct traffic_mirror_rebuild * instance)
|
|
|
|
|
{
|
2019-06-09 14:53:17 +08:00
|
|
|
tfe_stream_addr_free(instance->s_c_addr);
|
2019-06-06 18:41:40 +08:00
|
|
|
free(instance);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void traffic_mirror_rebuild_handshake(struct traffic_mirror_rebuild * instance)
|
|
|
|
|
{
|
2019-06-09 14:53:17 +08:00
|
|
|
tcp_send_to_target_group(instance->c_s_addr, instance->ethdev, instance->target,
|
2019-06-08 15:54:35 +08:00
|
|
|
NULL, 0, instance->c_seq, 0, TCP_SYN_FLAG);
|
2019-06-06 18:41:40 +08:00
|
|
|
|
2019-06-09 14:53:17 +08:00
|
|
|
tcp_send_to_target_group(instance->s_c_addr, instance->ethdev, instance->target,
|
2019-06-08 15:54:35 +08:00
|
|
|
NULL, 0, instance->s_seq, instance->c_seq + 1, TCP_SYN_FLAG | TCP_ACK_FLAG);
|
2019-06-06 18:41:40 +08:00
|
|
|
|
2019-06-09 14:53:17 +08:00
|
|
|
tcp_send_to_target_group(instance->c_s_addr, instance->ethdev, instance->target,
|
2019-06-08 15:54:35 +08:00
|
|
|
NULL, 0, instance->c_seq + 1, instance->s_seq + 1, TCP_ACK_FLAG);
|
2019-06-06 18:41:40 +08:00
|
|
|
|
|
|
|
|
instance->s_seq++;
|
|
|
|
|
instance->c_seq++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void traffic_mirror_rebuild_data(struct traffic_mirror_rebuild * instance,
|
|
|
|
|
const char * data, unsigned int datalen, enum tfe_conn_dir dir)
|
|
|
|
|
{
|
2019-06-09 14:53:17 +08:00
|
|
|
if (data == NULL || datalen == 0)
|
2019-06-06 18:41:40 +08:00
|
|
|
{
|
2019-06-09 14:53:17 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2019-06-06 18:41:40 +08:00
|
|
|
|
2019-06-09 14:53:17 +08:00
|
|
|
if (dir == CONN_DIR_DOWNSTREAM)
|
|
|
|
|
{
|
|
|
|
|
tcp_send_to_target_group(instance->c_s_addr, instance->ethdev, instance->target,
|
|
|
|
|
data, datalen, instance->c_seq, instance->s_seq, TCP_ACK_FLAG);
|
2019-06-06 18:41:40 +08:00
|
|
|
instance->c_seq += datalen;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-06-09 14:53:17 +08:00
|
|
|
tcp_send_to_target_group(instance->s_c_addr, instance->ethdev, instance->target,
|
|
|
|
|
data, datalen, instance->s_seq, instance->c_seq, TCP_ACK_FLAG);
|
2019-06-06 18:41:40 +08:00
|
|
|
instance->s_seq += datalen;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void traffic_mirror_rebuild_farewell(struct traffic_mirror_rebuild * instance)
|
|
|
|
|
{
|
2019-06-09 14:53:17 +08:00
|
|
|
/* C->S FIN */
|
|
|
|
|
tcp_send_to_target_group(instance->c_s_addr, instance->ethdev, instance->target,
|
|
|
|
|
NULL, 0, instance->c_seq, instance->s_seq, TCP_FIN_FLAG | TCP_ACK_FLAG);
|
|
|
|
|
|
|
|
|
|
/* C->S FIN, ACK */
|
|
|
|
|
tcp_send_to_target_group(instance->s_c_addr, instance->ethdev, instance->target,
|
|
|
|
|
NULL, 0, instance->s_seq, instance->c_seq + 1, TCP_ACK_FLAG);
|
|
|
|
|
|
|
|
|
|
instance->c_seq += 1;
|
|
|
|
|
|
|
|
|
|
/* S->C FIN */
|
|
|
|
|
tcp_send_to_target_group(instance->s_c_addr, instance->ethdev, instance->target,
|
|
|
|
|
NULL, 0, instance->s_seq, instance->c_seq, TCP_FIN_FLAG | TCP_ACK_FLAG);
|
|
|
|
|
|
|
|
|
|
/* C->S FIN, ACK */
|
|
|
|
|
tcp_send_to_target_group(instance->c_s_addr, instance->ethdev, instance->target,
|
|
|
|
|
NULL, 0, instance->c_seq, instance->s_seq + 1, TCP_ACK_FLAG);
|
|
|
|
|
|
|
|
|
|
instance->s_seq += 1;
|
2019-06-06 18:41:40 +08:00
|
|
|
}
|