diff --git a/src/ip_reassembly/ip_reassembly.cpp b/src/ip_reassembly/ip_reassembly.cpp index 86c4e2a..20e66f9 100644 --- a/src/ip_reassembly/ip_reassembly.cpp +++ b/src/ip_reassembly/ip_reassembly.cpp @@ -729,7 +729,6 @@ static struct packet *ip_frag_reassemble(struct ip_reassembly *assy, struct ip_f // create a new packet packet_parse(pkt, ptr, packet_len); - packet_set_drop(pkt); return pkt; diff --git a/src/stellar/stat.cpp b/src/stellar/stat.cpp index 684d3f5..bd0c185 100644 --- a/src/stellar/stat.cpp +++ b/src/stellar/stat.cpp @@ -44,6 +44,31 @@ struct stat_id int ctrl_tx_pkts; int ctrl_tx_bytes; + // ip reassembly + int ip4_flow_find; + int ip4_flow_add; + int ip4_flow_del; + int ip4_flow_timeout; + + int ip4_flow_fail_no_space; + int ip4_flow_fail_overlap; + int ip4_flow_fail_many_frag; + int ip4_flow_fail_invalid_length; + int ip4_flow_bypass_dup_fist_frag; + int ip4_flow_bypass_dup_last_frag; + + int ip6_flow_find; + int ip6_flow_add; + int ip6_flow_del; + int ip6_flow_timeout; + + int ip6_flow_fail_no_space; + int ip6_flow_fail_overlap; + int ip6_flow_fail_many_frag; + int ip6_flow_fail_invalid_length; + int ip6_flow_bypass_dup_fist_frag; + int ip6_flow_bypass_dup_last_frag; + // TCP session int nr_tcp_sess_used; int nr_tcp_sess_opening; @@ -149,6 +174,27 @@ struct stellar_stat *stellar_stat_new(uint16_t nr_thread) stat->ids.ctrl_rx_bytes = fieldstat_easy_register_counter(stat->fs, "ctrl_rx_bytes"); stat->ids.ctrl_tx_pkts = fieldstat_easy_register_counter(stat->fs, "ctrl_tx_pkts"); stat->ids.ctrl_tx_bytes = fieldstat_easy_register_counter(stat->fs, "ctrl_tx_bytes"); + // ip reassembly + stat->ids.ip4_flow_find = fieldstat_easy_register_counter(stat->fs, "ip4_flow_find"); + stat->ids.ip4_flow_add = fieldstat_easy_register_counter(stat->fs, "ip4_flow_add"); + stat->ids.ip4_flow_del = fieldstat_easy_register_counter(stat->fs, "ip4_flow_del"); + stat->ids.ip4_flow_timeout = fieldstat_easy_register_counter(stat->fs, "ip4_flow_timeout"); + stat->ids.ip4_flow_fail_no_space = fieldstat_easy_register_counter(stat->fs, "ip4_flow_fail_no_space"); + stat->ids.ip4_flow_fail_overlap = fieldstat_easy_register_counter(stat->fs, "ip4_flow_fail_overlap"); + stat->ids.ip4_flow_fail_many_frag = fieldstat_easy_register_counter(stat->fs, "ip4_flow_fail_many_frag"); + stat->ids.ip4_flow_fail_invalid_length = fieldstat_easy_register_counter(stat->fs, "ip4_flow_fail_invalid_length"); + stat->ids.ip4_flow_bypass_dup_fist_frag = fieldstat_easy_register_counter(stat->fs, "ip4_flow_bypass_dup_fist_frag"); + stat->ids.ip4_flow_bypass_dup_last_frag = fieldstat_easy_register_counter(stat->fs, "ip4_flow_bypass_dup_last_frag"); + stat->ids.ip6_flow_find = fieldstat_easy_register_counter(stat->fs, "ip6_flow_find"); + stat->ids.ip6_flow_add = fieldstat_easy_register_counter(stat->fs, "ip6_flow_add"); + stat->ids.ip6_flow_del = fieldstat_easy_register_counter(stat->fs, "ip6_flow_del"); + stat->ids.ip6_flow_timeout = fieldstat_easy_register_counter(stat->fs, "ip6_flow_timeout"); + stat->ids.ip6_flow_fail_no_space = fieldstat_easy_register_counter(stat->fs, "ip6_flow_fail_no_space"); + stat->ids.ip6_flow_fail_overlap = fieldstat_easy_register_counter(stat->fs, "ip6_flow_fail_overlap"); + stat->ids.ip6_flow_fail_many_frag = fieldstat_easy_register_counter(stat->fs, "ip6_flow_fail_many_frag"); + stat->ids.ip6_flow_fail_invalid_length = fieldstat_easy_register_counter(stat->fs, "ip6_flow_fail_invalid_length"); + stat->ids.ip6_flow_bypass_dup_fist_frag = fieldstat_easy_register_counter(stat->fs, "ip6_flow_bypass_dup_fist_frag"); + stat->ids.ip6_flow_bypass_dup_last_frag = fieldstat_easy_register_counter(stat->fs, "ip6_flow_bypass_dup_last_frag"); // TCP session stat->ids.nr_tcp_sess_used = fieldstat_easy_register_counter(stat->fs, "curr_tcp_sess_used"); stat->ids.nr_tcp_sess_opening = fieldstat_easy_register_counter(stat->fs, "curr_tcp_sess_opening"); @@ -330,6 +376,27 @@ void stellar_stat_output(struct stellar_stat *stat) fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ctrl_rx_bytes, NULL, 0, stat->io_stat.ctrl_rx_bytes); fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ctrl_tx_pkts, NULL, 0, stat->io_stat.ctrl_tx_pkts); fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ctrl_tx_bytes, NULL, 0, stat->io_stat.ctrl_tx_bytes); + // ip reassembly + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_find, NULL, 0, stat->ip_stat.ip4_flow_find); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_add, NULL, 0, stat->ip_stat.ip4_flow_add); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_del, NULL, 0, stat->ip_stat.ip4_flow_del); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_timeout, NULL, 0, stat->ip_stat.ip4_flow_timeout); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_fail_no_space, NULL, 0, stat->ip_stat.ip4_flow_fail_no_space); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_fail_overlap, NULL, 0, stat->ip_stat.ip4_flow_fail_overlap); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_fail_many_frag, NULL, 0, stat->ip_stat.ip4_flow_fail_many_frag); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_fail_invalid_length, NULL, 0, stat->ip_stat.ip4_flow_fail_invalid_length); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_bypass_dup_fist_frag, NULL, 0, stat->ip_stat.ip4_flow_bypass_dup_fist_frag); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip4_flow_bypass_dup_last_frag, NULL, 0, stat->ip_stat.ip4_flow_bypass_dup_last_frag); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_find, NULL, 0, stat->ip_stat.ip6_flow_find); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_add, NULL, 0, stat->ip_stat.ip6_flow_add); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_del, NULL, 0, stat->ip_stat.ip6_flow_del); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_timeout, NULL, 0, stat->ip_stat.ip6_flow_timeout); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_fail_no_space, NULL, 0, stat->ip_stat.ip6_flow_fail_no_space); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_fail_overlap, NULL, 0, stat->ip_stat.ip6_flow_fail_overlap); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_fail_many_frag, NULL, 0, stat->ip_stat.ip6_flow_fail_many_frag); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_fail_invalid_length, NULL, 0, stat->ip_stat.ip6_flow_fail_invalid_length); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_bypass_dup_fist_frag, NULL, 0, stat->ip_stat.ip6_flow_bypass_dup_fist_frag); + fieldstat_easy_counter_set(stat->fs, 0, stat->ids.ip6_flow_bypass_dup_last_frag, NULL, 0, stat->ip_stat.ip6_flow_bypass_dup_last_frag); // TCP session fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_sess_used, NULL, 0, stat->sess_stat.nr_tcp_sess_used); fieldstat_easy_counter_set(stat->fs, 0, stat->ids.nr_tcp_sess_opening, NULL, 0, stat->sess_stat.nr_tcp_sess_opening); diff --git a/src/stellar/stellar.cpp b/src/stellar/stellar.cpp index 5084b6c..1fd176a 100644 --- a/src/stellar/stellar.cpp +++ b/src/stellar/stellar.cpp @@ -96,6 +96,7 @@ static void *work_thread(void *arg) char thd_name[16] = {0}; void *plugin_ctx = NULL; struct packet *pkt = NULL; + struct packet *defraged_pkt = NULL; struct packet packets[RX_BURST_MAX]; struct session *sess = NULL; struct packet_io *packet_io = runtime->packet_io; @@ -130,12 +131,13 @@ static void *work_thread(void *arg) for (int i = 0; i < nr_recv; i++) { sess = NULL; + defraged_pkt = NULL; pkt = &packets[i]; plugin_manager_dispatch_packet(plug_mgr, pkt); if (packet_is_fragment(pkt)) { - struct packet *defraged_pkt = ip_reassembly_packet(ip_reass, pkt, now); + defraged_pkt = ip_reassembly_packet(ip_reass, pkt, now); if (defraged_pkt == NULL) { goto fast_path; @@ -171,11 +173,27 @@ static void *work_thread(void *arg) update_session_stat(sess, pkt); if (packet_need_drop(pkt)) { - packet_io_drop(packet_io, thr_idx, pkt, 1); + if (pkt == defraged_pkt) + { + packet_io_drop(packet_io, thr_idx, &packets[i], 1); + packet_free(defraged_pkt); + } + else + { + packet_io_drop(packet_io, thr_idx, pkt, 1); + } } else { - packet_io_egress(packet_io, thr_idx, pkt, 1); + if (pkt == defraged_pkt) + { + packet_io_egress(packet_io, thr_idx, &packets[i], 1); + packet_free(defraged_pkt); + } + else + { + packet_io_egress(packet_io, thr_idx, pkt, 1); + } } }