From bd30f127a53fa9c5d5da7cd91d52bf17bdbaea01 Mon Sep 17 00:00:00 2001 From: Christian Giese Date: Fri, 7 Oct 2022 11:52:41 +0000 Subject: [PATCH] LAG fixes, enhancements, commands... --- code/bngblaster/src/bbl_config.c | 55 ++++-- code/bngblaster/src/bbl_config.h | 3 +- code/bngblaster/src/bbl_ctrl.c | 9 +- code/bngblaster/src/bbl_interactive.c | 6 +- code/bngblaster/src/bbl_interface.h | 1 + code/bngblaster/src/bbl_lag.c | 208 +++++++++++++++++++-- code/bngblaster/src/bbl_lag.h | 10 +- code/bngblaster/src/bbl_rx.c | 12 +- code/bngblaster/src/bbl_session.c | 48 ++--- code/bngblaster/src/bbl_stats.c | 46 +++-- code/bngblaster/src/bbl_stream.c | 249 +++++++++++++------------- code/bngblaster/src/bbl_stream.h | 17 +- 12 files changed, 439 insertions(+), 225 deletions(-) diff --git a/code/bngblaster/src/bbl_config.c b/code/bngblaster/src/bbl_config.c index 76c8c8d0..648895f0 100644 --- a/code/bngblaster/src/bbl_config.c +++ b/code/bngblaster/src/bbl_config.c @@ -284,6 +284,18 @@ json_parse_lag(json_t *lag, bbl_lag_config_s *lag_config) lag_config->lacp_system_id[3] = 0xff; lag_config->lacp_system_id[4] = 0xff; } + value = json_object_get(lag, "lacp-min-active-links"); + if(value) { + lag_config->lacp_min_active_links = json_number_value(value); + } else { + lag_config->lacp_min_active_links = 0; + } + value = json_object_get(lag, "lacp-max-active-links"); + if(value) { + lag_config->lacp_min_active_links = json_number_value(value); + } else { + lag_config->lacp_max_active_links = UINT8_MAX; + } if(json_unpack(lag, "{s:s}", "mac", &s) == 0) { if(sscanf(s, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", @@ -1304,6 +1316,22 @@ json_parse_stream(json_t *stream, bbl_stream_config_s *stream_config) double bps; double number; + if(json_unpack(stream, "{s:s}", "name", &s) == 0) { + stream_config->name = strdup(s); + } else { + fprintf(stderr, "JSON config error: Missing value for stream->name\n"); + return false; + } + + value = json_object_get(stream, "stream-group-id"); + if(value) { + number = json_number_value(value); + if(number >= UINT16_MAX) { + fprintf(stderr, "JSON config error: Invalid value for stream->stream-group-id\n"); + } + stream_config->stream_group_id = number; + } + if(json_unpack(stream, "{s:s}", "type", &s) == 0) { if(strcmp(s, "ipv4") == 0) { stream_config->type = BBL_SUB_TYPE_IPV4; @@ -1332,24 +1360,17 @@ json_parse_stream(json_t *stream, bbl_stream_config_s *stream_config) return false; } } else { - stream_config->direction = BBL_DIRECTION_BOTH; - return false; - } - - if(json_unpack(stream, "{s:s}", "name", &s) == 0) { - stream_config->name = strdup(s); - } else { - fprintf(stderr, "JSON config error: Missing value for stream->name\n"); - return false; - } - - value = json_object_get(stream, "stream-group-id"); - if(value) { - number = json_number_value(value); - if(number >= UINT16_MAX) { - fprintf(stderr, "JSON config error: Invalid value for stream->stream-group-id\n"); + if(stream_config->stream_group_id) { + stream_config->direction = BBL_DIRECTION_BOTH; + } else { + stream_config->direction = BBL_DIRECTION_DOWN; } - stream_config->stream_group_id = number; + } + + if(stream_config->stream_group_id == 0 && + stream_config->direction != BBL_DIRECTION_DOWN) { + fprintf(stderr, "JSON config error: Invalid value for stream->direction (must be downstream for RAW streams)\n"); + return false; } if(json_unpack(stream, "{s:s}", "network-interface", &s) == 0) { diff --git a/code/bngblaster/src/bbl_config.h b/code/bngblaster/src/bbl_config.h index d8f55fb6..2c1e20b3 100644 --- a/code/bngblaster/src/bbl_config.h +++ b/code/bngblaster/src/bbl_config.h @@ -153,10 +153,11 @@ typedef struct bbl_lag_config_ char *interface; bool lacp_enable; bool lacp_timeout_short; + uint8_t lacp_min_active_links; + uint8_t lacp_max_active_links; uint16_t lacp_system_priority; uint8_t lacp_system_id[ETH_ADDR_LEN]; uint8_t mac[ETH_ADDR_LEN]; - void *next; /* pointer to next lag config element */ } bbl_lag_config_s; diff --git a/code/bngblaster/src/bbl_ctrl.c b/code/bngblaster/src/bbl_ctrl.c index 8afeafcc..14773573 100644 --- a/code/bngblaster/src/bbl_ctrl.c +++ b/code/bngblaster/src/bbl_ctrl.c @@ -1592,7 +1592,7 @@ bbl_ctrl_traffic_stop(int fd, uint32_t session_id __attribute__((unused)), json_ } int -bgp_ctrl_monkey_start(int fd, uint32_t session_id __attribute__((unused)), json_t* arguments __attribute__((unused))) +bbl_ctrl_monkey_start(int fd, uint32_t session_id __attribute__((unused)), json_t* arguments __attribute__((unused))) { if(!g_monkey) { LOG_NOARG(INFO, "Start monkey\n"); @@ -1602,7 +1602,7 @@ bgp_ctrl_monkey_start(int fd, uint32_t session_id __attribute__((unused)), json_ } int -bgp_ctrl_monkey_stop(int fd, uint32_t session_id __attribute__((unused)), json_t* arguments __attribute__((unused))) +bbl_ctrl_monkey_stop(int fd, uint32_t session_id __attribute__((unused)), json_t* arguments __attribute__((unused))) { if(g_monkey) { LOG_NOARG(INFO, "Stop monkey\n"); @@ -1674,8 +1674,9 @@ struct action actions[] = { {"bgp-teardown", bgp_ctrl_teardown, true}, {"bgp-raw-update-list", bgp_ctrl_raw_update_list, true}, {"bgp-raw-update", bgp_ctrl_raw_update, false}, - {"monkey-start", bgp_ctrl_monkey_start, false}, - {"monkey-stop", bgp_ctrl_monkey_stop, false}, + {"monkey-start", bbl_ctrl_monkey_start, false}, + {"monkey-stop", bbl_ctrl_monkey_stop, false}, + {"lag-info", bbl_lag_ctrl_info, true}, {NULL, NULL, false}, }; diff --git a/code/bngblaster/src/bbl_interactive.c b/code/bngblaster/src/bbl_interactive.c index 90358856..b63af876 100644 --- a/code/bngblaster/src/bbl_interactive.c +++ b/code/bngblaster/src/bbl_interactive.c @@ -616,7 +616,7 @@ bbl_interactive_window_job(timer_s *timer) if(i >= stats_win_postion && i < 16+stats_win_postion) { wprintw(stats_win, " %-16.16s | %-9.9s | %7lu | %10lu | %7lu | %10lu | %8lu\n", stream->config->name, stream->direction == BBL_DIRECTION_UP ? "up" : "down", - stream->rate_packets_tx.avg, tx_kbps, stream->rate_packets_rx.avg, rx_kbps, stream->loss); + stream->rate_packets_tx.avg, tx_kbps, stream->rate_packets_rx.avg, rx_kbps, stream->rx_loss); } else if (i == 16+stats_win_postion) { wprintw(stats_win, " ...\n"); } @@ -627,13 +627,13 @@ bbl_interactive_window_job(timer_s *timer) stream_sum_up_tx_kbps += tx_kbps; stream_sum_up_rx_pps += stream->rate_packets_rx.avg; stream_sum_up_rx_kbps += rx_kbps; - stream_sum_up_loss += stream->loss; + stream_sum_up_loss += stream->rx_loss; } else { stream_sum_down_tx_pps += stream->rate_packets_tx.avg; stream_sum_down_tx_kbps += tx_kbps; stream_sum_down_rx_pps += stream->rate_packets_rx.avg; stream_sum_down_rx_kbps += rx_kbps; - stream_sum_down_loss += stream->loss; + stream_sum_down_loss += stream->rx_loss; } stream = stream->session_next; } diff --git a/code/bngblaster/src/bbl_interface.h b/code/bngblaster/src/bbl_interface.h index 550f5583..93773167 100644 --- a/code/bngblaster/src/bbl_interface.h +++ b/code/bngblaster/src/bbl_interface.h @@ -15,6 +15,7 @@ typedef struct bbl_interface_ char *name; /* interface name */ interface_type_t type; /* interface type */ interface_state_t state; /* interface state */ + uint32_t state_transitions; /* interface state transitions */ uint32_t ifindex; /* interface index */ uint32_t pcap_index; /* interface index for packet captures */ diff --git a/code/bngblaster/src/bbl_lag.c b/code/bngblaster/src/bbl_lag.c index 20577674..e4ed3000 100644 --- a/code/bngblaster/src/bbl_lag.c +++ b/code/bngblaster/src/bbl_lag.c @@ -7,9 +7,21 @@ * SPDX-License-Identifier: BSD-3-Clause */ #include "bbl.h" +#include "../bbl_ctrl.h" uint16_t g_lag_port_id = 1; +const char * +lacp_state_string(lacp_state_t type) +{ + switch(type) { + case LACP_EXPIRED: return "Expired"; + case LACP_DEFAULTED: return "Defaulted"; + case LACP_CURRENT: return "Current"; + default: return "Disabled"; + } +} + bbl_lag_s * bbl_lag_get_by_name(char *interface) { @@ -76,18 +88,37 @@ bbl_lag_lacp_job(timer_s *timer) if(member->timeout > 3) { interface->state = INTERFACE_DOWN; if(!(member->actor_state & LACP_STATE_FLAG_EXPIRED)) { + member->lacp_state = LACP_EXPIRED; member->actor_state |= LACP_STATE_FLAG_EXPIRED; LOG(LAG, "LAG (%s) LACP expired on interface %s\n", member->lag->interface->name, interface->name); } if(member->timeout > 6) { if(!(member->actor_state & LACP_STATE_FLAG_DEFAULTED)) { + member->lacp_state = LACP_DEFAULTED; member->actor_state |= LACP_STATE_FLAG_DEFAULTED; + LOG(LAG, "LAG (%s) LACP defaulted on interface %s\n", + member->lag->interface->name, interface->name); } } } } +static void +bbl_lag_member_insert(bbl_lag_s *lag, bbl_lag_member_s *member) +{ + /* Insert LAG member links by port priority + * (lower value is higher priority). */ + bbl_lag_member_s *member_iter; + CIRCLEQ_FOREACH(member_iter, &lag->lag_member_qhead, lag_member_qnode) { + if(member_iter->actor_port_priority > member->actor_port_priority) { + CIRCLEQ_INSERT_BEFORE(&lag->lag_member_qhead, member_iter, member, lag_member_qnode); + return; + } + } + CIRCLEQ_INSERT_TAIL(&lag->lag_member_qhead, member, lag_member_qnode); +} + bool bbl_lag_interface_add(bbl_interface_s *interface, bbl_link_config_s *link_config) { @@ -135,41 +166,92 @@ bbl_lag_interface_add(bbl_interface_s *interface, bbl_link_config_s *link_config } else { member->lacp_state = LACP_DISABLED; } - CIRCLEQ_INSERT_TAIL(&lag->lag_member_qhead, member, lag_member_qnode); + + bbl_lag_member_insert(lag, member); LOG(LAG, "LAG (%s) Interface %s added\n", lag->interface->name, interface->name); } return true; } +static void +bbl_lag_member_update_state(bbl_lag_member_s *member, interface_state_t state) +{ + bbl_interface_s *interface = member->interface; + if(interface->state == state) { + return; + } + + LOG(LAG, "LAG (%s) Member interface %s state changed from %s to %s\n", + member->lag->interface->name, + interface->name, + interface_state_string(interface->state), + interface_state_string(state)); + + interface->state_transitions++; + interface->state = state; + switch(state) { + case INTERFACE_UP: + member->actor_state |= (LACP_STATE_FLAG_COLLECTING|LACP_STATE_FLAG_DISTRIBUTING); + break; + case INTERFACE_STANDBY: + member->actor_state &= ~LACP_STATE_FLAG_DISTRIBUTING; + member->actor_state |= LACP_STATE_FLAG_COLLECTING; + break; + default: + member->actor_state &= ~(LACP_STATE_FLAG_COLLECTING|LACP_STATE_FLAG_DISTRIBUTING); + break; + } +} + +static void +bbl_lag_update_state(bbl_lag_s *lag, interface_state_t state) +{ + bbl_interface_s *interface = lag->interface; + if(interface->state == state) { + return; + } + + LOG(LAG, "LAG (%s) Interface state changed from %s to %s\n", + interface->name, + interface_state_string(interface->state), + interface_state_string(state)); + + interface->state_transitions++; + interface->state = state; +} + static void bbl_lag_select(bbl_lag_s *lag) { bbl_lag_member_s *member; - lag->active_count = 0; + uint8_t active_count = 0; CIRCLEQ_FOREACH(member, &lag->lag_member_qhead, lag_member_qnode) { member->primary = false; if(member->partner_state & (LACP_STATE_FLAG_COLLECTING|LACP_STATE_FLAG_DISTRIBUTING)) { - member->actor_state |= (LACP_STATE_FLAG_COLLECTING|LACP_STATE_FLAG_DISTRIBUTING); - member->interface->state = INTERFACE_UP; - lag->active_list[lag->active_count++] = member; - if(lag->active_count == 1) { - member->primary = true; - LOG(LAG, "LAG (%s) Interface %s set to UP (primary)\n", member->lag->interface->name, member->interface->name); - + if(active_count >= LAG_MEMBER_ACTIVE_MAX || + active_count >= lag->config->lacp_max_active_links) { + bbl_lag_member_update_state(member, INTERFACE_STANDBY); } else { - LOG(LAG, "LAG (%s) Interface %s set to UP\n", member->lag->interface->name, member->interface->name); - + lag->active_list[active_count++] = member; + if(active_count == 1) { + member->primary = true; + } + bbl_lag_member_update_state(member, INTERFACE_UP); } } else { - member->interface->state = INTERFACE_DOWN; + bbl_lag_member_update_state(member, INTERFACE_DOWN); } } - if(lag->active_count) { - lag->interface->state = INTERFACE_UP; + + /* Update LAG state */ + if(active_count && + active_count >= lag->config->lacp_min_active_links) { + bbl_lag_update_state(lag, INTERFACE_UP); } else { - lag->interface->state = INTERFACE_DOWN; + bbl_lag_update_state(lag, INTERFACE_DOWN); } + lag->active_count = active_count; } void @@ -179,12 +261,14 @@ bbl_lag_rx_lacp(bbl_interface_s *interface, bbl_lag_member_s *member = interface->lag_member; bbl_lacp_s *lacp = (bbl_lacp_s*)eth->next; - if(member) { + if(member && member->lacp_state) { member->timeout = 0; + member->lacp_state = LACP_CURRENT; member->actor_state &= ~(LACP_STATE_FLAG_DEFAULTED|LACP_STATE_FLAG_EXPIRED); member->stats.lacp_rx++; if(member->partner_state != lacp->actor_state || - member->partner_system_priority != lacp->actor_system_priority) { + member->partner_system_priority != lacp->actor_system_priority || + member->partner_port_priority != lacp->actor_port_priority) { memcpy(member->partner_system_id, lacp->actor_system_id, ETH_ADDR_LEN); member->partner_system_priority = lacp->actor_system_priority; member->partner_key = lacp->actor_key; @@ -194,4 +278,94 @@ bbl_lag_rx_lacp(bbl_interface_s *interface, bbl_lag_select(member->lag); } } +} + +static json_t * +bbl_lag_json(bbl_lag_s *lag) +{ + bbl_lag_member_s *member; + json_t *jobj_lag, *jobj_member, *jobj_lacp, *jobj_array; + + jobj_array = json_array(); + + CIRCLEQ_FOREACH(member, &lag->lag_member_qhead, lag_member_qnode) { + if(member->lacp_state) { + jobj_lacp = json_pack("{si si si ss* si si si si si ss* si si si si si}", + "bpdu-rx", member->stats.lacp_rx, + "bpdu-tx", member->stats.lacp_tx, + "bpdu-dropped", member->stats.lacp_dropped, + "actor-system-id", format_mac_address(member->actor_system_id), + "actor-system-priority", member->actor_system_priority, + "actor-key", member->actor_key, + "actor-port-priority", member->actor_port_priority, + "actor-port-id", member->actor_port_id, + "actor-state", member->actor_state, + "partner-system-id", format_mac_address(member->partner_system_id), + "partner-system-priority", member->partner_system_priority, + "partner-key", member->partner_key, + "partner-port-priority", member->partner_port_priority, + "partner-port-id", member->partner_port_id, + "partner-state", member->partner_state); + } else { + jobj_lacp = NULL; + } + jobj_member = json_pack("{ss* ss* si ss* so*}", + "interface", member->interface->name, + "state", interface_state_string(member->interface->state), + "state-transitions", member->interface->state_transitions, + "lacp-state", lacp_state_string(member->lacp_state), + "lacp", jobj_lacp); + if(jobj_member) { + json_array_append(jobj_array, jobj_member); + } + } + + jobj_lag = json_pack("{si ss* ss* si so*}", + "id", lag->id, + "interface", lag->interface->name, + "state", interface_state_string(lag->interface->state), + "state-transitions", lag->interface->state_transitions, + "members", jobj_array); + + return jobj_lag; +} + +int +bbl_lag_ctrl_info(int fd, uint32_t session_id __attribute__((unused)), json_t* arguments __attribute__((unused))) +{ + int result = 0; + + bbl_lag_s *lag; + json_t *root, *jobj, *jobj_array; + const char *interface = NULL; + + jobj_array = json_array(); + + /* Unpack further arguments */ + json_unpack(arguments, "{s:s}", "interface", &interface); + + CIRCLEQ_FOREACH(lag, &g_ctx->lag_qhead, lag_qnode) { + if(interface) { + if(strcmp(lag->interface->name, interface) != 0) { + continue; + } + } + jobj = bbl_lag_json(lag); + if(jobj) { + json_array_append(jobj_array, jobj); + } + } + + root = json_pack("{ss si so*}", + "status", "ok", + "code", 200, + "lag-info", jobj_array); + + if(root) { + result = json_dumpfd(root, fd, 0); + json_decref(root); + } else { + result = bbl_ctrl_status(fd, "error", 500, "internal error"); + } + return result; } \ No newline at end of file diff --git a/code/bngblaster/src/bbl_lag.h b/code/bngblaster/src/bbl_lag.h index 5e5e88f3..d4734107 100644 --- a/code/bngblaster/src/bbl_lag.h +++ b/code/bngblaster/src/bbl_lag.h @@ -10,7 +10,7 @@ #ifndef __BBL_LAG_H__ #define __BBL_LAG_H__ -#define LAG_MEMBER_ACTIVE_MAX 16 +#define LAG_MEMBER_ACTIVE_MAX 64 typedef struct bbl_lag_ { @@ -18,7 +18,6 @@ typedef struct bbl_lag_ bbl_interface_s *interface; bbl_lag_config_s *config; - uint8_t active_max; uint8_t active_count; bbl_lag_member_s *active_list[LAG_MEMBER_ACTIVE_MAX]; @@ -32,7 +31,10 @@ typedef struct bbl_lag_member_ bbl_interface_s *interface; lacp_state_t lacp_state; + /* The "primary" link is used for + * all control traffic. */ bool primary; + bool periodic_fast; struct timer_ *lacp_timer; @@ -57,7 +59,6 @@ typedef struct bbl_lag_member_ uint32_t lacp_rx; uint32_t lacp_tx; uint32_t lacp_dropped; - uint32_t lacp_transitions; } stats; } bbl_lag_member_s; @@ -74,4 +75,7 @@ void bbl_lag_rx_lacp(bbl_interface_s *interface, bbl_ethernet_header_s *eth); +int +bbl_lag_ctrl_info(int fd, uint32_t session_id __attribute__((unused)), json_t* arguments); + #endif \ No newline at end of file diff --git a/code/bngblaster/src/bbl_rx.c b/code/bngblaster/src/bbl_rx.c index f575730d..71912552 100644 --- a/code/bngblaster/src/bbl_rx.c +++ b/code/bngblaster/src/bbl_rx.c @@ -19,8 +19,8 @@ bbl_rx_stream_network(bbl_network_interface_s *interface, } stream = bbl_stream_rx(eth, NULL); if(stream) { - if(stream->network_interface == NULL) { - stream->network_interface = interface; + if(stream->rx_network_interface == NULL) { + stream->rx_network_interface = interface; } return true; } @@ -49,8 +49,8 @@ bbl_rx_stream_access(bbl_access_interface_s *interface, session->session_state != BBL_IDLE) { stream = bbl_stream_rx(eth, session); if(stream) { - if(stream->access_interface == NULL) { - stream->access_interface = interface; + if(stream->rx_access_interface == NULL) { + stream->rx_access_interface = interface; } return true; } @@ -69,8 +69,8 @@ bbl_rx_stream_a10nsp(bbl_a10nsp_interface_s *interface, } stream = bbl_stream_rx(eth, NULL); if(stream) { - if(stream->a10nsp_interface == NULL) { - stream->a10nsp_interface = interface; + if(stream->rx_a10nsp_interface == NULL) { + stream->rx_a10nsp_interface = interface; } return true; } diff --git a/code/bngblaster/src/bbl_session.c b/code/bngblaster/src/bbl_session.c index 227ced33..64735d80 100644 --- a/code/bngblaster/src/bbl_session.c +++ b/code/bngblaster/src/bbl_session.c @@ -994,56 +994,56 @@ bbl_session_json(bbl_session_s *session) if(session->session_traffic.ipv4_down) { stream = session->session_traffic.ipv4_down; json_object_set(session_traffic, "downstream-ipv4-flow-id", json_integer(stream->flow_id)); - json_object_set(session_traffic, "downstream-ipv4-tx-packets", json_integer(stream->packets_tx - stream->reset_packets_tx)); - json_object_set(session_traffic, "downstream-ipv4-rx-packets", json_integer(stream->packets_rx - stream->reset_packets_rx)); + json_object_set(session_traffic, "downstream-ipv4-tx-packets", json_integer(stream->tx_packets - stream->reset_packets_tx)); + json_object_set(session_traffic, "downstream-ipv4-rx-packets", json_integer(stream->rx_packets - stream->reset_packets_rx)); json_object_set(session_traffic, "downstream-ipv4-rx-first-seq", json_integer(stream->rx_first_seq)); - json_object_set(session_traffic, "downstream-ipv4-loss", json_integer(stream->loss - stream->reset_loss)); - json_object_set(session_traffic, "downstream-ipv4-wrong-session", json_integer(stream->wrong_session - stream->reset_wrong_session)); + json_object_set(session_traffic, "downstream-ipv4-loss", json_integer(stream->rx_loss - stream->reset_loss)); + json_object_set(session_traffic, "downstream-ipv4-wrong-session", json_integer(stream->rx_wrong_session - stream->reset_wrong_session)); } if(session->session_traffic.ipv4_up) { stream = session->session_traffic.ipv4_up; json_object_set(session_traffic, "upstream-ipv4-flow-id", json_integer(stream->flow_id)); - json_object_set(session_traffic, "upstream-ipv4-tx-packets", json_integer(stream->packets_tx - stream->reset_packets_tx)); - json_object_set(session_traffic, "upstream-ipv4-rx-packets", json_integer(stream->packets_rx - stream->reset_packets_rx)); + json_object_set(session_traffic, "upstream-ipv4-tx-packets", json_integer(stream->tx_packets - stream->reset_packets_tx)); + json_object_set(session_traffic, "upstream-ipv4-rx-packets", json_integer(stream->rx_packets - stream->reset_packets_rx)); json_object_set(session_traffic, "upstream-ipv4-rx-first-seq", json_integer(stream->rx_first_seq)); - json_object_set(session_traffic, "upstream-ipv4-loss", json_integer(stream->loss - stream->reset_loss)); - json_object_set(session_traffic, "upstream-ipv4-wrong-session", json_integer(stream->wrong_session - stream->reset_wrong_session)); + json_object_set(session_traffic, "upstream-ipv4-loss", json_integer(stream->rx_loss - stream->reset_loss)); + json_object_set(session_traffic, "upstream-ipv4-wrong-session", json_integer(stream->rx_wrong_session - stream->reset_wrong_session)); } if(session->session_traffic.ipv6_down) { stream = session->session_traffic.ipv6_down; json_object_set(session_traffic, "downstream-ipv6-flow-id", json_integer(stream->flow_id)); - json_object_set(session_traffic, "downstream-ipv6-tx-packets", json_integer(stream->packets_tx - stream->reset_packets_tx)); - json_object_set(session_traffic, "downstream-ipv6-rx-packets", json_integer(stream->packets_rx - stream->reset_packets_rx)); + json_object_set(session_traffic, "downstream-ipv6-tx-packets", json_integer(stream->tx_packets - stream->reset_packets_tx)); + json_object_set(session_traffic, "downstream-ipv6-rx-packets", json_integer(stream->rx_packets - stream->reset_packets_rx)); json_object_set(session_traffic, "downstream-ipv6-rx-first-seq", json_integer(stream->rx_first_seq)); - json_object_set(session_traffic, "downstream-ipv6-loss", json_integer(stream->loss - stream->reset_loss)); - json_object_set(session_traffic, "downstream-ipv6-wrong-session", json_integer(stream->wrong_session - stream->reset_wrong_session)); + json_object_set(session_traffic, "downstream-ipv6-loss", json_integer(stream->rx_loss - stream->reset_loss)); + json_object_set(session_traffic, "downstream-ipv6-wrong-session", json_integer(stream->rx_wrong_session - stream->reset_wrong_session)); } if(session->session_traffic.ipv6_up) { stream = session->session_traffic.ipv6_up; json_object_set(session_traffic, "upstream-ipv6-flow-id", json_integer(stream->flow_id)); - json_object_set(session_traffic, "upstream-ipv6-tx-packets", json_integer(stream->packets_tx - stream->reset_packets_tx)); - json_object_set(session_traffic, "upstream-ipv6-rx-packets", json_integer(stream->packets_rx - stream->reset_packets_rx)); + json_object_set(session_traffic, "upstream-ipv6-tx-packets", json_integer(stream->tx_packets - stream->reset_packets_tx)); + json_object_set(session_traffic, "upstream-ipv6-rx-packets", json_integer(stream->rx_packets - stream->reset_packets_rx)); json_object_set(session_traffic, "upstream-ipv6-rx-first-seq", json_integer(stream->rx_first_seq)); - json_object_set(session_traffic, "upstream-ipv6-loss", json_integer(stream->loss - stream->reset_loss)); - json_object_set(session_traffic, "upstream-ipv6-wrong-session", json_integer(stream->wrong_session - stream->reset_wrong_session)); + json_object_set(session_traffic, "upstream-ipv6-loss", json_integer(stream->rx_loss - stream->reset_loss)); + json_object_set(session_traffic, "upstream-ipv6-wrong-session", json_integer(stream->rx_wrong_session - stream->reset_wrong_session)); } if(session->session_traffic.ipv6pd_down) { stream = session->session_traffic.ipv6pd_down; json_object_set(session_traffic, "downstream-ipv6pd-flow-id", json_integer(stream->flow_id)); - json_object_set(session_traffic, "downstream-ipv6pd-tx-packets", json_integer(stream->packets_tx - stream->reset_packets_tx)); - json_object_set(session_traffic, "downstream-ipv6pd-rx-packets", json_integer(stream->packets_rx - stream->reset_packets_rx)); + json_object_set(session_traffic, "downstream-ipv6pd-tx-packets", json_integer(stream->tx_packets - stream->reset_packets_tx)); + json_object_set(session_traffic, "downstream-ipv6pd-rx-packets", json_integer(stream->rx_packets - stream->reset_packets_rx)); json_object_set(session_traffic, "downstream-ipv6pd-rx-first-seq", json_integer(stream->rx_first_seq)); - json_object_set(session_traffic, "downstream-ipv6pd-loss", json_integer(stream->loss - stream->reset_loss)); - json_object_set(session_traffic, "downstream-ipv6pd-wrong-session", json_integer(stream->wrong_session - stream->reset_wrong_session)); + json_object_set(session_traffic, "downstream-ipv6pd-loss", json_integer(stream->rx_loss - stream->reset_loss)); + json_object_set(session_traffic, "downstream-ipv6pd-wrong-session", json_integer(stream->rx_wrong_session - stream->reset_wrong_session)); } if(session->session_traffic.ipv6pd_up) { stream = session->session_traffic.ipv6pd_up; json_object_set(session_traffic, "upstream-ipv6pd-flow-id", json_integer(stream->flow_id)); - json_object_set(session_traffic, "upstream-ipv6pd-tx-packets", json_integer(stream->packets_tx - stream->reset_packets_tx)); - json_object_set(session_traffic, "upstream-ipv6pd-rx-packets", json_integer(stream->packets_rx - stream->reset_packets_rx)); + json_object_set(session_traffic, "upstream-ipv6pd-tx-packets", json_integer(stream->tx_packets - stream->reset_packets_tx)); + json_object_set(session_traffic, "upstream-ipv6pd-rx-packets", json_integer(stream->rx_packets - stream->reset_packets_rx)); json_object_set(session_traffic, "upstream-ipv6pd-rx-first-seq", json_integer(stream->rx_first_seq)); - json_object_set(session_traffic, "upstream-ipv6pd-loss", json_integer(stream->loss - stream->reset_loss)); - json_object_set(session_traffic, "upstream-ipv6pd-wrong-session", json_integer(stream->wrong_session - stream->reset_wrong_session)); + json_object_set(session_traffic, "upstream-ipv6pd-loss", json_integer(stream->rx_loss - stream->reset_loss)); + json_object_set(session_traffic, "upstream-ipv6pd-wrong-session", json_integer(stream->rx_wrong_session - stream->reset_wrong_session)); } } if(session->a10nsp_session) { diff --git a/code/bngblaster/src/bbl_stats.c b/code/bngblaster/src/bbl_stats.c index 009522bf..bfa5555c 100644 --- a/code/bngblaster/src/bbl_stats.c +++ b/code/bngblaster/src/bbl_stats.c @@ -351,11 +351,11 @@ bbl_stats_generate(bbl_stats_s * stats) stream = (bbl_stream_s*)*dict_itor_datum(itor); if(stream) { if(stats->min_stream_loss) { - if(stream->loss < stats->min_stream_loss) stats->min_stream_loss = stream->loss; + if(stream->rx_loss < stats->min_stream_loss) stats->min_stream_loss = stream->rx_loss; } else { - stats->min_stream_loss = stream->loss; + stats->min_stream_loss = stream->rx_loss; } - if(stream->loss > stats->max_stream_loss) stats->max_stream_loss = stream->loss; + if(stream->rx_loss > stats->max_stream_loss) stats->max_stream_loss = stream->rx_loss; if(stream->rx_first_seq) { if(stats->min_stream_rx_first_seq) { @@ -366,11 +366,11 @@ bbl_stats_generate(bbl_stats_s * stats) if(stream->rx_first_seq > stats->max_stream_rx_first_seq) stats->max_stream_rx_first_seq = stream->rx_first_seq; if(stats->min_stream_delay_ns) { - if(stream->min_delay_ns < stats->min_stream_delay_ns) stats->min_stream_delay_ns = stream->min_delay_ns; + if(stream->rx_min_delay_ns < stats->min_stream_delay_ns) stats->min_stream_delay_ns = stream->rx_min_delay_ns; } else { - stats->min_stream_delay_ns = stream->min_delay_ns; + stats->min_stream_delay_ns = stream->rx_min_delay_ns; } - if(stream->max_delay_ns > stats->max_stream_delay_ns) stats->max_stream_delay_ns = stream->max_delay_ns; + if(stream->rx_max_delay_ns > stats->max_stream_delay_ns) stats->max_stream_delay_ns = stream->rx_max_delay_ns; } } } @@ -425,21 +425,29 @@ bbl_stats_stdout(bbl_stats_s *stats) { access_interface = interface->access; a10nsp_interface = interface->a10nsp; - bbl_stats_generate_interface(interface->io.tx, &interface_stats_tx); - bbl_stats_generate_interface(interface->io.rx, &interface_stats_rx); - printf("\nInterface: %s", interface->name); + if(interface->type == LAG_INTERFACE) { + printf(" (LAG)"); + } else if(interface->type == LAG_MEMBER_INTERFACE) { + printf(" (%s)", interface->lag->interface->name); + } printf("\n--------------------------------------------------------------\n"); - printf(" TX: %10lu packets %16lu bytes\n", - interface_stats_tx.packets, interface_stats_tx.bytes); - printf(" TX Polled: %10lu\n", interface_stats_tx.polled); - printf(" TX IO Error: %10lu\n", interface_stats_tx.io_errors); - printf(" RX: %10lu packets %16lu bytes\n", - interface_stats_rx.packets, interface_stats_rx.bytes); - printf(" RX Protocol Error: %10lu packets\n", interface_stats_rx.protocol_errors); - printf(" RX Unknown: %10lu packets\n", interface_stats_rx.unknown); - printf(" RX Polled: %10lu\n", interface_stats_rx.polled); - printf(" RX IO Error: %10lu\n", interface_stats_rx.io_errors); + + if(interface->type != LAG_INTERFACE) { + bbl_stats_generate_interface(interface->io.tx, &interface_stats_tx); + bbl_stats_generate_interface(interface->io.rx, &interface_stats_rx); + + printf(" TX: %10lu packets %16lu bytes\n", + interface_stats_tx.packets, interface_stats_tx.bytes); + printf(" TX Polled: %10lu\n", interface_stats_tx.polled); + printf(" TX IO Error: %10lu\n", interface_stats_tx.io_errors); + printf(" RX: %10lu packets %16lu bytes\n", + interface_stats_rx.packets, interface_stats_rx.bytes); + printf(" RX Protocol Error: %10lu packets\n", interface_stats_rx.protocol_errors); + printf(" RX Unknown: %10lu packets\n", interface_stats_rx.unknown); + printf(" RX Polled: %10lu\n", interface_stats_rx.polled); + printf(" RX IO Error: %10lu\n", interface_stats_rx.io_errors); + } while(network_interface) { printf("\nNetwork Interface: %s\n", network_interface->name); diff --git a/code/bngblaster/src/bbl_stream.c b/code/bngblaster/src/bbl_stream.c index 9f7e7c33..505e5400 100644 --- a/code/bngblaster/src/bbl_stream.c +++ b/code/bngblaster/src/bbl_stream.c @@ -28,15 +28,15 @@ bbl_stream_delay(bbl_stream_s *stream, struct timespec *rx_timestamp, struct tim uint64_t delay_nsec; timespec_sub(&delay, rx_timestamp, bbl_timestamp); delay_nsec = delay.tv_sec * 1000000000 + delay.tv_nsec; - if(delay_nsec > stream->max_delay_ns) { - stream->max_delay_ns = delay_nsec; + if(delay_nsec > stream->rx_max_delay_ns) { + stream->rx_max_delay_ns = delay_nsec; } - if(stream->min_delay_ns) { - if(delay_nsec < stream->min_delay_ns) { - stream->min_delay_ns = delay_nsec; + if(stream->rx_min_delay_ns) { + if(delay_nsec < stream->rx_min_delay_ns) { + stream->rx_min_delay_ns = delay_nsec; } } else { - stream->min_delay_ns = delay_nsec; + stream->rx_min_delay_ns = delay_nsec; } } @@ -925,101 +925,97 @@ bbl_stream_rx_stats(bbl_stream_s *stream, uint64_t packets, uint64_t bytes, uint bbl_network_interface_s *network_interface; bbl_a10nsp_interface_s *a10nsp_interface; - if(stream->direction == BBL_DIRECTION_DOWN) { - access_interface = stream->access_interface; + if(stream->rx_access_interface) { + access_interface = stream->rx_access_interface; + access_interface->stats.packets_rx += packets; + access_interface->stats.bytes_rx += bytes; + access_interface->stats.stream_rx += packets; + access_interface->stats.stream_loss += loss; session = stream->session; - if(access_interface) { - access_interface->stats.packets_rx += packets; - access_interface->stats.bytes_rx += bytes; - access_interface->stats.stream_rx += packets; - access_interface->stats.stream_loss += loss; - if(session) { - session->stats.packets_rx += packets; - session->stats.bytes_rx += bytes; - session->stats.accounting_packets_rx += packets; - session->stats.accounting_bytes_rx += bytes; - if(stream->session_traffic) { - switch(stream->sub_type) { - case BBL_SUB_TYPE_IPV4: - access_interface->stats.session_ipv4_rx += packets; - access_interface->stats.session_ipv4_loss += loss; - break; - case BBL_SUB_TYPE_IPV6: - access_interface->stats.session_ipv6_rx += packets; - access_interface->stats.session_ipv6_loss += loss; - break; - case BBL_SUB_TYPE_IPV6PD: - access_interface->stats.session_ipv6pd_rx += packets; - access_interface->stats.session_ipv6pd_loss += loss; - break; - default: - break; - } + if(session) { + session->stats.packets_rx += packets; + session->stats.bytes_rx += bytes; + session->stats.accounting_packets_rx += packets; + session->stats.accounting_bytes_rx += bytes; + if(stream->session_traffic) { + switch(stream->sub_type) { + case BBL_SUB_TYPE_IPV4: + access_interface->stats.session_ipv4_rx += packets; + access_interface->stats.session_ipv4_loss += loss; + break; + case BBL_SUB_TYPE_IPV6: + access_interface->stats.session_ipv6_rx += packets; + access_interface->stats.session_ipv6_loss += loss; + break; + case BBL_SUB_TYPE_IPV6PD: + access_interface->stats.session_ipv6pd_rx += packets; + access_interface->stats.session_ipv6pd_loss += loss; + break; + default: + break; } } } - } else { - if(stream->network_interface) { - network_interface = stream->network_interface; - network_interface->stats.packets_rx += packets; - network_interface->stats.bytes_rx += bytes; - network_interface->stats.stream_rx += packets; - network_interface->stats.stream_loss += loss; - if(session) { - if(session->l2tp_session) { - network_interface->stats.l2tp_data_rx += packets; - session->l2tp_session->tunnel->stats.data_rx += packets; - session->l2tp_session->stats.data_rx += packets; - if(stream->type == BBL_SUB_TYPE_IPV4) { - session->l2tp_session->stats.data_ipv4_rx += packets; - } - } - if(stream->session_traffic) { - switch(stream->sub_type) { - case BBL_SUB_TYPE_IPV4: - network_interface->stats.session_ipv4_rx += packets; - network_interface->stats.session_ipv4_loss += loss; - break; - case BBL_SUB_TYPE_IPV6: - network_interface->stats.session_ipv6_rx += packets; - network_interface->stats.session_ipv6_loss += loss; - break; - case BBL_SUB_TYPE_IPV6PD: - network_interface->stats.session_ipv6pd_rx += packets; - network_interface->stats.session_ipv6pd_loss += loss; - break; - default: - break; - } + } else if(stream->rx_network_interface) { + network_interface = stream->rx_network_interface; + network_interface->stats.packets_rx += packets; + network_interface->stats.bytes_rx += bytes; + network_interface->stats.stream_rx += packets; + network_interface->stats.stream_loss += loss; + if(session) { + if(session->l2tp_session) { + network_interface->stats.l2tp_data_rx += packets; + session->l2tp_session->tunnel->stats.data_rx += packets; + session->l2tp_session->stats.data_rx += packets; + if(stream->type == BBL_SUB_TYPE_IPV4) { + session->l2tp_session->stats.data_ipv4_rx += packets; } } - } else if(stream->a10nsp_interface) { - a10nsp_interface = stream->a10nsp_interface; - a10nsp_interface->stats.packets_rx += packets; - a10nsp_interface->stats.bytes_rx += bytes; - a10nsp_interface->stats.stream_rx += packets; - a10nsp_interface->stats.stream_loss += loss; - if(session) { - if(session->a10nsp_session) { - session->a10nsp_session->stats.packets_rx += packets; + if(stream->session_traffic) { + switch(stream->sub_type) { + case BBL_SUB_TYPE_IPV4: + network_interface->stats.session_ipv4_rx += packets; + network_interface->stats.session_ipv4_loss += loss; + break; + case BBL_SUB_TYPE_IPV6: + network_interface->stats.session_ipv6_rx += packets; + network_interface->stats.session_ipv6_loss += loss; + break; + case BBL_SUB_TYPE_IPV6PD: + network_interface->stats.session_ipv6pd_rx += packets; + network_interface->stats.session_ipv6pd_loss += loss; + break; + default: + break; } - if(stream->session_traffic) { - switch(stream->sub_type) { - case BBL_SUB_TYPE_IPV4: - a10nsp_interface->stats.session_ipv4_rx += packets; - a10nsp_interface->stats.session_ipv4_loss += loss; - break; - case BBL_SUB_TYPE_IPV6: - a10nsp_interface->stats.session_ipv6_rx += packets; - a10nsp_interface->stats.session_ipv6_loss += loss; - break; - case BBL_SUB_TYPE_IPV6PD: - a10nsp_interface->stats.session_ipv6pd_rx += packets; - a10nsp_interface->stats.session_ipv6pd_loss += loss; - break; - default: - break; - } + } + } + } else if(stream->rx_a10nsp_interface) { + a10nsp_interface = stream->rx_a10nsp_interface; + a10nsp_interface->stats.packets_rx += packets; + a10nsp_interface->stats.bytes_rx += bytes; + a10nsp_interface->stats.stream_rx += packets; + a10nsp_interface->stats.stream_loss += loss; + if(session) { + if(session->a10nsp_session) { + session->a10nsp_session->stats.packets_rx += packets; + } + if(stream->session_traffic) { + switch(stream->sub_type) { + case BBL_SUB_TYPE_IPV4: + a10nsp_interface->stats.session_ipv4_rx += packets; + a10nsp_interface->stats.session_ipv4_loss += loss; + break; + case BBL_SUB_TYPE_IPV6: + a10nsp_interface->stats.session_ipv6_rx += packets; + a10nsp_interface->stats.session_ipv6_loss += loss; + break; + case BBL_SUB_TYPE_IPV6PD: + a10nsp_interface->stats.session_ipv6pd_rx += packets; + a10nsp_interface->stats.session_ipv6pd_loss += loss; + break; + default: + break; } } } @@ -1032,7 +1028,7 @@ bbl_stream_rx_wrong_session(bbl_stream_s *stream) uint64_t packets; uint64_t packets_delta; - packets = stream->wrong_session; + packets = stream->rx_wrong_session; packets_delta = packets - stream->last_sync_wrong_session; stream->last_sync_wrong_session = packets; @@ -1064,18 +1060,18 @@ bbl_stream_ctrl(bbl_stream_s *stream) uint64_t loss_delta; /* Calculate TX packets/bytes since last sync. */ - packets = stream->packets_tx; + packets = stream->tx_packets; packets_delta = packets - stream->last_sync_packets_tx; bytes_delta = packets_delta * stream->tx_len; stream->last_sync_packets_tx = packets; bbl_stream_tx_stats(stream, packets_delta, bytes_delta); if(g_ctx->config.stream_rate_calc) { - bbl_compute_avg_rate(&stream->rate_packets_tx, stream->packets_tx); + bbl_compute_avg_rate(&stream->rate_packets_tx, stream->tx_packets); } if(stream->type == BBL_TYPE_MULTICAST) { return; } - if(unlikely(stream->wrong_session)) { + if(unlikely(stream->rx_wrong_session)) { bbl_stream_rx_wrong_session(stream); } if(unlikely(!stream->verified)) { @@ -1107,17 +1103,17 @@ bbl_stream_ctrl(bbl_stream_s *stream) } /* Calculate RX packets/bytes since last sync. */ - packets = stream->packets_rx; + packets = stream->rx_packets; packets_delta = packets - stream->last_sync_packets_rx; bytes_delta = packets_delta * stream->rx_len; stream->last_sync_packets_rx = packets; /* Calculate RX loss since last sync. */ - packets = stream->loss; + packets = stream->rx_loss; loss_delta = packets - stream->last_sync_loss; stream->last_sync_loss = packets; bbl_stream_rx_stats(stream, packets_delta, bytes_delta, loss_delta); if(g_ctx->config.stream_rate_calc) { - bbl_compute_avg_rate(&stream->rate_packets_rx, stream->packets_rx); + bbl_compute_avg_rate(&stream->rate_packets_rx, stream->rx_packets); } } @@ -1179,7 +1175,7 @@ bbl_stream_send_window(bbl_stream_s *stream, struct timespec *now) { struct timespec time_elapsed = {0}; /** Enforce optional stream traffic start delay ... */ - if(stream->config->start_delay && stream->packets_tx == 0) { + if(stream->config->start_delay && stream->tx_packets == 0) { if(stream->wait) { timespec_sub(&time_elapsed, now, &stream->wait_start); if(time_elapsed.tv_sec < stream->config->start_delay) { @@ -1216,9 +1212,9 @@ bbl_stream_send_window(bbl_stream_s *stream, struct timespec *now) { /** Enforce optional stream packet limit ... */ if(stream->config->max_packets && - stream->packets_tx + packets > stream->config->max_packets) { - if(stream->packets_tx < stream->config->max_packets) { - packets = stream->config->max_packets - stream->packets_tx; + stream->tx_packets + packets > stream->config->max_packets) { + if(stream->tx_packets < stream->config->max_packets) { + packets = stream->config->max_packets - stream->tx_packets; } else { packets = 0; } @@ -1278,8 +1274,8 @@ bbl_stream_tx(bbl_stream_s *stream) return false; } stream->send_window_packets++; - stream->packets_tx++; stream->flow_seq++; + stream->tx_packets++; packets--; send++; } @@ -1297,9 +1293,12 @@ bbl_stream_lag_tx_job(timer_s *timer) { bbl_stream_s *stream = timer->data; bbl_lag_s *lag = stream->tx_interface->lag; - uint8_t key = stream->flow_id % lag->active_count; - stream->io = lag->active_list[key]->interface->io.tx; - bbl_stream_tx(stream); + uint8_t key = 0; + if(lag->active_count) { + key = stream->flow_id % lag->active_count; + stream->io = lag->active_list[key]->interface->io.tx; + bbl_stream_tx(stream); + } } void @@ -1829,13 +1828,13 @@ bbl_stream_reset(bbl_stream_s *stream) stream->reset = true; - stream->reset_packets_tx = stream->packets_tx; - stream->reset_packets_rx = stream->packets_rx; - stream->reset_loss = stream->loss; - stream->reset_wrong_session = stream->wrong_session; + stream->reset_packets_tx = stream->tx_packets; + stream->reset_packets_rx = stream->rx_packets; + stream->reset_loss = stream->rx_loss; + stream->reset_wrong_session = stream->rx_wrong_session; - stream->min_delay_ns = 0; - stream->max_delay_ns = 0; + stream->rx_min_delay_ns = 0; + stream->rx_max_delay_ns = 0; stream->rx_len = 0; stream->rx_first_seq = 0; stream->rx_last_seq = 0; @@ -1894,7 +1893,7 @@ bbl_stream_rx(bbl_ethernet_header_s *eth, bbl_session_s *session) /* Stream already verified */ if((stream->rx_last_seq +1) < bbl->flow_seq) { loss = bbl->flow_seq - (stream->rx_last_seq +1); - stream->loss += loss; + stream->rx_loss += loss; if(session) { LOG(LOSS, "LOSS (ID: %u) Unicast flow: %lu seq: %lu last: %lu\n", session->session_id, bbl->flow_id, bbl->flow_seq, stream->rx_last_seq); @@ -1946,13 +1945,13 @@ bbl_stream_rx(bbl_ethernet_header_s *eth, bbl_session_s *session) if(bbl->outer_vlan_id != session->vlan_key.outer_vlan_id || bbl->inner_vlan_id != session->vlan_key.inner_vlan_id || bbl->session_id != session->session_id) { - stream->wrong_session++; + stream->rx_wrong_session++; return NULL; } } stream->rx_first_seq = bbl->flow_seq; } - stream->packets_rx++; + stream->rx_packets++; stream->rx_last_seq = bbl->flow_seq; bbl_stream_delay(stream, ð->timestamp, &bbl->timestamp); return stream; @@ -2001,12 +2000,12 @@ bbl_stream_json(bbl_stream_s *stream) "rx-inner-vlan-pbit", stream->rx_inner_vlan_pbit, "rx-len", stream->rx_len, "tx-len", stream->tx_len, - "tx-packets", stream->packets_tx - stream->reset_packets_tx, - "rx-packets", stream->packets_rx - stream->reset_packets_rx, - "rx-loss", stream->loss - stream->reset_loss, - "rx-wrong-session", stream->wrong_session - stream->reset_wrong_session, - "rx-delay-nsec-min", stream->min_delay_ns, - "rx-delay-nsec-max", stream->max_delay_ns, + "tx-packets", stream->tx_packets - stream->reset_packets_tx, + "rx-packets", stream->rx_packets - stream->reset_packets_rx, + "rx-loss", stream->rx_loss - stream->reset_loss, + "rx-wrong-session", stream->rx_wrong_session - stream->reset_wrong_session, + "rx-delay-nsec-min", stream->rx_min_delay_ns, + "rx-delay-nsec-max", stream->rx_max_delay_ns, "rx-pps", stream->rate_packets_rx.avg, "tx-pps", stream->rate_packets_tx.avg, "tx-bps-l2", stream->rate_packets_tx.avg * stream->tx_len * 8, @@ -2045,7 +2044,7 @@ bbl_stream_json(bbl_stream_s *stream) "network-interface", network_interface_name, "flow-id", stream->flow_id, "tx-len", stream->tx_len, - "tx-packets", stream->packets_tx - stream->reset_packets_tx, + "tx-packets", stream->tx_packets - stream->reset_packets_tx, "tx-pps", stream->rate_packets_tx.avg, "tx-bps-l2", stream->rate_packets_tx.avg * stream->tx_len * 8, "tx-mbps-l2", (double)(stream->rate_packets_tx.avg * stream->tx_len * 8) / 1000000.0); diff --git a/code/bngblaster/src/bbl_stream.h b/code/bngblaster/src/bbl_stream.h index d0265e35..630b065a 100644 --- a/code/bngblaster/src/bbl_stream.h +++ b/code/bngblaster/src/bbl_stream.h @@ -107,16 +107,17 @@ typedef struct bbl_stream_ struct timespec wait_start; struct timespec send_window_start; uint64_t send_window_packets; - uint64_t packets_tx; + + uint64_t tx_packets; char _pad0 __attribute__((__aligned__(CACHE_LINE_SIZE))); /* empty cache line */ - uint64_t packets_rx; - uint64_t loss; - uint64_t wrong_session; + uint64_t rx_packets; + uint64_t rx_loss; + uint64_t rx_wrong_session; - uint64_t min_delay_ns; - uint64_t max_delay_ns; + uint64_t rx_min_delay_ns; + uint64_t rx_max_delay_ns; uint16_t rx_len; uint64_t rx_first_seq; @@ -136,6 +137,10 @@ typedef struct bbl_stream_ uint8_t rx_mpls2_ttl; uint32_t rx_mpls2_label; + bbl_access_interface_s *rx_access_interface; + bbl_network_interface_s *rx_network_interface; + bbl_a10nsp_interface_s *rx_a10nsp_interface; + char _pad1 __attribute__((__aligned__(CACHE_LINE_SIZE))); /* empty cache line */ uint64_t last_sync_packets_tx;