TFE Packet IO支持带封装报文格式

This commit is contained in:
wangmenglan
2023-05-26 18:50:18 +08:00
parent f00ef65963
commit 4d26281338
14 changed files with 1577 additions and 156 deletions

View File

@@ -31,7 +31,7 @@
#include "bpf_obj.h"
#include "tfe_session_table.h"
#include "tfe_packet_io.h"
#include "tfe_fieldstat.h"
/******************************************************************************
@@ -40,6 +40,10 @@
#define RX_BURST_MAX 128
#define IS_SINGLE 0x01
#define IS_TUNNEL 0x02
#define TRAFFIC_IS_DECRYPTED (1 << 0)
#define SET_TRAFFIC_IS_DECRYPTED(field) (field | TRAFFIC_IS_DECRYPTED)
#define CLEAR_TRAFFIC_IS_DECRYPTED(field) (field & ~TRAFFIC_IS_DECRYPTED)
@@ -198,7 +202,6 @@ static int tap_write(int tap_fd, const char *data, int data_len, void *logger)
static struct metadata *metadata_new()
{
struct metadata *meta = (struct metadata *)calloc(1, sizeof(struct metadata));
return meta;
}
@@ -275,6 +278,16 @@ static void session_ctx_free(struct session_ctx *ctx)
ctx->ctrl_meta = NULL;
}
if (ctx->c2s_info.header_data) {
free(ctx->c2s_info.header_data);
ctx->c2s_info.header_data = NULL;
}
if (ctx->s2c_info.header_data) {
free(ctx->s2c_info.header_data);
ctx->s2c_info.header_data = NULL;
}
free(ctx);
ctx = NULL;
}
@@ -293,6 +306,12 @@ static int add_ether_header(void *raw_data, char *src_mac, char *dst_mac){
return 0;
}
static int add_ether_proto(void *raw_data, uint16_t proto){
struct ethhdr *ether_hdr = (struct ethhdr*)raw_data;
ether_hdr->h_proto = htons(proto); // ETH_P_IP
return 0;
}
static int fake_tcp_handshake(struct tfe_proxy *proxy, struct tcp_restore_info *restore_info)
{
char buffer[1500] = {0};
@@ -962,9 +981,9 @@ static int packet_io_set_metadata(marsio_buff_t *tx_buff, struct metadata *meta,
return 0;
}
static void packet_io_dump_metadata(marsio_buff_t *tx_buff, struct metadata *meta, void *logger)
static void packet_io_dump_metadata(struct metadata *meta, void *logger)
{
TFE_LOG_DEBUG(logger, "%s: META={session_id: %lu, raw_len: %d, is_e2i_dir: %d, is_ctrl_pkt: %d, l7offset: %d, is_decrypted: %u, sids_num: %d}", LOG_TAG_PKTIO, meta->session_id, meta->raw_len, meta->is_e2i_dir, meta->is_ctrl_pkt, meta->l7offset, meta->is_decrypted, meta->sids.num);
TFE_LOG_ERROR(logger, "%s: META={session_id: %lu, raw_len: %d, is_e2i_dir: %d, is_ctrl_pkt: %d, l7offset: %d, is_decrypted: %u, sids_num: %d}", LOG_TAG_PKTIO, meta->session_id, meta->raw_len, meta->is_e2i_dir, meta->is_ctrl_pkt, meta->l7offset, meta->is_decrypted, meta->sids.num);
}
/*
@@ -1154,15 +1173,32 @@ static void tcp_restore_info_dump(struct tcp_restore_info *info, uint64_t sessio
}
}
static void set_passthrough_reason(struct tfe_cmsg *cmsg, char *reason)
{
uint8_t ssl_intercept_status = SSL_ACTION_PASSTHROUGH;
tfe_cmsg_set(cmsg, TFE_CMSG_SSL_PASSTHROUGH_REASON, (const unsigned char *)&reason, strlen(reason));
tfe_cmsg_set(cmsg, TFE_CMSG_SSL_INTERCEPT_STATE, (const unsigned char *)&ssl_intercept_status, (uint16_t)sizeof(ssl_intercept_status));
tfe_cmsg_set_flag(cmsg, TFE_CMSG_FLAG_USER0);
}
// return 0 : success
// return -1 : error
static int handle_session_opening(struct metadata *meta, struct ctrl_pkt_parser *parser, int thread_seq, void *ctx)
{
int ret = 0;
int fd_downstream = 0;
int fd_upstream = 0;
int fd_fake_c = 0;
int fd_fake_s = 0;
uint16_t size = 0;
uint8_t is_passthrough = 0;
uint8_t hit_no_intercept = 0;
uint16_t out_size = 0;
char reason_hit_no_intercept[] = "Hit No Intercept";
char reason_invalid_intercept_param[] = "Invalid Intercept Param";
char reason_invalid_tcp_policy_param[] = "Invalid tcp policy Param";
char reason_underlying_stream_error[] = "Underlying Stream Error";
unsigned int stream_common_direction;
uint8_t stream_protocol_in_char = 0;
@@ -1187,81 +1223,118 @@ static int handle_session_opening(struct metadata *meta, struct ctrl_pkt_parser
uint16_t offset = (char *)payload - meta->raw_data;
TFE_LOG_ERROR(logger, "%s: incorrect dataoffset in the control zone of session %lu, offset:%u, l7offset:%u, payload:%p, raw_data:%p", LOG_TAG_PKTIO, meta->session_id, offset, meta->l7offset, payload, meta->raw_data);
}
raw_packet_parser_get_most_inner_tuple4(&raw_parser, &inner_tuple4, logger);
intercept_policy_enforce(thread->ref_proxy->int_ply_enforcer, parser->cmsg);
tcp_policy_enforce(thread->ref_proxy->tcp_ply_enforcer, parser->cmsg);
for (int i = 0; i < parser->sce_policy_id_num; i++) {
chaining_policy_enforce(thread->ref_proxy->chain_ply_enforcer, parser->cmsg, parser->sce_policy_ids[i]);
if (parser->intercpet_data == 0) {
ret = intercept_policy_enforce(thread->ref_proxy->int_ply_enforcer, parser->cmsg);
if (ret != 0) {
is_passthrough = 1;
set_passthrough_reason(parser->cmsg, reason_invalid_intercept_param);
goto passthrough;
}
tfe_cmsg_get_value(parser->cmsg, TFE_CMSG_HIT_NO_INTERCEPT, (unsigned char *)&hit_no_intercept, sizeof(hit_no_intercept), &out_size);
if (hit_no_intercept == 1) {
is_passthrough = 1;
set_passthrough_reason(parser->cmsg, reason_hit_no_intercept);
goto passthrough;
}
ret = tcp_policy_enforce(thread->ref_proxy->tcp_ply_enforcer, parser->cmsg);
if (ret != 0) {
is_passthrough = 1;
set_passthrough_reason(parser->cmsg, reason_invalid_tcp_policy_param);
goto passthrough;
}
for (int i = 0; i < parser->sce_policy_id_num; i++) {
chaining_policy_enforce(thread->ref_proxy->chain_ply_enforcer, parser->cmsg, parser->sce_policy_ids[i]);
}
tcp_restore_set_from_cmsg(parser->cmsg, &restore_info);
tcp_restore_set_from_pkg(&inner_tuple4, &restore_info);
if (overwrite_tcp_mss(parser->cmsg, &restore_info, meta->session_id, logger)) {
is_passthrough = 1;
set_passthrough_reason(parser->cmsg, reason_invalid_tcp_policy_param);
goto passthrough;
}
tcp_restore_info_dump(&restore_info, meta->session_id, logger);
// tcp repair C2S
fd_upstream = tfe_tcp_restore_fd_create(&(restore_info.client), &(restore_info.server), packet_io->config.dev_tap, 0x65);
if (fd_upstream < 0) {
TFE_LOG_ERROR(logger, "%s: session %lu Failed at tcp_restore_fd_create(UPSTREAM)", LOG_TAG_PKTIO, meta->session_id);
is_passthrough = 1;
set_passthrough_reason(parser->cmsg, reason_invalid_tcp_policy_param);
goto passthrough;
}
// tcp repair S2C
fd_downstream = tfe_tcp_restore_fd_create(&(restore_info.server), &(restore_info.client), packet_io->config.dev_tap, 0x65);
if (fd_downstream < 0)
{
TFE_LOG_ERROR(logger, "%s: session %lu Failed at tcp_restore_fd_create(DOWNSTREAM)", LOG_TAG_PKTIO, meta->session_id);
is_passthrough = 1;
set_passthrough_reason(parser->cmsg, reason_invalid_tcp_policy_param);
goto passthrough;
}
tfe_cmsg_get_value(parser->cmsg, TFE_CMSG_TCP_RESTORE_PROTOCOL, (unsigned char *)&stream_protocol_in_char, sizeof(stream_protocol_in_char), &size);
tfe_cmsg_get_value(parser->cmsg, TFE_CMSG_TCP_DECRYPTED_TRAFFIC_STEERING, (unsigned char *)&enable_decrypted_traffic_steering, sizeof(enable_decrypted_traffic_steering), &size);
if ((STREAM_PROTO_PLAIN == (enum tfe_stream_proto)stream_protocol_in_char && thread->ref_proxy->traffic_steering_options.enable_steering_http) ||
(STREAM_PROTO_SSL == (enum tfe_stream_proto)stream_protocol_in_char && thread->ref_proxy->traffic_steering_options.enable_steering_ssl) ||
enable_decrypted_traffic_steering == 1)
{
if (fake_tcp_handshake(thread->ref_proxy, &restore_info) == -1)
{
TFE_LOG_ERROR(logger, "%s: session %lu Failed at fake_tcp_handshake()", LOG_TAG_PKTIO, meta->session_id);
is_passthrough = 1;
set_passthrough_reason(parser->cmsg, reason_invalid_tcp_policy_param);
goto passthrough;
}
fd_fake_c = tfe_tcp_restore_fd_create(&(restore_info.client), &(restore_info.server), thread->ref_proxy->traffic_steering_options.device_client, thread->ref_proxy->traffic_steering_options.so_mask_client);
if (fd_fake_c < 0)
{
TFE_LOG_ERROR(logger, "%s: session %lu Failed at tcp_restore_fd_create(fd_fake_c)", LOG_TAG_PKTIO, meta->session_id);
is_passthrough = 1;
set_passthrough_reason(parser->cmsg, reason_invalid_tcp_policy_param);
goto passthrough;
}
fd_fake_s = tfe_tcp_restore_fd_create(&(restore_info.server), &(restore_info.client), thread->ref_proxy->traffic_steering_options.device_server, thread->ref_proxy->traffic_steering_options.so_mask_server);
if (fd_fake_s < 0)
{
TFE_LOG_ERROR(logger, "%s: session %lu Failed at tcp_restore_fd_create(fd_fake_s)", LOG_TAG_PKTIO, meta->session_id);
is_passthrough = 1;
set_passthrough_reason(parser->cmsg, reason_invalid_tcp_policy_param);
goto passthrough;
}
}
if (tfe_proxy_fds_accept(thread->ref_proxy, fd_downstream, fd_upstream, fd_fake_c, fd_fake_s, parser->cmsg) < 0)
{
TFE_LOG_ERROR(logger, "%s: session %lu Failed at tfe_proxy_fds_accept()", LOG_TAG_PKTIO, meta->session_id);
is_passthrough = 1;
set_passthrough_reason(parser->cmsg, reason_invalid_tcp_policy_param);
goto passthrough;
}
// E -> I
if (meta->is_e2i_dir)
stream_common_direction = 'I';
// I -> E
else
stream_common_direction = 'E';
tfe_cmsg_set(parser->cmsg, TFE_CMSG_COMMON_DIRECTION, (const unsigned char *)&stream_common_direction, sizeof(stream_common_direction));
}
else if (parser->intercpet_data & (IS_SINGLE | IS_TUNNEL)) {
is_passthrough = 1;
set_passthrough_reason(parser->cmsg, reason_underlying_stream_error);
}
tcp_restore_set_from_cmsg(parser->cmsg, &restore_info);
tcp_restore_set_from_pkg(&inner_tuple4, &restore_info);
if (overwrite_tcp_mss(parser->cmsg, &restore_info, meta->session_id, logger))
{
goto end;
}
tcp_restore_info_dump(&restore_info, meta->session_id, logger);
// tcp repair C2S
fd_upstream = tfe_tcp_restore_fd_create(&(restore_info.client), &(restore_info.server), packet_io->config.dev_tap, 0x65);
if (fd_upstream < 0)
{
TFE_LOG_ERROR(logger, "%s: session %lu Failed at tcp_restore_fd_create(UPSTREAM)", LOG_TAG_PKTIO, meta->session_id);
goto end;
}
// tcp repair S2C
fd_downstream = tfe_tcp_restore_fd_create(&(restore_info.server), &(restore_info.client), packet_io->config.dev_tap, 0x65);
if (fd_downstream < 0)
{
TFE_LOG_ERROR(logger, "%s: session %lu Failed at tcp_restore_fd_create(DOWNSTREAM)", LOG_TAG_PKTIO, meta->session_id);
goto end;
}
tfe_cmsg_get_value(parser->cmsg, TFE_CMSG_TCP_RESTORE_PROTOCOL, (unsigned char *)&stream_protocol_in_char, sizeof(stream_protocol_in_char), &size);
tfe_cmsg_get_value(parser->cmsg, TFE_CMSG_TCP_DECRYPTED_TRAFFIC_STEERING, (unsigned char *)&enable_decrypted_traffic_steering, sizeof(enable_decrypted_traffic_steering), &size);
if ((STREAM_PROTO_PLAIN == (enum tfe_stream_proto)stream_protocol_in_char && thread->ref_proxy->traffic_steering_options.enable_steering_http) ||
(STREAM_PROTO_SSL == (enum tfe_stream_proto)stream_protocol_in_char && thread->ref_proxy->traffic_steering_options.enable_steering_ssl) ||
enable_decrypted_traffic_steering == 1)
{
if (fake_tcp_handshake(thread->ref_proxy, &restore_info) == -1)
{
TFE_LOG_ERROR(logger, "%s: session %lu Failed at fake_tcp_handshake()", LOG_TAG_PKTIO, meta->session_id);
goto end;
}
fd_fake_c = tfe_tcp_restore_fd_create(&(restore_info.client), &(restore_info.server), thread->ref_proxy->traffic_steering_options.device_client, thread->ref_proxy->traffic_steering_options.so_mask_client);
if (fd_fake_c < 0)
{
TFE_LOG_ERROR(logger, "%s: session %lu Failed at tcp_restore_fd_create(fd_fake_c)", LOG_TAG_PKTIO, meta->session_id);
goto end;
}
fd_fake_s = tfe_tcp_restore_fd_create(&(restore_info.server), &(restore_info.client), thread->ref_proxy->traffic_steering_options.device_server, thread->ref_proxy->traffic_steering_options.so_mask_server);
if (fd_fake_s < 0)
{
TFE_LOG_ERROR(logger, "%s: session %lu Failed at tcp_restore_fd_create(fd_fake_s)", LOG_TAG_PKTIO, meta->session_id);
goto end;
}
}
if (tfe_proxy_fds_accept(thread->ref_proxy, fd_downstream, fd_upstream, fd_fake_c, fd_fake_s, parser->cmsg) < 0)
{
TFE_LOG_ERROR(logger, "%s: session %lu Failed at tfe_proxy_fds_accept()", LOG_TAG_PKTIO, meta->session_id);
goto end;
}
// E -> I
if (meta->is_e2i_dir)
stream_common_direction = 'I';
// I -> E
else
stream_common_direction = 'E';
tfe_cmsg_set(parser->cmsg, TFE_CMSG_COMMON_DIRECTION, (const unsigned char *)&stream_common_direction, sizeof(stream_common_direction));
passthrough:
s_ctx = session_ctx_new();
s_ctx->raw_meta_i2e = metadata_new();
s_ctx->raw_meta_e2i = metadata_new();
@@ -1271,6 +1344,7 @@ static int handle_session_opening(struct metadata *meta, struct ctrl_pkt_parser
s_ctx->session_id = meta->session_id;
s_ctx->session_addr = addr_tuple4_to_str(&inner_tuple4);
s_ctx->cmsg = parser->cmsg;
s_ctx->is_passthrough = is_passthrough;
metadata_deep_copy(s_ctx->ctrl_meta, meta);
ether_hdr = (struct ethhdr *)(s_ctx->ctrl_meta->raw_data);
@@ -1289,6 +1363,12 @@ static int handle_session_opening(struct metadata *meta, struct ctrl_pkt_parser
sids_copy(&s_ctx->ctrl_meta->sids, &meta->sids);
route_ctx_copy(&s_ctx->ctrl_meta->route_ctx, &meta->route_ctx);
if (parser->seq_len > 0)
raw_traffic_decapsulate(&raw_parser, parser->seq_header, parser->seq_len, &s_ctx->c2s_info.header_data, &s_ctx->c2s_info.header_len, &s_ctx->c2s_info.is_ipv4);
if (parser->ack_len > 0)
raw_traffic_decapsulate(&raw_parser, parser->ack_header, parser->ack_len, &s_ctx->s2c_info.header_data, &s_ctx->s2c_info.header_len, &s_ctx->s2c_info.is_ipv4);
if (s_ctx->c2s_info.is_e2i_dir) {
sids_copy(&s_ctx->raw_meta_e2i->sids, &parser->seq_sids);
route_ctx_copy(&s_ctx->raw_meta_e2i->route_ctx, &parser->seq_route_ctx);
@@ -1307,10 +1387,12 @@ static int handle_session_opening(struct metadata *meta, struct ctrl_pkt_parser
session_table_insert(thread->session_table, s_ctx->session_id, &(s_ctx->c2s_info.tuple4), s_ctx, session_value_free_cb);
ATOMIC_INC(&(packet_io_fs->session_num));
tfe_cmsg_dup(parser->cmsg);
if (parser->seq_header)
FREE(&parser->seq_header);
if (parser->ack_header)
FREE(&parser->ack_header);
return 0;
end:
ctrl_packet_cmsg_destroy(parser);
return -1;
}
// return 0 : success
@@ -1343,6 +1425,7 @@ static int handle_session_closing(struct metadata *meta, struct ctrl_pkt_parser
TFE_LOG_INFO(logger, "%s: session %lu closing", LOG_TAG_PKTIO, s_ctx->session_id);
session_table_delete_by_id(thread->session_table, meta->session_id);
ATOMIC_DEC(&(packet_io_fs->session_num));
tfe_set_intercept_metric(s_ctx->cmsg, 1, s_ctx->c2s_info.rx.n_pkts, s_ctx->c2s_info.rx.n_bytes, s_ctx->s2c_info.rx.n_pkts, s_ctx->s2c_info.rx.n_bytes, thread_seq);
return 0;
}
@@ -1429,14 +1512,16 @@ static int handle_raw_packet_from_nf(struct packet_io *handle, marsio_buff_t *rx
struct packet_io_thread_ctx *thread = (struct packet_io_thread_ctx *)ctx;
struct packet_io *packet_io = thread->ref_io;
struct packet_io_fs *packet_io_fs = thread->ret_fs_state;
int is_ipv4 = 0;
char *header = NULL;
int header_len = 0;
void * logger = thread->logger;
int raw_len = marsio_buff_datalen(rx_buff);
char *raw_data = marsio_buff_mtod(rx_buff);
struct metadata meta;
if (packet_io_get_metadata(rx_buff, &meta, logger) == -1)
{
if (packet_io_get_metadata(rx_buff, &meta, logger) == -1) {
TFE_LOG_ERROR(logger, "%s: unexpected control packet, unable to get metadata\n\tMETA={session_id: %lu, raw_len: %d, is_e2i_dir: %d, is_ctrl_pkt: %d, l7offset: %d, is_decrypted: %u, sids_num: %d}",
LOG_TAG_PKTIO, meta.session_id, meta.raw_len, meta.is_e2i_dir, meta.is_ctrl_pkt, meta.l7offset, meta.is_decrypted, meta.sids.num);
throughput_metrics_inc(&packet_io_fs->raw_pkt_rx, 1, raw_len);
@@ -1446,8 +1531,7 @@ static int handle_raw_packet_from_nf(struct packet_io *handle, marsio_buff_t *rx
}
struct session_node *node = session_table_search_by_id(thread->session_table, meta.session_id);
if (node == NULL)
{
if (node == NULL) {
throughput_metrics_inc(&packet_io_fs->raw_pkt_rx, 1, raw_len);
throughput_metrics_inc(&packet_io_fs->raw_bypass, 1, raw_len);
marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1);
@@ -1456,6 +1540,17 @@ static int handle_raw_packet_from_nf(struct packet_io *handle, marsio_buff_t *rx
struct session_ctx *s_ctx = (struct session_ctx *)node->val_data;
if (s_ctx->is_passthrough > 0) {
throughput_metrics_inc(&packet_io_fs->raw_pkt_rx, 1, raw_len);
throughput_metrics_inc(&packet_io_fs->raw_bypass, 1, raw_len);
if (meta.is_e2i_dir == s_ctx->c2s_info.is_e2i_dir)
throughput_metrics_inc(&s_ctx->c2s_info.rx, 1, raw_len);
else
throughput_metrics_inc(&s_ctx->s2c_info.rx, 1, raw_len);
marsio_send_burst(handle->dev_nf_interface.mr_path, thread_seq, &rx_buff, 1);
return 0;
}
if (meta.is_decrypted)
{
throughput_metrics_inc(&packet_io_fs->decrypt_rx, 1, raw_len);
@@ -1485,31 +1580,64 @@ static int handle_raw_packet_from_nf(struct packet_io *handle, marsio_buff_t *rx
else
{
throughput_metrics_inc(&packet_io_fs->raw_pkt_rx, 1, raw_len);
if (meta.is_e2i_dir)
{
if (metadata_is_empty(s_ctx->raw_meta_e2i))
{
if (meta.is_e2i_dir) {
if (metadata_is_empty(s_ctx->raw_meta_e2i)) {
metadata_deep_copy(s_ctx->raw_meta_e2i, &meta);
}
s_ctx->raw_meta_e2i->sids = meta.sids;
}
else
{
if (metadata_is_empty(s_ctx->raw_meta_i2e))
{
else {
if (metadata_is_empty(s_ctx->raw_meta_i2e)) {
metadata_deep_copy(s_ctx->raw_meta_i2e, &meta);
}
s_ctx->raw_meta_i2e->sids = meta.sids;
}
// send to tap0
add_ether_header(raw_data, packet_io->config.src_mac, packet_io->config.tap_mac);
if (packet_io->config.enable_iouring) {
io_uring_submit_write_entry(thread->tap_ctx->io_uring_fd, raw_data, raw_len);
if (meta.is_e2i_dir == s_ctx->c2s_info.is_e2i_dir) {
header = s_ctx->c2s_info.header_data;
header_len = s_ctx->c2s_info.header_len;
is_ipv4 = s_ctx->c2s_info.is_ipv4;
throughput_metrics_inc(&s_ctx->c2s_info.rx, 1, raw_len);
}
else {
tap_write(thread->tap_ctx->tap_fd, raw_data, raw_len, logger);
header = s_ctx->s2c_info.header_data;
header_len = s_ctx->s2c_info.header_len;
is_ipv4 = s_ctx->s2c_info.is_ipv4;
throughput_metrics_inc(&s_ctx->s2c_info.rx, 1, raw_len);
}
if (header != NULL) {
char *packet_buff = NULL;
int packet_len = sizeof(struct ethhdr) + raw_len - header_len;
packet_buff = (char *)calloc(packet_len, sizeof(char));
memcpy(packet_buff + sizeof(struct ethhdr), raw_data + header_len, raw_len - header_len);
add_ether_header(packet_buff, packet_io->config.src_mac, packet_io->config.tap_mac);
if (is_ipv4)
add_ether_proto(packet_buff, ETH_P_IP);
else
add_ether_proto(packet_buff, ETH_P_IPV6);
if (packet_io->config.enable_iouring) {
io_uring_submit_write_entry(thread->tap_ctx->io_uring_fd, packet_buff, packet_len);
}
else {
tap_write(thread->tap_ctx->tap_fd, packet_buff, packet_len, logger);
}
throughput_metrics_inc(&packet_io_fs->tap_pkt_tx, 1, packet_len);
if (packet_buff)
free(packet_buff);
}
else {
// send to tap0
add_ether_header(raw_data, packet_io->config.src_mac, packet_io->config.tap_mac);
if (packet_io->config.enable_iouring) {
io_uring_submit_write_entry(thread->tap_ctx->io_uring_fd, raw_data, raw_len);
}
else {
tap_write(thread->tap_ctx->tap_fd, raw_data, raw_len, logger);
}
throughput_metrics_inc(&packet_io_fs->tap_pkt_tx, 1, raw_len);
}
throughput_metrics_inc(&packet_io_fs->tap_pkt_tx, 1, raw_len);
uint8_t flag = tfe_cmsg_get_flag(s_ctx->cmsg);
if (flag & TFE_CMSG_FLAG_USER0) {
@@ -1881,7 +2009,12 @@ void handle_raw_packet_from_tap(const char *data, int len, void *args)
struct packet_io_fs *packet_io_fs = thread->ret_fs_state;
struct addr_tuple4 inner_addr;
struct raw_pkt_parser raw_parser;
struct metadata meta = {0};
void * logger = thread->logger;
char *dst = NULL;
char *header = NULL;
int header_len = 0;
int packet_len = 0;
memset(&inner_addr, 0, sizeof(struct addr_tuple4));
raw_packet_parser_init(&raw_parser, 0, LAYER_TYPE_ALL, 8);
@@ -1906,28 +2039,21 @@ void handle_raw_packet_from_tap(const char *data, int len, void *args)
return;
}
char *dst = marsio_buff_append(tx_buffs[0], len);
memcpy(dst, data, len);
struct metadata meta = {0};
meta.session_id = s_ctx->session_id;
meta.raw_data = dst;
meta.raw_len = len;
meta.is_decrypted = 0;
meta.is_ctrl_pkt = 0;
meta.l7offset = 0;
if (memcmp(&inner_addr, &s_ctx->c2s_info.tuple4, sizeof(struct addr_tuple4)) == 0)
{
meta.is_e2i_dir = s_ctx->c2s_info.is_e2i_dir;
src_mac = s_ctx->client_mac;
dst_mac = s_ctx->server_mac;
header = s_ctx->c2s_info.header_data;
header_len = s_ctx->c2s_info.header_len;
}
else
{
meta.is_e2i_dir = s_ctx->s2c_info.is_e2i_dir;
src_mac = s_ctx->server_mac;
dst_mac = s_ctx->client_mac;
header = s_ctx->s2c_info.header_data;
header_len = s_ctx->s2c_info.header_len;
}
if (meta.is_e2i_dir)
@@ -1941,8 +2067,27 @@ void handle_raw_packet_from_tap(const char *data, int len, void *args)
route_ctx_copy(&meta.route_ctx, &s_ctx->raw_meta_i2e->route_ctx);
}
if (header != NULL) {
packet_len = len + header_len - sizeof(struct ethhdr);
dst = marsio_buff_append(tx_buffs[0], packet_len);
memcpy(dst, header, header_len);
memcpy(dst + header_len, data + sizeof(struct ethhdr), len - sizeof(struct ethhdr));
}
else {
packet_len = len;
dst = marsio_buff_append(tx_buffs[0], len);
memcpy(dst, data, len);
}
meta.session_id = s_ctx->session_id;
meta.raw_data = dst;
meta.raw_len = packet_len;
meta.is_decrypted = 0;
meta.is_ctrl_pkt = 0;
meta.l7offset = 0;
packet_io_set_metadata(tx_buffs[0], &meta, logger);
add_ether_header(dst, src_mac, dst_mac);
throughput_metrics_inc(&packet_io_fs->raw_pkt_tx, 1, len);
throughput_metrics_inc(&packet_io_fs->raw_pkt_tx, 1, packet_len);
marsio_send_burst(packet_io->dev_nf_interface.mr_path, thread->thread_index, tx_buffs, 1);
}