diff --git a/plugin/business/traffic-mirror/include/traffic_mirror.h b/plugin/business/traffic-mirror/include/traffic_mirror.h index 2cb68e4..b91196b 100644 --- a/plugin/business/traffic-mirror/include/traffic_mirror.h +++ b/plugin/business/traffic-mirror/include/traffic_mirror.h @@ -29,6 +29,8 @@ struct traffic_mirror_instance /* DEFAULT MAC ADDRESS, IN VLAN MODE */ char default_ether_addr_src; char default_ether_addr_dst; + + struct traffic_mirror_ethdev * ethdev; }; struct policy_table_ex_data diff --git a/plugin/business/traffic-mirror/src/entry.cpp b/plugin/business/traffic-mirror/src/entry.cpp index 23a2f61..23fa24a 100644 --- a/plugin/business/traffic-mirror/src/entry.cpp +++ b/plugin/business/traffic-mirror/src/entry.cpp @@ -24,14 +24,14 @@ void policy_table_ex_data_free(struct policy_table_ex_data * object) void policy_table_ex_data_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA * to, MAAT_PLUGIN_EX_DATA * from, long argl, void * argp) { - struct policy_table_ex_data * ex_data = (struct policy_table_ex_data *)from; + struct policy_table_ex_data * ex_data = (struct policy_table_ex_data *)*from; __sync_add_and_fetch(&ex_data->atomic_refcnt, 1); *to = (void *)ex_data; } void policy_table_ex_data_free_cb(int table_id, MAAT_PLUGIN_EX_DATA * ad, long argl, void * argp) { - struct policy_table_ex_data * ex_data = (struct policy_table_ex_data *)argp; + struct policy_table_ex_data * ex_data = (struct policy_table_ex_data *)*ad; policy_table_ex_data_free(ex_data); } @@ -100,19 +100,18 @@ void policy_table_ex_data_new_cb(int table_id, const char * key, const char * ta goto ignore; } + ex_data->profile_id = json_item->valueint; + success: - TFE_LOG_DEBUG(instance->logger, "table line in PXY_INTERCEPT_COMPILE added: %s", table_line); + TFE_LOG_DEBUG(instance->logger, "traffic mirror policy, key %s: enable = %d, profile = %d", + key, ex_data->enable, ex_data->profile_id); + *ad = ex_data; - - fprintf(stderr, "---- ex_data = %p, atomic_refcnt = %d, enable = %d, profile_id = %d\n", - ex_data, ex_data->atomic_refcnt, ex_data->profile_id); - ex_data = nullptr; goto out; ignore: - TFE_LOG_ERROR(instance->logger, "table line in PXY_INTERCEPT_COMPILE ignored: %s", table_line); - *ad = nullptr; + TFE_LOG_ERROR(instance->logger, "table line in PXY_INTERCEPT_COMPILE ignored %s: %s", key, table_line); goto out; out: @@ -129,14 +128,14 @@ void profile_table_ex_data_free(struct profile_table_ex_data * object) void profile_table_ex_data_dup_cb(int table_id, MAAT_PLUGIN_EX_DATA * to, MAAT_PLUGIN_EX_DATA * from, long argl, void * argp) { - struct profile_table_ex_data * ex_data = (struct profile_table_ex_data *)from; + struct profile_table_ex_data * ex_data = (struct profile_table_ex_data *)*from; __sync_add_and_fetch(&ex_data->atomic_refcnt, 1); *to = (void *)ex_data; } void profile_table_ex_data_free_cb(int table_id, MAAT_PLUGIN_EX_DATA * ad, long argl, void * argp) { - struct profile_table_ex_data * ex_data = (struct profile_table_ex_data *)ad; + struct profile_table_ex_data * ex_data = (struct profile_table_ex_data *)*ad; profile_table_ex_data_free(ex_data); } @@ -263,12 +262,11 @@ success: *ad = (void *)ex_data; ex_data = nullptr; - TFE_LOG_DEBUG(instance->logger, "table line in PXY_PROFILE_TRAFFIC_MIRROR added: %s", table_line); + TFE_LOG_DEBUG(instance->logger, "traffic mirror profile %s: %s", key, str_json); goto out; ignore: - TFE_LOG_ERROR(instance->logger, "table line in PXY_PROFILE_TRAFFIC_MIRROR ignored: %s", table_line); - *ad = nullptr; + TFE_LOG_ERROR(instance->logger, "table line in PXY_PROFILE_TRAFFIC_MIRROR ignored %s: %s", key, table_line); goto out; out: @@ -396,6 +394,31 @@ error_out: return NULL; } +static int traffic_mirror_ethdev_init(struct traffic_mirror_instance * instance) +{ + char str_ethdev[TFE_SYMBOL_MAX] = {0}; + const char * profile = "./conf/tfe/tfe.conf"; + + int ret = MESA_load_profile_string_nodef(profile, "traffic_mirror", "device", + str_ethdev, sizeof(str_ethdev)); + + if (ret < 0) + { + TFE_LOG_ERROR(instance->logger, "failed at reading conffile, " + "[traffic_mirror]device is not defined."); + return -1; + } + + instance->ethdev = traffic_mirror_ethdev_pcap_create(str_ethdev, instance->logger); + if (!instance->ethdev) + { + TFE_LOG_ERROR(instance->logger, "failed at traffic mirror device init "); + return -2; + } + + return 0; +} + int traffic_mirror_init(struct tfe_proxy * proxy) { int result = 0; @@ -455,6 +478,11 @@ int traffic_mirror_init(struct tfe_proxy * proxy) "table_id = %d, ret = %d", instance->policy_table_id, result); } + if (traffic_mirror_ethdev_init(instance) < 0) + { + goto errout; + } + errout: return 0; } @@ -490,8 +518,6 @@ int traffic_mirror_on_open_cb(const struct tfe_stream * stream, unsigned int thr policy_ex_data = (struct policy_table_ex_data *)Maat_plugin_get_EX_data(instance->maat_feather, instance->policy_table_id, str_policy_id); - fprintf(stderr, "--- policy lookup, str_policy_id = %s, opt_val = %u\n", str_policy_id, opt_val); - if (!policy_ex_data) { TFE_LOG_ERROR(instance->logger, "failed at getting policy %s's EXDATA, detach the stream", str_policy_id); @@ -516,7 +542,7 @@ int traffic_mirror_on_open_cb(const struct tfe_stream * stream, unsigned int thr me = ALLOC(struct traffic_mirror_me, 1); - me->rebuild_ctx = traffic_mirror_rebuild_create(stream->addr, profile_ex_data, NULL); + me->rebuild_ctx = traffic_mirror_rebuild_create(stream->addr, profile_ex_data, instance->ethdev); me->profile_ex_data = profile_ex_data; /* profile_ex_data's ownership is transfer to me */ diff --git a/plugin/business/traffic-mirror/src/rebuild.cpp b/plugin/business/traffic-mirror/src/rebuild.cpp index 618f731..ada2a22 100644 --- a/plugin/business/traffic-mirror/src/rebuild.cpp +++ b/plugin/business/traffic-mirror/src/rebuild.cpp @@ -153,19 +153,24 @@ static void l2_send_to_target(struct traffic_mirror_ethdev * ethdev, { assert(l3_data_offset >= (sizeof(struct ethhdr) + sizeof(struct vlan_hdr))); unsigned int header_offset = l3_data_offset; + unsigned int header_len = 0; /* need to construct vlan header */ if (vlan_tci > 0) { header_offset -= sizeof(struct vlan_hdr); + header_len += sizeof(struct vlan_hdr); 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); + header_len += sizeof(struct ethhdr); ether_header_construct(snd_buffer + header_offset, (unsigned char *)target_addr->ether_addr_octet, (unsigned char *)ethdev->local_ether_addr, eth_protocol); + + traffic_mirror_ethdev_inject(ethdev, (char *)snd_buffer + header_offset, header_len + l3_data_len); } static void l2_send_to_target_group(struct traffic_mirror_ethdev * ethdev, struct profile_table_ex_data * t_group, @@ -183,19 +188,24 @@ static void tcp_segment_send_to_target_group(struct tfe_stream_addr * addr, stru unsigned int seq, unsigned int ack, char flags) { char pkt[ETHER_MAX_LEN]; - unsigned sz_pkt_prepend = sizeof(struct ethhdr) + sizeof(struct iphdr) + sizeof(struct tcphdr); + unsigned sz_pkt_prepend = sizeof(struct ethhdr) + sizeof(struct vlan_hdr) + sizeof(struct iphdr) + sizeof(struct tcphdr); unsigned l3_l4_header_len = 0; + unsigned header_len = 0; - l3_l4_header_len += tcp_header_construct_by_stream_addr(addr, + header_len = tcp_header_construct_by_stream_addr(addr, (unsigned char *)pkt + sz_pkt_prepend, seq, ack, flags, 0xffff, 0); - l3_l4_header_len += ip_header_construct_by_stream_addr(addr, (unsigned char *)pkt + sz_pkt_prepend, + sz_pkt_prepend -= header_len; + l3_l4_header_len += header_len; + + header_len = ip_header_construct_by_stream_addr(addr, (unsigned char *)pkt + sz_pkt_prepend, sizeof(struct tcphdr) + payload_len, 0, 0x1000, 0, 128, IPPROTO_TCP); - sz_pkt_prepend -= l3_l4_header_len; + sz_pkt_prepend -= header_len; + l3_l4_header_len += header_len; - l2_send_to_target_group(ethdev, t_group, (unsigned char *)pkt, - sz_pkt_prepend, l3_l4_header_len + payload_len, ETHERTYPE_IP); + l2_send_to_target_group(ethdev, t_group, (unsigned char *)pkt, sz_pkt_prepend, + l3_l4_header_len + payload_len, ETHERTYPE_IP); } static void tcp_send_to_target_group(struct tfe_stream_addr * addr, struct traffic_mirror_ethdev * ethdev, @@ -205,7 +215,7 @@ static void tcp_send_to_target_group(struct tfe_stream_addr * addr, struct traff unsigned int payload_offset = 0; unsigned mss = ethdev->mtu - (sizeof(struct iphdr) + sizeof(struct tcphdr)); - while(payload_offset < payload_len) + while(payload_offset <= payload_len) { unsigned int payload_sz_seg = MIN(payload_offset, mss); const char * payload_ptr_seg = payload + payload_offset; @@ -213,6 +223,8 @@ static void tcp_send_to_target_group(struct tfe_stream_addr * addr, struct traff 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; + + if (payload_sz_seg == 0) break; } } @@ -220,6 +232,7 @@ struct traffic_mirror_rebuild * traffic_mirror_rebuild_create(struct tfe_stream_ struct profile_table_ex_data * target, struct traffic_mirror_ethdev * ethdev) { struct traffic_mirror_rebuild * instance = ALLOC(struct traffic_mirror_rebuild, 1); + instance->addr = addr; instance->target = target; instance->ethdev = ethdev;