支持从原始流量中获取MAC地址并用于解密流量转发以太网头部的构建。

This commit is contained in:
luqiuwen
2019-09-18 20:00:03 +08:00
parent 4af0b21d58
commit ac14a745f9
4 changed files with 189 additions and 142 deletions

View File

@@ -37,7 +37,11 @@ enum tfe_cmsg_tlv_type
TFE_CMSG_SSL_CLIENT_SIDE_VERSION, TFE_CMSG_SSL_CLIENT_SIDE_VERSION,
TFE_CMSG_SSL_PINNING_STATE, //size uint64_t, 0-not pinning 1-pinning 2-maybe pinning TFE_CMSG_SSL_PINNING_STATE, //size uint64_t, 0-not pinning 1-pinning 2-maybe pinning
TFE_CMSG_SSL_CERT_VERIFY, TFE_CMSG_SSL_CERT_VERIFY,
TFE_CMSG_SSL_ERROR //string TFE_CMSG_SSL_ERROR, //string
/* Original Traffic's src & dst MAC address */
TFE_CMSG_SRC_MAC,
TFE_CMSG_DST_MAC,
}; };
struct tfe_cmsg* tfe_cmsg_init(); struct tfe_cmsg* tfe_cmsg_init();

View File

@@ -108,6 +108,7 @@ void traffic_mirror_ethdev_destroy(struct traffic_mirror_ethdev * ethdev);
int traffic_mirror_ethdev_finish(struct traffic_mirror_ethdev * ethdev, unsigned int tid, unsigned int pktlen); int traffic_mirror_ethdev_finish(struct traffic_mirror_ethdev * ethdev, unsigned int tid, unsigned int pktlen);
struct traffic_mirror_rebuild * traffic_mirror_rebuild_create(struct tfe_stream_addr * addr, struct traffic_mirror_rebuild * traffic_mirror_rebuild_create(struct tfe_stream_addr * addr,
struct ether_addr * s_ether_addr, struct ether_addr * d_ether_addr,
struct traffic_mirror_rebuild_target * target, struct traffic_mirror_ethdev * ethdev); struct traffic_mirror_rebuild_target * target, struct traffic_mirror_ethdev * ethdev);
void traffic_mirror_rebuild_destroy(struct traffic_mirror_rebuild * instance); void traffic_mirror_rebuild_destroy(struct traffic_mirror_rebuild * instance);

View File

@@ -561,6 +561,9 @@ int traffic_mirror_on_open_cb(const struct tfe_stream * stream, unsigned int thr
struct policy_table_ex_data * policy_ex_data = NULL; struct policy_table_ex_data * policy_ex_data = NULL;
struct profile_table_ex_data * profile_ex_data = NULL; struct profile_table_ex_data * profile_ex_data = NULL;
struct ether_addr c_ether_addr = {};
struct ether_addr s_ether_addr = {};
int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_POLICY_ID, (unsigned char *) &opt_val, sizeof(opt_val), &opt_out_size); int ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_POLICY_ID, (unsigned char *) &opt_val, sizeof(opt_val), &opt_out_size);
if (ret < 0) if (ret < 0)
{ {
@@ -594,13 +597,33 @@ int traffic_mirror_on_open_cb(const struct tfe_stream * stream, unsigned int thr
goto detach; goto detach;
} }
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_SRC_MAC, (unsigned char *) &c_ether_addr,
sizeof(c_ether_addr), &opt_out_size);
if (ret < 0)
{
TFE_LOG_ERROR(instance->logger, "failed at source mac address, detach the stream.");
goto detach;
}
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_DST_MAC, (unsigned char *) &s_ether_addr,
sizeof(s_ether_addr), &opt_out_size);
if (ret < 0)
{
TFE_LOG_ERROR(instance->logger, "failed at dest mac address, detach the stream.");
goto detach;
}
target_id = random() % profile_ex_data->nr_targets; target_id = random() % profile_ex_data->nr_targets;
rebuild_target = ALLOC(struct traffic_mirror_rebuild_target, 1); rebuild_target = ALLOC(struct traffic_mirror_rebuild_target, 1);
rebuild_target->vlan_tci = profile_ex_data->vlans[target_id]; rebuild_target->vlan_tci = profile_ex_data->vlans[target_id];
rebuild_target->ether_addr = profile_ex_data->ether_addrs[target_id]; rebuild_target->ether_addr = profile_ex_data->ether_addrs[target_id];
me = ALLOC(struct traffic_mirror_me, 1); me = ALLOC(struct traffic_mirror_me, 1);
me->rebuild_ctx = traffic_mirror_rebuild_create(stream->addr, rebuild_target, instance->ethdev); me->rebuild_ctx = traffic_mirror_rebuild_create(stream->addr, &c_ether_addr, &s_ether_addr,
rebuild_target, instance->ethdev);
me->profile_ex_data = profile_ex_data; me->profile_ex_data = profile_ex_data;
*pme = (void *) me; *pme = (void *) me;

View File

@@ -11,6 +11,8 @@ struct traffic_mirror_rebuild
{ {
struct tfe_stream_addr * c_s_addr; struct tfe_stream_addr * c_s_addr;
struct tfe_stream_addr * s_c_addr; struct tfe_stream_addr * s_c_addr;
struct ether_addr c_ether_addr;
struct ether_addr s_ether_addr;
struct traffic_mirror_rebuild_target * target; struct traffic_mirror_rebuild_target * target;
struct traffic_mirror_ethdev * ethdev; struct traffic_mirror_ethdev * ethdev;
@@ -278,14 +280,13 @@ static void vlan_tag_construct(unsigned char *buf, unsigned short tci, unsigned
} }
static int ether_header_construct(struct traffic_mirror_ethdev * ethdev, char * buffer, static int ether_header_construct(struct traffic_mirror_ethdev * ethdev, char * buffer,
struct ether_addr * target_addr, unsigned int vlan_tci, unsigned l3_protocol) struct ether_addr * source, struct ether_addr * dest, unsigned int vlan_tci, unsigned l3_protocol)
{ {
unsigned int header_len = 0; unsigned int header_len = 0;
unsigned int eth_protocol = vlan_tci > 0 ? ETH_P_8021Q : l3_protocol; unsigned int eth_protocol = vlan_tci > 0 ? ETH_P_8021Q : l3_protocol;
ether_header_construct_helper((unsigned char *) buffer + header_len, ether_header_construct_helper((unsigned char *) buffer + header_len,
(unsigned char *)target_addr->ether_addr_octet, (unsigned char *) dest, (unsigned char *) source, eth_protocol);
(unsigned char *)ethdev->local_ether_addr, eth_protocol);
header_len += sizeof(struct ethhdr); header_len += sizeof(struct ethhdr);
@@ -299,9 +300,9 @@ static int ether_header_construct(struct traffic_mirror_ethdev * ethdev, char *
return header_len; return header_len;
} }
static void tcp_segment_send_to_target_group(struct tfe_stream_addr * addr, static void tcp_segment_send_to_target_group(struct tfe_stream_addr * addr, struct ether_addr * ether_addr_src,
struct traffic_mirror_ethdev * ethdev, struct traffic_mirror_rebuild_target * target, struct ether_addr * ether_addr_dst, struct traffic_mirror_ethdev * ethdev,
unsigned int tid, const char * payload, unsigned int payload_len, struct traffic_mirror_rebuild_target * target, unsigned int tid, const char * payload, unsigned int payload_len,
unsigned int seq, unsigned int ack, char flags) unsigned int seq, unsigned int ack, char flags)
{ {
char * pkt_buffer = ethdev->fn_send_prepare(ethdev, tid); char * pkt_buffer = ethdev->fn_send_prepare(ethdev, tid);
@@ -318,7 +319,16 @@ static void tcp_segment_send_to_target_group(struct tfe_stream_addr * addr,
unsigned int pkt_len = 0; unsigned int pkt_len = 0;
/* Ethernet and VLAN header */ /* Ethernet and VLAN header */
pkt_len += ether_header_construct(ethdev, pkt_buffer, &target->ether_addr, target->vlan_tci, l3_protocol); if (target->vlan_tci > 0)
{
pkt_len += ether_header_construct(ethdev, pkt_buffer, ether_addr_src,
ether_addr_dst, target->vlan_tci, l3_protocol);
}
else
{
pkt_len += ether_header_construct(ethdev, pkt_buffer, ether_addr_src,
&target->ether_addr, target->vlan_tci, l3_protocol);
}
/* IPv4/IPv6 Header */ /* IPv4/IPv6 Header */
pkt_len += ip_header_construct_by_stream_addr(addr, pkt_len += ip_header_construct_by_stream_addr(addr,
@@ -338,9 +348,10 @@ static void tcp_segment_send_to_target_group(struct tfe_stream_addr * addr,
} }
} }
static void tcp_send_to_target(struct tfe_stream_addr * addr, struct traffic_mirror_ethdev * ethdev, static void tcp_send_to_target(struct tfe_stream_addr * addr, struct ether_addr * ether_addr_src,
struct traffic_mirror_rebuild_target * target, unsigned int tid, const char * payload, struct ether_addr * ether_addr_dst, struct traffic_mirror_ethdev * ethdev,
unsigned int payload_len, unsigned int seq, unsigned int ack, char flags) struct traffic_mirror_rebuild_target * target, unsigned int tid, const char * payload, unsigned int payload_len,
unsigned int seq, unsigned int ack, char flags)
{ {
unsigned int payload_offset = 0; unsigned int payload_offset = 0;
unsigned mss = ethdev->mtu - (MAX(sizeof(struct iphdr), sizeof(struct ip6_hdr)) + sizeof(struct tcphdr)); unsigned mss = ethdev->mtu - (MAX(sizeof(struct iphdr), sizeof(struct ip6_hdr)) + sizeof(struct tcphdr));
@@ -348,7 +359,8 @@ static void tcp_send_to_target(struct tfe_stream_addr * addr, struct traffic_mir
/* handshake or farewell */ /* handshake or farewell */
if (payload == NULL || payload_len == 0) if (payload == NULL || payload_len == 0)
{ {
tcp_segment_send_to_target_group(addr, ethdev, target, tid, NULL, 0, seq, ack, flags); tcp_segment_send_to_target_group(addr, ether_addr_src, ether_addr_dst,
ethdev, target, tid, NULL, 0, seq, ack, flags);
return; return;
} }
@@ -357,18 +369,23 @@ static void tcp_send_to_target(struct tfe_stream_addr * addr, struct traffic_mir
unsigned int payload_sz_seg = MIN(payload_len - payload_offset, mss); unsigned int payload_sz_seg = MIN(payload_len - payload_offset, mss);
const char * payload_ptr_seg = payload + payload_offset; const char * payload_ptr_seg = payload + payload_offset;
tcp_segment_send_to_target_group(addr, ethdev, target, tid, payload_ptr_seg, payload_sz_seg, seq, ack, flags); tcp_segment_send_to_target_group(addr, ether_addr_src, ether_addr_dst,
ethdev, target, tid, payload_ptr_seg, payload_sz_seg, seq, ack, flags);
seq += payload_sz_seg; seq += payload_sz_seg;
payload_offset += payload_sz_seg; payload_offset += payload_sz_seg;
} }
} }
struct traffic_mirror_rebuild * traffic_mirror_rebuild_create(struct tfe_stream_addr * addr, struct traffic_mirror_rebuild * traffic_mirror_rebuild_create(struct tfe_stream_addr * addr,
struct ether_addr * c_ether_addr, struct ether_addr * s_ether_addr,
struct traffic_mirror_rebuild_target * target, struct traffic_mirror_ethdev * ethdev) struct traffic_mirror_rebuild_target * target, struct traffic_mirror_ethdev * ethdev)
{ {
struct traffic_mirror_rebuild * instance = ALLOC(struct traffic_mirror_rebuild, 1); struct traffic_mirror_rebuild * instance = ALLOC(struct traffic_mirror_rebuild, 1);
instance->c_s_addr = addr; instance->c_s_addr = addr;
instance->s_c_addr = tfe_stream_addr_reverse(addr); instance->s_c_addr = tfe_stream_addr_reverse(addr);
instance->c_ether_addr = *c_ether_addr;
instance->s_ether_addr = *s_ether_addr;
instance->target = target; instance->target = target;
instance->ethdev = ethdev; instance->ethdev = ethdev;
@@ -387,14 +404,16 @@ void traffic_mirror_rebuild_destroy(struct traffic_mirror_rebuild * instance)
void traffic_mirror_rebuild_handshake(struct traffic_mirror_rebuild * instance, unsigned int tid) void traffic_mirror_rebuild_handshake(struct traffic_mirror_rebuild * instance, unsigned int tid)
{ {
tcp_send_to_target(instance->c_s_addr, instance->ethdev, instance->target, tid, tcp_send_to_target(instance->c_s_addr, &instance->c_ether_addr, &instance->s_ether_addr,
NULL, 0, instance->c_seq, 0, TCP_SYN_FLAG); instance->ethdev, instance->target, tid,NULL, 0, instance->c_seq, 0, TCP_SYN_FLAG);
tcp_send_to_target(instance->s_c_addr, instance->ethdev, instance->target, tid, tcp_send_to_target(instance->s_c_addr, &instance->s_ether_addr, &instance->c_ether_addr,
NULL, 0, instance->s_seq, instance->c_seq + 1, TCP_SYN_FLAG | TCP_ACK_FLAG); instance->ethdev, instance->target, tid,NULL, 0, instance->s_seq,
instance->c_seq + 1, TCP_SYN_FLAG | TCP_ACK_FLAG);
tcp_send_to_target(instance->c_s_addr, instance->ethdev, instance->target, tid, tcp_send_to_target(instance->c_s_addr, &instance->c_ether_addr, &instance->s_ether_addr,
NULL, 0, instance->c_seq + 1, instance->s_seq + 1, TCP_ACK_FLAG); instance->ethdev, instance->target, tid,NULL, 0, instance->c_seq + 1,
instance->s_seq + 1, TCP_ACK_FLAG);
instance->s_seq++; instance->s_seq++;
instance->c_seq++; instance->c_seq++;
@@ -410,14 +429,14 @@ void traffic_mirror_rebuild_data(struct traffic_mirror_rebuild * instance, unsig
if (dir == CONN_DIR_DOWNSTREAM) if (dir == CONN_DIR_DOWNSTREAM)
{ {
tcp_send_to_target(instance->c_s_addr, instance->ethdev, instance->target, tid, tcp_send_to_target(instance->c_s_addr, &instance->c_ether_addr, &instance->s_ether_addr,
data, datalen, instance->c_seq, instance->s_seq, TCP_ACK_FLAG); instance->ethdev, instance->target, tid, data, datalen, instance->c_seq, instance->s_seq, TCP_ACK_FLAG);
instance->c_seq += datalen; instance->c_seq += datalen;
} }
else else
{ {
tcp_send_to_target(instance->s_c_addr, instance->ethdev, instance->target, tid, tcp_send_to_target(instance->s_c_addr, &instance->s_ether_addr, &instance->c_ether_addr, instance->ethdev,
data, datalen, instance->s_seq, instance->c_seq, TCP_ACK_FLAG); instance->target, tid, data, datalen, instance->s_seq, instance->c_seq, TCP_ACK_FLAG);
instance->s_seq += datalen; instance->s_seq += datalen;
} }
} }
@@ -425,21 +444,21 @@ void traffic_mirror_rebuild_data(struct traffic_mirror_rebuild * instance, unsig
void traffic_mirror_rebuild_farewell(struct traffic_mirror_rebuild * instance, unsigned int tid) void traffic_mirror_rebuild_farewell(struct traffic_mirror_rebuild * instance, unsigned int tid)
{ {
/* C->S FIN */ /* C->S FIN */
tcp_send_to_target(instance->c_s_addr, instance->ethdev, instance->target, tid, tcp_send_to_target(instance->c_s_addr, &instance->c_ether_addr, &instance->s_ether_addr, instance->ethdev, instance->target, tid,
NULL, 0, instance->c_seq, instance->s_seq, TCP_FIN_FLAG | TCP_ACK_FLAG); NULL, 0, instance->c_seq, instance->s_seq, TCP_FIN_FLAG | TCP_ACK_FLAG);
/* C->S FIN, ACK */ /* C->S FIN, ACK */
tcp_send_to_target(instance->s_c_addr, instance->ethdev, instance->target, tid, tcp_send_to_target(instance->s_c_addr, &instance->s_ether_addr, &instance->c_ether_addr, instance->ethdev, instance->target, tid,
NULL, 0, instance->s_seq, instance->c_seq + 1, TCP_ACK_FLAG); NULL, 0, instance->s_seq, instance->c_seq + 1, TCP_ACK_FLAG);
instance->c_seq += 1; instance->c_seq += 1;
/* S->C FIN */ /* S->C FIN */
tcp_send_to_target(instance->s_c_addr, instance->ethdev, instance->target, tid, tcp_send_to_target(instance->s_c_addr, &instance->s_ether_addr, &instance->c_ether_addr, instance->ethdev, instance->target, tid,
NULL, 0, instance->s_seq, instance->c_seq, TCP_FIN_FLAG | TCP_ACK_FLAG); NULL, 0, instance->s_seq, instance->c_seq, TCP_FIN_FLAG | TCP_ACK_FLAG);
/* C->S FIN, ACK */ /* C->S FIN, ACK */
tcp_send_to_target(instance->c_s_addr, instance->ethdev, instance->target, tid, tcp_send_to_target(instance->c_s_addr, &instance->c_ether_addr, &instance->s_ether_addr, instance->ethdev, instance->target, tid,
NULL, 0, instance->c_seq, instance->s_seq + 1, TCP_ACK_FLAG); NULL, 0, instance->c_seq, instance->s_seq + 1, TCP_ACK_FLAG);
instance->s_seq += 1; instance->s_seq += 1;