Traffic Streams and Fixes

+ count/report validated traffic streams
+ add sessions stats to JSON report
+ add stream stats to JSON report
+ add argument -T for traffic stream file
+ fix network interface ARP
+ ...
This commit is contained in:
Christian Giese
2021-10-20 18:34:17 +02:00
parent 24afc0df41
commit b3b1edefed
18 changed files with 872 additions and 632 deletions
+5 -1
View File
@@ -22,6 +22,7 @@ IPTV, L2TPv2, QoS, forwarding verification and convergence testing capabilities.
```
$ bngblaster --help
____ __ ____ _ __ ,/
/ __ \ / /_ / __ ) _____ (_)_____ / /__ ,'/
/ /_/ // __// __ |/ ___// // ___// //_/ ,' /
@@ -38,12 +39,14 @@ Usage: bngblaster [OPTIONS]
-v --version
-h --help
-C --config <args>
-T --stream-config <args>
-l --logging debug|error|igmp|io|pppoe|info|pcap|timer|timer-detail|ip|loss|l2tp|dhcp
-L --log-file <args>
-u --username <args>
-p --password <args>
-P --pcap-capture <args>
-J --json-report <args>
-j --json-report-content sessions|streams
-J --json-report-file <args>
-c --session-count <args>
-g --mc-group <args>
-s --mc-source <args>
@@ -53,6 +56,7 @@ Usage: bngblaster [OPTIONS]
-I --interactive
-b --hide-banner
-f --force
```
The BNG Blaster includes an optional interactive mode (`-I`) with realtime stats and
+49 -22
View File
@@ -22,6 +22,7 @@
/* Global Variables */
bool g_interactive = false; /* interactive mode using ncurses */
bool g_init_phase = true;
bool g_traffic = true;
bool g_banner = true;
char *g_log_file = NULL;
@@ -132,17 +133,19 @@ bbl_add_multicast_packets(bbl_ctx_s *ctx)
/*
* Command line options.
*/
const char *optstring = "vhC:l:L:u:p:P:J:c:g:s:r:z:S:Ibf";
const char *optstring = "vhC:T:l:L:u:p:P:j:J:c:g:s:r:z:S:Ibf";
static struct option long_options[] = {
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ "config", required_argument, NULL, 'C' },
{ "stream-config", required_argument, NULL, 'T' },
{ "logging", required_argument, NULL, 'l' },
{ "log-file", required_argument, NULL, 'L' },
{ "username", required_argument, NULL, 'u' },
{ "password", required_argument, NULL, 'p' },
{ "pcap-capture", required_argument, NULL, 'P' },
{ "json-report", required_argument, NULL, 'J' },
{ "json-report-content", required_argument, NULL, 'j' },
{ "json-report-file", required_argument, NULL, 'J' },
{ "session-count", required_argument, NULL, 'c' },
{ "mc-group", required_argument, NULL, 'g' },
{ "mc-source", required_argument, NULL, 's' },
@@ -162,7 +165,9 @@ bbl_print_usage_arg (struct option *option)
if (strcmp(option->name, "logging") == 0) {
return log_usage();
}
if (strcmp(option->name, "json-report-content") == 0) {
return " sessions|streams";
}
return " <args>";
}
return "";
@@ -226,6 +231,29 @@ bbl_ctrl_job (timer_s *timer)
int rate = 0;
uint32_t i;
/* Setup phase ...
* Wait for all network interfaces to be resolved. */
if(g_init_phase && !g_teardown) {
LOG(INFO, "Resolve network interfaces\n");
for(i = 0; i < ctx->interfaces.network_if_count; i++) {
interface = ctx->interfaces.network_if[i];
if(interface->gateway_resolve_wait == false) {
continue;
}
if(interface->gateway6.len && !interface->icmpv6_nd_resolved) {
LOG(DEBUG, "Wait for %s IPv6 gateway %s to be resolved\n",
interface->name, format_ipv6_prefix(&interface->gateway6));
return;
}
if(interface->gateway && !interface->arp_resolved) {
LOG(DEBUG, "Wait for %s IPv4 gateway %s to be resolved\n",
interface->name, format_ipv4_address(&interface->gateway));
return;
}
}
g_init_phase = false;
LOG(INFO, "All network interfaces resolved\n");
}
if(ctx->sessions_outstanding) ctx->sessions_outstanding--;
@@ -286,25 +314,6 @@ bbl_ctrl_job (timer_s *timer)
}
}
} else {
/* Setup phase ...
* Wait for all network interfaces to be resolved. */
if(g_init_phase) {
LOG(INFO, "Resolve network interfaces\n");
for(i = 0; i < ctx->interfaces.network_if_count; i++) {
interface = ctx->interfaces.network_if[i];
if(interface->gateway_resolve_wait == false) {
continue;
}
if(interface->gateway6.len && !interface->icmpv6_nd_resolved) {
return;
}
if(interface->gateway && !interface->arp_resolved) {
return;
}
}
g_init_phase = false;
LOG(INFO, "Start sessions\n");
}
/* Iterate over all idle session (list of pending sessions)
* and start as much as permitted per interval based on max
* outstanding and setup rate. Sessions started will be removed
@@ -380,6 +389,7 @@ main (int argc, char *argv[])
bbl_stats_t stats = {0};
const char *config_file = NULL;
const char *config_streams_file = NULL;
const char *username = NULL;
const char *password = NULL;
const char *sessions = NULL;
@@ -418,12 +428,22 @@ main (int argc, char *argv[])
case 'P':
ctx->pcap.filename = optarg;
break;
case 'j':
if (strcmp("sessions", optarg) == 0) {
ctx->config.json_report_sessions = true;
} else if (strcmp("streams", optarg) == 0) {
ctx->config.json_report_streams = true;
}
break;
case 'J':
ctx->config.json_report_filename = optarg;
break;
case 'C':
config_file = optarg;
break;
case 'T':
config_streams_file = optarg;
break;
case 'l':
log_enable(optarg);
break;
@@ -485,6 +505,13 @@ main (int argc, char *argv[])
fprintf(stderr, "Error: Failed to load configuration file %s\n", config_file);
exit(1);
}
if(config_streams_file) {
if(!bbl_config_streams_load_json(config_streams_file, ctx)) {
fprintf(stderr, "Error: Failed to load stream configuration file %s\n", config_file);
exit(1);
}
}
if(username) ctx->config.username = username;
if(password) ctx->config.password = password;
if(sessions) ctx->config.sessions = atoi(sessions);
+1
View File
@@ -34,6 +34,7 @@
#include <sys/mman.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <jansson.h>
#define NCURSES_NOMACROS 1
#include <curses.h>
+1
View File
@@ -287,6 +287,7 @@ bbl_a10nsp_pppoes_handler(bbl_interface_s *interface,
}
if(!stream->rx_first_seq) {
stream->rx_first_seq = bbl->flow_seq;
interface->ctx->stats.stream_traffic_flows_verified++;
} else {
if(stream->rx_last_seq +1 != bbl->flow_seq) {
stream->loss++;
+91 -38
View File
@@ -11,7 +11,6 @@
#include "bbl.h"
#include "bbl_config.h"
#include "bbl_stream.h"
#include <jansson.h>
#include <sys/stat.h>
const char g_default_user[] = "user{session-global}@rtbrick.com";
@@ -40,8 +39,7 @@ add_secondary_ipv4(bbl_ctx_s *ctx, uint32_t ipv4) {
secondary_ip = secondary_ip->next;
} else {
/* Append secondary address ... */
secondary_ip->next = malloc(sizeof(bbl_secondary_ip_s));
memset(secondary_ip->next, 0x0, sizeof(bbl_secondary_ip_s));
secondary_ip->next = calloc(1, sizeof(bbl_secondary_ip_s));
secondary_ip = secondary_ip->next;
secondary_ip->ip = ipv4;
break;
@@ -49,8 +47,7 @@ add_secondary_ipv4(bbl_ctx_s *ctx, uint32_t ipv4) {
}
} else {
/* Add first secondary address */
ctx->config.secondary_ip_addresses = malloc(sizeof(bbl_secondary_ip_s));
memset(ctx->config.secondary_ip_addresses, 0x0, sizeof(bbl_secondary_ip_s));
ctx->config.secondary_ip_addresses = calloc(1, sizeof(bbl_secondary_ip_s));
ctx->config.secondary_ip_addresses->ip = ipv4;
}
}
@@ -78,8 +75,7 @@ add_secondary_ipv6(bbl_ctx_s *ctx, ipv6addr_t ipv6) {
secondary_ip6 = secondary_ip6->next;
} else {
/* Append secondary address ... */
secondary_ip6->next = malloc(sizeof(bbl_secondary_ip6_s));
memset(secondary_ip6->next, 0x0, sizeof(bbl_secondary_ip6_s));
secondary_ip6->next = calloc(1, sizeof(bbl_secondary_ip6_s));
secondary_ip6 = secondary_ip6->next;
memcpy(secondary_ip6->ip, ipv6, IPV6_ADDR_LEN);
break;
@@ -87,8 +83,7 @@ add_secondary_ipv6(bbl_ctx_s *ctx, ipv6addr_t ipv6) {
}
} else {
/* Add first secondary address */
ctx->config.secondary_ip6_addresses = malloc(sizeof(bbl_secondary_ip6_s));
memset(ctx->config.secondary_ip6_addresses, 0x0, sizeof(bbl_secondary_ip6_s));
ctx->config.secondary_ip6_addresses = calloc(1, sizeof(bbl_secondary_ip6_s));
memcpy(ctx->config.secondary_ip6_addresses->ip, ipv6, IPV6_ADDR_LEN);
}
}
@@ -1294,21 +1289,19 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) {
size = json_array_size(sub);
for (i = 0; i < size; i++) {
if (!network_config) {
ctx->config.network_config = malloc(sizeof(bbl_network_config_s));
ctx->config.network_config = calloc(1, sizeof(bbl_network_config_s));
network_config = ctx->config.network_config;
} else {
network_config->next = malloc(sizeof(bbl_network_config_s));
network_config->next = calloc(1, sizeof(bbl_network_config_s));
network_config = network_config->next;
}
memset(network_config, 0x0, sizeof(bbl_network_config_s));
if (!json_parse_network_interface(ctx, json_array_get(sub, i), network_config)) {
return false;
}
}
} else if (json_is_object(sub)) {
/* Config is provided as object (single network interface) */
network_config = malloc(sizeof(bbl_network_config_s));
memset(network_config, 0x0, sizeof(bbl_network_config_s));
network_config = calloc(1, sizeof(bbl_network_config_s));
if (!ctx->config.network_config) {
ctx->config.network_config = network_config;
}
@@ -1324,21 +1317,19 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) {
size = json_array_size(sub);
for (i = 0; i < size; i++) {
if (!access_config) {
ctx->config.access_config = malloc(sizeof(bbl_access_config_s));
ctx->config.access_config = calloc(1, sizeof(bbl_access_config_s));
access_config = ctx->config.access_config;
} else {
access_config->next = malloc(sizeof(bbl_access_config_s));
access_config->next = calloc(1, sizeof(bbl_access_config_s));
access_config = access_config->next;
}
memset(access_config, 0x0, sizeof(bbl_access_config_s));
if (!json_parse_access_interface(ctx, json_array_get(sub, i), access_config)) {
return false;
}
}
} else if (json_is_object(sub)) {
/* Config is provided as object (single access range) */
access_config = malloc(sizeof(bbl_access_config_s));
memset(access_config, 0x0, sizeof(bbl_access_config_s));
access_config = calloc(1, sizeof(bbl_access_config_s));
if (!ctx->config.access_config) {
ctx->config.access_config = access_config;
}
@@ -1354,21 +1345,19 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) {
size = json_array_size(sub);
for (i = 0; i < size; i++) {
if (!a10nsp_config) {
ctx->config.a10nsp_config = malloc(sizeof(bbl_a10nsp_config_s));
ctx->config.a10nsp_config = calloc(1, sizeof(bbl_a10nsp_config_s));
a10nsp_config = ctx->config.a10nsp_config;
} else {
a10nsp_config->next = malloc(sizeof(bbl_a10nsp_config_s));
a10nsp_config->next = calloc(1, sizeof(bbl_a10nsp_config_s));
a10nsp_config = a10nsp_config->next;
}
memset(a10nsp_config, 0x0, sizeof(bbl_a10nsp_config_s));
if (!json_parse_a10nsp_interface(ctx, json_array_get(sub, i), a10nsp_config)) {
return false;
}
}
} else if (json_is_object(sub)) {
/* Config is provided as object (single a10nsp interface) */
a10nsp_config = malloc(sizeof(bbl_a10nsp_config_s));
memset(a10nsp_config, 0x0, sizeof(bbl_a10nsp_config_s));
a10nsp_config = calloc(1, sizeof(bbl_a10nsp_config_s));
if (!ctx->config.a10nsp_config) {
ctx->config.a10nsp_config = a10nsp_config;
}
@@ -1392,13 +1381,12 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) {
for (i = 0; i < size; i++) {
sub = json_array_get(section, i);
if (!l2tp_server) {
ctx->config.l2tp_server = malloc(sizeof(bbl_l2tp_server_t));
ctx->config.l2tp_server = calloc(1, sizeof(bbl_l2tp_server_t));
l2tp_server = ctx->config.l2tp_server;
} else {
l2tp_server->next = malloc(sizeof(bbl_l2tp_server_t));
l2tp_server->next = calloc(1, sizeof(bbl_l2tp_server_t));
l2tp_server = l2tp_server->next;
}
memset(l2tp_server, 0x0, sizeof(bbl_l2tp_server_t));
if (json_unpack(sub, "{s:s}", "name", &s) == 0) {
l2tp_server->host_name = strdup(s);
} else {
@@ -1477,13 +1465,12 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) {
size = json_array_size(section);
for (i = 0; i < size; i++) {
if (!stream_config) {
ctx->config.stream_config = malloc(sizeof(bbl_stream_config));
ctx->config.stream_config = calloc(1, sizeof(bbl_stream_config));
stream_config = ctx->config.stream_config;
} else {
stream_config->next = malloc(sizeof(bbl_stream_config));
stream_config->next = calloc(1, sizeof(bbl_stream_config));
stream_config = stream_config->next;
}
memset(stream_config, 0x0, sizeof(bbl_stream_config));
if (!json_parse_stream(ctx, json_array_get(section, i), stream_config)) {
return false;
}
@@ -1497,13 +1484,12 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) {
size = json_array_size(section);
for (i = 0; i < size; i++) {
if (!access_line_profile) {
ctx->config.access_line_profile = malloc(sizeof(bbl_access_line_profile_s));
ctx->config.access_line_profile = calloc(1, sizeof(bbl_access_line_profile_s));
access_line_profile = ctx->config.access_line_profile;
} else {
access_line_profile->next = malloc(sizeof(bbl_access_line_profile_s));
access_line_profile->next = calloc(1, sizeof(bbl_access_line_profile_s));
access_line_profile = access_line_profile->next;
}
memset(access_line_profile, 0x0, sizeof(bbl_access_line_profile_s));
if (!json_parse_access_line_profile(json_array_get(section, i), access_line_profile)) {
return false;
}
@@ -1513,12 +1499,16 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) {
return true;
}
/* bbl_config_load_json
/**
* bbl_config_load_json
*
* This functions is population the BBL context
* This function populates the BBL context
* from given JSON configuration file returning
* true is successfull or false if failed with
* error message printed to stderr.
* true if successfull or false if failed with
* error message printed to stderr.
*
* @param ctx JSON filename
* @param ctx global context
*/
bool
bbl_config_load_json (const char *filename, bbl_ctx_s *ctx) {
@@ -1536,10 +1526,73 @@ bbl_config_load_json (const char *filename, bbl_ctx_s *ctx) {
return result;
}
/* bbl_config_load_json
static bool
json_parse_config_streams (json_t *root, bbl_ctx_s *ctx) {
json_t *section = NULL;
int i, size;
bbl_stream_config *stream_config = ctx->config.stream_config;
if (json_typeof(root) != JSON_OBJECT) {
fprintf(stderr, "JSON config error: Configuration root element must object\n");
return false;
}
section = json_object_get(root, "streams");
if (json_is_array(section)) {
/* Config is provided as array (multiple streams) */
size = json_array_size(section);
for (i = 0; i < size; i++) {
if (!stream_config) {
ctx->config.stream_config = calloc(1, sizeof(bbl_stream_config));
stream_config = ctx->config.stream_config;
} else {
stream_config->next = calloc(1, sizeof(bbl_stream_config));
stream_config = stream_config->next;
}
if (!json_parse_stream(ctx, json_array_get(section, i), stream_config)) {
return false;
}
}
}
return true;
}
/**
* bbl_config_streams_load_json
*
* This function populates traffic streams
* from given JSON stream configuration file returning
* true if successfull or false if failed with
* error message printed to stderr.
*
* @param ctx JSON filename
* @param ctx global context
*/
bool
bbl_config_streams_load_json (const char *filename, bbl_ctx_s *ctx) {
json_t *root = NULL;
json_error_t error;
bool result = false;
root = json_load_file(filename, 0, &error);
if (root) {
result = json_parse_config_streams(root, ctx);
json_decref(root);
} else {
fprintf(stderr, "JSON stream config error: File %s Line %d: %s\n", filename, error.line, error.text);
}
return result;
}
/**
* bbl_config_init_defaults
*
* This functions is population the BBL context
* with default configuration values.
*
* @param ctx global context
*/
void
bbl_config_init_defaults (bbl_ctx_s *ctx) {
+3
View File
@@ -154,6 +154,9 @@ typedef struct bbl_a10nsp_config_
bool
bbl_config_load_json(const char *filename, bbl_ctx_s *ctx);
bool
bbl_config_streams_load_json(const char *filename, bbl_ctx_s *ctx);
void
bbl_config_init_defaults(bbl_ctx_s *ctx);
+13 -276
View File
@@ -18,8 +18,6 @@
#include <signal.h>
#include <errno.h>
#include <sys/stat.h>
#include <time.h>
#include <jansson.h>
#include "bbl.h"
#include "bbl_ctrl.h"
@@ -35,34 +33,10 @@
extern volatile bool g_teardown;
extern volatile bool g_teardown_request;
extern bool g_traffic;
typedef ssize_t callback_function(int fd, bbl_ctx_s *ctx, uint32_t session_id, json_t* arguments);
const char *
ppp_state_string(uint32_t state) {
switch(state) {
case BBL_PPP_CLOSED: return "Closed";
case BBL_PPP_INIT: return "Init";
case BBL_PPP_LOCAL_ACK: return "Local-Ack";
case BBL_PPP_PEER_ACK: return "Peer-Ack";
case BBL_PPP_OPENED: return "Opened";
case BBL_PPP_TERMINATE: return "Terminate";
default: return "N/A";
}
}
const char *
dhcp_state_string(uint32_t state) {
switch(state) {
case BBL_DHCP_INIT: return "Init";
case BBL_DHCP_SELECTING: return "Selecting";
case BBL_DHCP_REQUESTING: return "Requesting";
case BBL_DHCP_BOUND: return "Bound";
case BBL_DHCP_RENEWING: return "Renewing";
case BBL_DHCP_RELEASE: return "Releasing";
default: return "N/A";
}
}
static char *
string_or_na(char *string) {
if(string) {
@@ -392,245 +366,32 @@ ssize_t
bbl_ctrl_session_info(int fd, bbl_ctx_s *ctx, uint32_t session_id, json_t* arguments __attribute__((unused))) {
ssize_t result = 0;
json_t *root;
json_t *session_traffic = NULL;
json_t *a10nsp_session = NULL;
json_t *session_json;
bbl_session_s *session;
struct timespec now;
const char *ipv4 = NULL;
const char *ipv4_netmask = NULL;
const char *ipv4_gw = NULL;
const char *dns1 = NULL;
const char *dns2 = NULL;
const char *ipv6 = NULL;
const char *ipv6pd = NULL;
const char *ipv6_dns1 = NULL;
const char *ipv6_dns2 = NULL;
const char *dhcpv6_dns1 = NULL;
const char *dhcpv6_dns2 = NULL;
int flows = 0;
int flows_verified = 0;
uint32_t seconds = 0;
uint32_t dhcp_lease_expire = 0;
uint32_t dhcp_lease_expire_t1 = 0;
uint32_t dhcp_lease_expire_t2 = 0;
uint32_t dhcpv6_lease_expire = 0;
uint32_t dhcpv6_lease_expire_t1 = 0;
uint32_t dhcpv6_lease_expire_t2 = 0;
if(session_id == 0) {
/* session-id is mandatory */
return bbl_ctrl_status(fd, "error", 400, "missing session-id");
}
session = bbl_session_get(ctx, session_id);
if(session) {
if(session->ip_address) {
ipv4 = format_ipv4_address(&session->ip_address);
}
if(session->ip_netmask) {
ipv4_netmask = format_ipv4_address(&session->ip_netmask);
}
if(session->peer_ip_address) {
ipv4_gw = format_ipv4_address(&session->peer_ip_address);
}
if(session->dns1) {
dns1 = format_ipv4_address(&session->dns1);
}
if(session->dns2) {
dns2 = format_ipv4_address(&session->dns2);
}
if(session->ipv6_prefix.len) {
ipv6 = format_ipv6_prefix(&session->ipv6_prefix);
}
if(session->delegated_ipv6_prefix.len) {
ipv6pd = format_ipv6_prefix(&session->delegated_ipv6_prefix);
}
if(*(uint64_t*)session->ipv6_dns1) {
ipv6_dns1 = format_ipv6_address(&session->ipv6_dns1);
}
if(*(uint64_t*)session->ipv6_dns2) {
ipv6_dns2 = format_ipv6_address(&session->ipv6_dns2);
}
if(*(uint64_t*)session->dhcpv6_dns1) {
dhcpv6_dns1 = format_ipv6_address(&session->dhcpv6_dns1);
}
if(*(uint64_t*)session->dhcpv6_dns2) {
dhcpv6_dns2 = format_ipv6_address(&session->dhcpv6_dns2);
if(session) {
session_json = bbl_session_json(session);
if(!session_json) {
bbl_ctrl_status(fd, "error", 500, "internal error");
}
if(ctx->config.session_traffic_ipv4_pps || ctx->config.session_traffic_ipv6_pps || ctx->config.session_traffic_ipv6pd_pps) {
if(session->access_ipv4_tx_flow_id) flows++;
if(session->access_ipv6_tx_flow_id) flows++;
if(session->access_ipv6pd_tx_flow_id) flows++;
if(session->network_ipv4_tx_flow_id) flows++;
if(session->network_ipv6_tx_flow_id) flows++;
if(session->network_ipv6pd_tx_flow_id) flows++;
if(session->access_ipv4_rx_first_seq) flows_verified++;
if(session->access_ipv6_rx_first_seq) flows_verified++;
if(session->access_ipv6pd_rx_first_seq) flows_verified++;
if(session->network_ipv4_rx_first_seq) flows_verified++;
if(session->network_ipv6_rx_first_seq) flows_verified++;
if(session->network_ipv6pd_rx_first_seq) flows_verified++;
root = json_pack("{ss si so*}",
"status", "ok",
"code", 200,
"session-info", session_json);
session_traffic = json_pack("{si si si si si si si si si si si si si si si si si si si si si si si si si si}",
"total-flows", flows,
"verified-flows", flows_verified,
"first-seq-rx-access-ipv4", session->access_ipv4_rx_first_seq,
"first-seq-rx-access-ipv6", session->access_ipv6_rx_first_seq,
"first-seq-rx-access-ipv6pd", session->access_ipv6pd_rx_first_seq,
"first-seq-rx-network-ipv4", session->network_ipv4_rx_first_seq,
"first-seq-rx-network-ipv6", session->network_ipv6_rx_first_seq,
"first-seq-rx-network-ipv6pd", session->network_ipv6pd_rx_first_seq,
"access-tx-session-packets", session->stats.access_ipv4_tx,
"access-rx-session-packets", session->stats.access_ipv4_rx,
"access-rx-session-packets-loss", session->stats.access_ipv4_loss,
"network-tx-session-packets", session->stats.network_ipv4_tx,
"network-rx-session-packets", session->stats.network_ipv4_rx,
"network-rx-session-packets-loss", session->stats.network_ipv4_loss,
"access-tx-session-packets-ipv6", session->stats.access_ipv6_tx,
"access-rx-session-packets-ipv6", session->stats.access_ipv6_rx,
"access-rx-session-packets-ipv6-loss", session->stats.access_ipv6_loss,
"network-tx-session-packets-ipv6", session->stats.network_ipv6_tx,
"network-rx-session-packets-ipv6", session->stats.network_ipv6_rx,
"network-rx-session-packets-ipv6-loss", session->stats.network_ipv6_loss,
"access-tx-session-packets-ipv6pd", session->stats.access_ipv6pd_tx,
"access-rx-session-packets-ipv6pd", session->stats.access_ipv6pd_rx,
"access-rx-session-packets-ipv6pd-loss", session->stats.access_ipv6pd_loss,
"network-tx-session-packets-ipv6pd", session->stats.network_ipv6pd_tx,
"network-rx-session-packets-ipv6pd", session->stats.network_ipv6pd_rx,
"network-rx-session-packets-ipv6pd-loss", session->stats.network_ipv6pd_loss);
}
if(session->a10nsp_session) {
a10nsp_session = json_pack("{ss si sb sb ss* ss* si si}",
"interface", session->a10nsp_session->a10nsp_if->name,
"s-vlan", session->a10nsp_session->s_vlan,
"qinq-send", session->a10nsp_session->a10nsp_if->qinq,
"qinq-received", session->a10nsp_session->qinq_received,
"pppoe-aci", session->a10nsp_session->pppoe_aci,
"pppoe-ari", session->a10nsp_session->pppoe_ari,
"tx-packets", session->a10nsp_session->stats.packets_tx,
"rx-packets", session->a10nsp_session->stats.packets_rx);
}
if(session->access_type == ACCESS_TYPE_PPPOE) {
root = json_pack("{ss si s{ss si ss ss si si ss ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* si si si so* so*}}",
"status", "ok",
"code", 200,
"session-info",
"type", "pppoe",
"session-id", session->session_id,
"session-state", session_state_string(session->session_state),
"interface", session->interface->name,
"outer-vlan", session->vlan_key.outer_vlan_id,
"inner-vlan", session->vlan_key.inner_vlan_id,
"mac", format_mac_address(session->client_mac),
"username", session->username,
"agent-circuit-id", session->agent_circuit_id,
"agent-remote-id", session->agent_remote_id,
"reply-message", session->reply_message,
"connection-status-message", session->connections_status_message,
"lcp-state", ppp_state_string(session->lcp_state),
"ipcp-state", ppp_state_string(session->ipcp_state),
"ip6cp-state", ppp_state_string(session->ip6cp_state),
"ipv4-address", ipv4,
"ipv4-dns1", dns1,
"ipv4-dns2", dns2,
"ipv6-prefix", ipv6,
"ipv6-delegated-prefix", ipv6pd,
"ipv6-dns1", ipv6_dns1,
"ipv6-dns2", ipv6_dns2,
"dhcpv6-state", dhcp_state_string(session->dhcpv6_state),
"dhcpv6-dns1", dhcpv6_dns1,
"dhcpv6-dns2", dhcpv6_dns2,
"tx-packets", session->stats.packets_tx,
"rx-packets", session->stats.packets_rx,
"rx-fragmented-packets", session->stats.ipv4_fragmented_rx,
"session-traffic", session_traffic,
"a10nsp", a10nsp_session);
} else {
clock_gettime(CLOCK_MONOTONIC, &now);
if(session->dhcp_lease_timestamp.tv_sec && now.tv_sec > session->dhcp_lease_timestamp.tv_sec) {
seconds = now.tv_sec - session->dhcp_lease_timestamp.tv_sec;
}
if(seconds <= session->dhcp_lease_time) dhcp_lease_expire = session->dhcp_lease_time - seconds;
if(seconds <= session->dhcp_t1) dhcp_lease_expire_t1 = session->dhcp_t1 - seconds;
if(seconds <= session->dhcp_t2) dhcp_lease_expire_t2 = session->dhcp_t2 - seconds;
if(session->dhcpv6_lease_timestamp.tv_sec && now.tv_sec > session->dhcpv6_lease_timestamp.tv_sec) {
seconds = now.tv_sec - session->dhcpv6_lease_timestamp.tv_sec;
}
if(seconds <= session->dhcpv6_lease_time) dhcpv6_lease_expire = session->dhcpv6_lease_time - seconds;
if(seconds <= session->dhcpv6_t1) dhcpv6_lease_expire_t1 = session->dhcpv6_t1 - seconds;
if(seconds <= session->dhcpv6_t2) dhcpv6_lease_expire_t2 = session->dhcpv6_t2 - seconds;
root = json_pack("{ss si s{ss si ss ss si si ss ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* si si si si si si si si si si si si ss* si si si si si si si si si si si si ss* ss* si si si so* so*}}",
"status", "ok",
"code", 200,
"session-info",
"type", "ipoe",
"session-id", session->session_id,
"session-state", session_state_string(session->session_state),
"interface", session->interface->name,
"outer-vlan", session->vlan_key.outer_vlan_id,
"inner-vlan", session->vlan_key.inner_vlan_id,
"mac", format_mac_address(session->client_mac),
"agent-circuit-id", session->agent_circuit_id,
"agent-remote-id", session->agent_remote_id,
"ipv4-address", ipv4,
"ipv4-netmask", ipv4_netmask,
"ipv4-gateway", ipv4_gw,
"ipv4-dns1", dns1,
"ipv4-dns2", dns2,
"ipv6-prefix", ipv6,
"ipv6-delegated-prefix", ipv6pd,
"ipv6-dns1", ipv6_dns1,
"ipv6-dns2", ipv6_dns2,
"dhcp-state", dhcp_state_string(session->dhcp_state),
"dhcp-server", format_ipv4_address(&session->dhcp_server_identifier),
"dhcp-lease-time", session->dhcp_lease_time,
"dhcp-lease-expire", dhcp_lease_expire,
"dhcp-lease-expire-t1", dhcp_lease_expire_t1,
"dhcp-lease-expire-t2", dhcp_lease_expire_t2,
"dhcp-tx", session->stats.dhcp_tx,
"dhcp-rx", session->stats.dhcp_rx,
"dhcp-tx-discover", session->stats.dhcp_tx_discover,
"dhcp-rx-offer", session->stats.dhcp_rx_offer,
"dhcp-tx-request", session->stats.dhcp_tx_request,
"dhcp-rx-ack", session->stats.dhcp_rx_ack,
"dhcp-rx-nak", session->stats.dhcp_rx_nak,
"dhcp-tx-release", session->stats.dhcp_tx_release,
"dhcpv6-state", dhcp_state_string(session->dhcpv6_state),
"dhcpv6-lease-time", session->dhcpv6_lease_time,
"dhcpv6-lease-expire", dhcpv6_lease_expire,
"dhcpv6-lease-expire-t1", dhcpv6_lease_expire_t1,
"dhcpv6-lease-expire-t2", dhcpv6_lease_expire_t2,
"dhcpv6-tx", session->stats.dhcpv6_tx,
"dhcpv6-rx", session->stats.dhcpv6_rx,
"dhcpv6-tx-solicit", session->stats.dhcpv6_tx_solicit,
"dhcpv6-rx-advertise", session->stats.dhcpv6_rx_advertise,
"dhcpv6-tx-request", session->stats.dhcpv6_tx_request,
"dhcpv6-rx-reply", session->stats.dhcpv6_rx_reply,
"dhcpv6-tx-renew", session->stats.dhcpv6_tx_renew,
"dhcpv6-tx-release", session->stats.dhcpv6_tx_release,
"dhcpv6-dns1", dhcpv6_dns1,
"dhcpv6-dns2", dhcpv6_dns2,
"tx-packets", session->stats.packets_tx,
"rx-packets", session->stats.packets_rx,
"rx-fragmented-packets", session->stats.ipv4_fragmented_rx,
"session-traffic", session_traffic,
"a10nsp", a10nsp_session);
}
if(root) {
result = json_dumpfd(root, fd, 0);
json_decref(root);
} else {
result = bbl_ctrl_status(fd, "error", 500, "internal error");
json_decref(session_traffic);
json_decref(session_json);
}
return result;
} else {
@@ -1201,31 +962,7 @@ bbl_ctrl_session_streams(int fd, bbl_ctx_s *ctx, uint32_t session_id, json_t* ar
json_streams = json_array();
while(stream) {
json_stream = json_pack("{ss ss si si si si si si si si si si si si si si si si si si sf sf sf}",
"name", stream->config->name,
"direction", stream->direction == STREAM_DIRECTION_UP ? "upstream" : "downstream",
"flow-id", stream->flow_id,
"rx-first-seq", stream->rx_first_seq,
"rx-last-seq", stream->rx_last_seq,
"rx-tos-tc", stream->rx_priority,
"rx-outer-vlan-pbit", stream->rx_outer_vlan_pbit,
"rx-inner-vlan-pbit", stream->rx_inner_vlan_pbit,
"rx-len", stream->rx_len,
"tx-len", stream->tx_len,
"rx-packets", stream->packets_rx,
"tx-packets", stream->packets_tx,
"rx-loss", stream->loss,
"rx-delay-nsec-min", stream->min_delay_ns,
"rx-delay-nsec-max", stream->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,
"rx-bps-l2", stream->rate_packets_rx.avg * stream->rx_len * 8,
"rx-bps-l3", stream->rate_packets_rx.avg * stream->config->length * 8,
"tx-mbps-l2", (double)(stream->rate_packets_tx.avg * stream->tx_len * 8) / 1000000.0,
"rx-mbps-l2", (double)(stream->rate_packets_rx.avg * stream->rx_len * 8) / 1000000.0,
"rx-mbps-l3", (double)(stream->rate_packets_rx.avg * stream->config->length * 8) / 1000000.0);
json_stream = bbl_stream_json(stream);
json_array_append(json_streams, json_stream);
stream = stream->next;
}
+4
View File
@@ -121,6 +121,8 @@ typedef struct bbl_ctx_
uint32_t sessions_established_max;
uint32_t session_traffic_flows;
uint32_t session_traffic_flows_verified;
uint32_t stream_traffic_flows;
uint32_t stream_traffic_flows_verified;
} stats;
bool multicast_traffic;
@@ -139,6 +141,8 @@ typedef struct bbl_ctx_
bbl_io_mode_t io_mode;
char *json_report_filename;
bool json_report_sessions; /* Include sessions */
bool json_report_streams; /* Include streams */
bbl_secondary_ip_s *secondary_ip_addresses;
bbl_secondary_ip6_s *secondary_ip6_addresses;
+62 -53
View File
@@ -34,6 +34,8 @@ extern volatile bool g_teardown;
extern volatile bool g_teardown_request;
extern volatile bool g_banner;
extern bool g_traffic;
/* This global variable is used to switch between access interfaces. */
uint8_t g_access_if_selected = 0;
uint8_t g_network_if_selected = 0;
@@ -71,22 +73,6 @@ bbl_init_stats_win(bbl_ctx_s *ctx)
}
}
static void
enable_disable_traffic(bbl_ctx_s *ctx, bool status)
{
bbl_session_s *session;
uint32_t i;
/* Iterate over all sessions */
for(i = 0; i < ctx->sessions; i++) {
session = ctx->session_list[i];
if(session) {
session->session_traffic = status;
session->stream_traffic = status;
}
}
}
/*
* Interactive keyboard reader
*/
@@ -165,11 +151,11 @@ bbl_read_key_job (timer_s *timer)
bbl_init_stats_win(ctx);
break;
case KEY_F(7):
enable_disable_traffic(ctx, true);
g_traffic = true;
LOG(INFO, "Start traffic\n");
break;
case KEY_F(8):
enable_disable_traffic(ctx, false);
g_traffic = false;
LOG(INFO, "Stop traffic\n");
break;
case KEY_F(9):
@@ -350,6 +336,23 @@ bbl_stats_job (timer_s *timer)
wprintw(stats_win, "]\n");
}
if(ctx->stats.stream_traffic_flows) {
wprintw(stats_win, "\nTraffic Streams\n");
wprintw(stats_win, " Flows %10lu\n", ctx->stats.stream_traffic_flows);
/* Progress bar traffic stream flows */
wprintw(stats_win, " Verified %10lu [", ctx->stats.stream_traffic_flows_verified);
if(ctx->stats.stream_traffic_flows == ctx->stats.stream_traffic_flows_verified) {
wattron(stats_win, COLOR_PAIR(COLOR_GREEN));
wprintw(stats_win, "%s", bbl_format_progress(ctx->stats.stream_traffic_flows, ctx->stats.stream_traffic_flows_verified));
wattroff(stats_win, COLOR_PAIR(COLOR_GREEN));
} else {
wattron(stats_win, COLOR_PAIR(COLOR_BLACK));
wprintw(stats_win, "%s", bbl_format_progress(ctx->stats.stream_traffic_flows, ctx->stats.stream_traffic_flows_verified));
wattroff(stats_win, COLOR_PAIR(COLOR_BLACK));
}
wprintw(stats_win, "]\n");
}
if(network_if) {
wprintw(stats_win, "\nNetwork Interface (");
for(i = 0; i < ctx->interfaces.network_if_count; i++) {
@@ -367,21 +370,23 @@ bbl_stats_job (timer_s *timer)
wprintw(stats_win, " Rx Packets %10lu |%7lu PPS %10lu Kbps\n",
network_if->stats.packets_rx, network_if->stats.rate_packets_rx.avg,
network_if->stats.rate_bytes_rx.avg * 8 / 1000);
wprintw(stats_win, " Tx Session Packets %10lu |%7lu PPS\n",
network_if->stats.session_ipv4_tx, network_if->stats.rate_session_ipv4_tx.avg);
wprintw(stats_win, " Rx Session Packets %10lu |%7lu PPS %10lu Loss\n",
network_if->stats.session_ipv4_rx, network_if->stats.rate_session_ipv4_rx.avg,
network_if->stats.session_ipv4_loss);
wprintw(stats_win, " Tx Session Packets IPv6 %10lu |%7lu PPS\n",
network_if->stats.session_ipv6_tx, network_if->stats.rate_session_ipv6_tx.avg);
wprintw(stats_win, " Rx Session Packets IPv6 %10lu |%7lu PPS %10lu Loss\n",
network_if->stats.session_ipv6_rx, network_if->stats.rate_session_ipv6_rx.avg,
network_if->stats.session_ipv6_loss);
wprintw(stats_win, " Tx Session Packets IPv6PD %10lu |%7lu PPS\n",
network_if->stats.session_ipv6pd_tx, network_if->stats.rate_session_ipv6pd_tx.avg);
wprintw(stats_win, " Rx Session Packets IPv6PD %10lu |%7lu PPS %10lu Loss\n",
network_if->stats.session_ipv6pd_rx, network_if->stats.rate_session_ipv6pd_rx.avg,
network_if->stats.session_ipv6pd_loss);
if(ctx->stats.session_traffic_flows) {
wprintw(stats_win, " Tx Session Packets %10lu |%7lu PPS\n",
network_if->stats.session_ipv4_tx, network_if->stats.rate_session_ipv4_tx.avg);
wprintw(stats_win, " Rx Session Packets %10lu |%7lu PPS %10lu Loss\n",
network_if->stats.session_ipv4_rx, network_if->stats.rate_session_ipv4_rx.avg,
network_if->stats.session_ipv4_loss);
wprintw(stats_win, " Tx Session Packets IPv6 %10lu |%7lu PPS\n",
network_if->stats.session_ipv6_tx, network_if->stats.rate_session_ipv6_tx.avg);
wprintw(stats_win, " Rx Session Packets IPv6 %10lu |%7lu PPS %10lu Loss\n",
network_if->stats.session_ipv6_rx, network_if->stats.rate_session_ipv6_rx.avg,
network_if->stats.session_ipv6_loss);
wprintw(stats_win, " Tx Session Packets IPv6PD %10lu |%7lu PPS\n",
network_if->stats.session_ipv6pd_tx, network_if->stats.rate_session_ipv6pd_tx.avg);
wprintw(stats_win, " Rx Session Packets IPv6PD %10lu |%7lu PPS %10lu Loss\n",
network_if->stats.session_ipv6pd_rx, network_if->stats.rate_session_ipv6pd_rx.avg,
network_if->stats.session_ipv6pd_loss);
}
wprintw(stats_win, " Tx Multicast Packets %10lu |%7lu PPS\n",
network_if->stats.mc_tx, network_if->stats.rate_mc_tx.avg);
}
@@ -403,11 +408,13 @@ bbl_stats_job (timer_s *timer)
wprintw(stats_win, " Rx Packets %10lu |%7lu PPS %10lu Kbps\n",
a10nsp_if->stats.packets_rx, a10nsp_if->stats.rate_packets_rx.avg,
a10nsp_if->stats.rate_bytes_rx.avg * 8 / 1000);
wprintw(stats_win, " Tx Session Packets %10lu |%7lu PPS\n",
a10nsp_if->stats.session_ipv4_tx, a10nsp_if->stats.rate_session_ipv4_tx.avg);
wprintw(stats_win, " Rx Session Packets %10lu |%7lu PPS %10lu Loss\n",
a10nsp_if->stats.session_ipv4_rx, a10nsp_if->stats.rate_session_ipv4_rx.avg,
a10nsp_if->stats.session_ipv4_loss);
if(ctx->stats.session_traffic_flows) {
wprintw(stats_win, " Tx Session Packets %10lu |%7lu PPS\n",
a10nsp_if->stats.session_ipv4_tx, a10nsp_if->stats.rate_session_ipv4_tx.avg);
wprintw(stats_win, " Rx Session Packets %10lu |%7lu PPS %10lu Loss\n",
a10nsp_if->stats.session_ipv4_rx, a10nsp_if->stats.rate_session_ipv4_rx.avg,
a10nsp_if->stats.session_ipv4_loss);
}
}
if(access_if) {
@@ -427,21 +434,23 @@ bbl_stats_job (timer_s *timer)
wprintw(stats_win, " Rx Packets %10lu |%7lu PPS %10lu Kbps\n",
access_if->stats.packets_rx, access_if->stats.rate_packets_rx.avg,
access_if->stats.rate_bytes_rx.avg * 8 / 1000);
wprintw(stats_win, " Tx Session Packets %10lu |%7lu PPS\n",
access_if->stats.session_ipv4_tx, access_if->stats.rate_session_ipv4_tx.avg);
wprintw(stats_win, " Rx Session Packets %10lu |%7lu PPS %10lu Loss %lu Wrong Session\n",
access_if->stats.session_ipv4_rx, access_if->stats.rate_session_ipv4_rx.avg,
access_if->stats.session_ipv4_loss, access_if->stats.session_ipv4_wrong_session);
wprintw(stats_win, " Tx Session Packets IPv6 %10lu |%7lu PPS\n",
access_if->stats.session_ipv6_tx, access_if->stats.rate_session_ipv6_tx.avg);
wprintw(stats_win, " Rx Session Packets IPv6 %10lu |%7lu PPS %10lu Loss %lu Wrong Session\n",
access_if->stats.session_ipv6_rx, access_if->stats.rate_session_ipv6_rx.avg,
access_if->stats.session_ipv6_loss, access_if->stats.session_ipv6_wrong_session);
wprintw(stats_win, " Tx Session Packets IPv6PD %10lu |%7lu PPS\n",
access_if->stats.session_ipv6pd_tx, access_if->stats.rate_session_ipv6pd_tx.avg);
wprintw(stats_win, " Rx Session Packets IPv6PD %10lu |%7lu PPS %10lu Loss %lu Wrong Session\n",
access_if->stats.session_ipv6pd_rx, access_if->stats.rate_session_ipv6pd_rx.avg,
access_if->stats.session_ipv6pd_loss, access_if->stats.session_ipv6pd_wrong_session);
if(ctx->stats.session_traffic_flows) {
wprintw(stats_win, " Tx Session Packets %10lu |%7lu PPS\n",
access_if->stats.session_ipv4_tx, access_if->stats.rate_session_ipv4_tx.avg);
wprintw(stats_win, " Rx Session Packets %10lu |%7lu PPS %10lu Loss %lu Wrong Session\n",
access_if->stats.session_ipv4_rx, access_if->stats.rate_session_ipv4_rx.avg,
access_if->stats.session_ipv4_loss, access_if->stats.session_ipv4_wrong_session);
wprintw(stats_win, " Tx Session Packets IPv6 %10lu |%7lu PPS\n",
access_if->stats.session_ipv6_tx, access_if->stats.rate_session_ipv6_tx.avg);
wprintw(stats_win, " Rx Session Packets IPv6 %10lu |%7lu PPS %10lu Loss %lu Wrong Session\n",
access_if->stats.session_ipv6_rx, access_if->stats.rate_session_ipv6_rx.avg,
access_if->stats.session_ipv6_loss, access_if->stats.session_ipv6_wrong_session);
wprintw(stats_win, " Tx Session Packets IPv6PD %10lu |%7lu PPS\n",
access_if->stats.session_ipv6pd_tx, access_if->stats.rate_session_ipv6pd_tx.avg);
wprintw(stats_win, " Rx Session Packets IPv6PD %10lu |%7lu PPS %10lu Loss %lu Wrong Session\n",
access_if->stats.session_ipv6pd_rx, access_if->stats.rate_session_ipv6pd_rx.avg,
access_if->stats.session_ipv6pd_loss, access_if->stats.session_ipv6pd_wrong_session);
}
wprintw(stats_win, " Rx Multicast Packets %10lu |%7lu PPS %10lu Loss\n",
access_if->stats.mc_rx, access_if->stats.rate_mc_rx.avg,
access_if->stats.mc_loss);
+1
View File
@@ -1002,6 +1002,7 @@ bbl_l2tp_data_rx(bbl_ethernet_header_t *eth, bbl_l2tp_t *l2tp, bbl_interface_s *
}
if(!stream->rx_first_seq) {
stream->rx_first_seq = bbl->flow_seq;
interface->ctx->stats.stream_traffic_flows_verified++;
} else {
if(stream->rx_last_seq +1 != bbl->flow_seq) {
stream->loss++;
+12
View File
@@ -304,6 +304,7 @@ bbl_rx_stream(bbl_interface_s *interface, bbl_ethernet_header_t *eth, bbl_bbl_t
}
if(!stream->rx_first_seq) {
stream->rx_first_seq = bbl->flow_seq;
interface->ctx->stats.stream_traffic_flows_verified++;
} else {
if(stream->rx_last_seq +1 != bbl->flow_seq) {
stream->loss++;
@@ -1880,6 +1881,17 @@ bbl_rx_handler_network(bbl_ethernet_header_t *eth, bbl_interface_s *interface) {
default:
break;
}
} else {
/* Accept RAW streams */
switch (bbl->sub_type) {
case BBL_SUB_TYPE_IPV4:
if(ipv4) bbl_rx_stream(interface, eth, bbl, ipv4->tos);
break;
case BBL_SUB_TYPE_IPV6:
case BBL_SUB_TYPE_IPV6PD:
if(ipv6) bbl_rx_stream(interface, eth, bbl, ipv6->tos);
break;
}
}
}
} else {
+263
View File
@@ -32,6 +32,32 @@ session_state_string(uint32_t state) {
}
}
const char *
ppp_state_string(uint32_t state) {
switch(state) {
case BBL_PPP_CLOSED: return "Closed";
case BBL_PPP_INIT: return "Init";
case BBL_PPP_LOCAL_ACK: return "Local-Ack";
case BBL_PPP_PEER_ACK: return "Peer-Ack";
case BBL_PPP_OPENED: return "Opened";
case BBL_PPP_TERMINATE: return "Terminate";
default: return "N/A";
}
}
const char *
dhcp_state_string(uint32_t state) {
switch(state) {
case BBL_DHCP_INIT: return "Init";
case BBL_DHCP_SELECTING: return "Selecting";
case BBL_DHCP_REQUESTING: return "Requesting";
case BBL_DHCP_BOUND: return "Bound";
case BBL_DHCP_RENEWING: return "Renewing";
case BBL_DHCP_RELEASE: return "Releasing";
default: return "N/A";
}
}
void
bbl_session_tx_qnode_insert(bbl_session_s *session)
{
@@ -649,4 +675,241 @@ NEXT:
}
}
return true;
}
json_t *
bbl_session_json(bbl_session_s *session)
{
json_t *root = NULL;
json_t *session_traffic = NULL;
json_t *a10nsp_session = NULL;
bbl_ctx_s *ctx;
struct timespec now;
const char *ipv4 = NULL;
const char *ipv4_netmask = NULL;
const char *ipv4_gw = NULL;
const char *dns1 = NULL;
const char *dns2 = NULL;
const char *ipv6 = NULL;
const char *ipv6pd = NULL;
const char *ipv6_dns1 = NULL;
const char *ipv6_dns2 = NULL;
const char *dhcpv6_dns1 = NULL;
const char *dhcpv6_dns2 = NULL;
int flows = 0;
int flows_verified = 0;
uint32_t seconds = 0;
uint32_t dhcp_lease_expire = 0;
uint32_t dhcp_lease_expire_t1 = 0;
uint32_t dhcp_lease_expire_t2 = 0;
uint32_t dhcpv6_lease_expire = 0;
uint32_t dhcpv6_lease_expire_t1 = 0;
uint32_t dhcpv6_lease_expire_t2 = 0;
if(!session) {
return NULL;
}
ctx = session->interface->ctx;
if(session->ip_address) {
ipv4 = format_ipv4_address(&session->ip_address);
}
if(session->ip_netmask) {
ipv4_netmask = format_ipv4_address(&session->ip_netmask);
}
if(session->peer_ip_address) {
ipv4_gw = format_ipv4_address(&session->peer_ip_address);
}
if(session->dns1) {
dns1 = format_ipv4_address(&session->dns1);
}
if(session->dns2) {
dns2 = format_ipv4_address(&session->dns2);
}
if(session->ipv6_prefix.len) {
ipv6 = format_ipv6_prefix(&session->ipv6_prefix);
}
if(session->delegated_ipv6_prefix.len) {
ipv6pd = format_ipv6_prefix(&session->delegated_ipv6_prefix);
}
if(*(uint64_t*)session->ipv6_dns1) {
ipv6_dns1 = format_ipv6_address(&session->ipv6_dns1);
}
if(*(uint64_t*)session->ipv6_dns2) {
ipv6_dns2 = format_ipv6_address(&session->ipv6_dns2);
}
if(*(uint64_t*)session->dhcpv6_dns1) {
dhcpv6_dns1 = format_ipv6_address(&session->dhcpv6_dns1);
}
if(*(uint64_t*)session->dhcpv6_dns2) {
dhcpv6_dns2 = format_ipv6_address(&session->dhcpv6_dns2);
}
if(ctx->config.session_traffic_ipv4_pps || ctx->config.session_traffic_ipv6_pps || ctx->config.session_traffic_ipv6pd_pps) {
if(session->access_ipv4_tx_flow_id) flows++;
if(session->access_ipv6_tx_flow_id) flows++;
if(session->access_ipv6pd_tx_flow_id) flows++;
if(session->network_ipv4_tx_flow_id) flows++;
if(session->network_ipv6_tx_flow_id) flows++;
if(session->network_ipv6pd_tx_flow_id) flows++;
if(session->access_ipv4_rx_first_seq) flows_verified++;
if(session->access_ipv6_rx_first_seq) flows_verified++;
if(session->access_ipv6pd_rx_first_seq) flows_verified++;
if(session->network_ipv4_rx_first_seq) flows_verified++;
if(session->network_ipv6_rx_first_seq) flows_verified++;
if(session->network_ipv6pd_rx_first_seq) flows_verified++;
session_traffic = json_pack("{si si si si si si si si si si si si si si si si si si si si si si si si si si}",
"total-flows", flows,
"verified-flows", flows_verified,
"first-seq-rx-access-ipv4", session->access_ipv4_rx_first_seq,
"first-seq-rx-access-ipv6", session->access_ipv6_rx_first_seq,
"first-seq-rx-access-ipv6pd", session->access_ipv6pd_rx_first_seq,
"first-seq-rx-network-ipv4", session->network_ipv4_rx_first_seq,
"first-seq-rx-network-ipv6", session->network_ipv6_rx_first_seq,
"first-seq-rx-network-ipv6pd", session->network_ipv6pd_rx_first_seq,
"access-tx-session-packets", session->stats.access_ipv4_tx,
"access-rx-session-packets", session->stats.access_ipv4_rx,
"access-rx-session-packets-loss", session->stats.access_ipv4_loss,
"network-tx-session-packets", session->stats.network_ipv4_tx,
"network-rx-session-packets", session->stats.network_ipv4_rx,
"network-rx-session-packets-loss", session->stats.network_ipv4_loss,
"access-tx-session-packets-ipv6", session->stats.access_ipv6_tx,
"access-rx-session-packets-ipv6", session->stats.access_ipv6_rx,
"access-rx-session-packets-ipv6-loss", session->stats.access_ipv6_loss,
"network-tx-session-packets-ipv6", session->stats.network_ipv6_tx,
"network-rx-session-packets-ipv6", session->stats.network_ipv6_rx,
"network-rx-session-packets-ipv6-loss", session->stats.network_ipv6_loss,
"access-tx-session-packets-ipv6pd", session->stats.access_ipv6pd_tx,
"access-rx-session-packets-ipv6pd", session->stats.access_ipv6pd_rx,
"access-rx-session-packets-ipv6pd-loss", session->stats.access_ipv6pd_loss,
"network-tx-session-packets-ipv6pd", session->stats.network_ipv6pd_tx,
"network-rx-session-packets-ipv6pd", session->stats.network_ipv6pd_rx,
"network-rx-session-packets-ipv6pd-loss", session->stats.network_ipv6pd_loss);
}
if(session->a10nsp_session) {
a10nsp_session = json_pack("{ss si sb sb ss* ss* si si}",
"interface", session->a10nsp_session->a10nsp_if->name,
"s-vlan", session->a10nsp_session->s_vlan,
"qinq-send", session->a10nsp_session->a10nsp_if->qinq,
"qinq-received", session->a10nsp_session->qinq_received,
"pppoe-aci", session->a10nsp_session->pppoe_aci,
"pppoe-ari", session->a10nsp_session->pppoe_ari,
"tx-packets", session->a10nsp_session->stats.packets_tx,
"rx-packets", session->a10nsp_session->stats.packets_rx);
}
if(session->access_type == ACCESS_TYPE_PPPOE) {
root = json_pack("{ss si ss ss si si ss ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* si si si so* so*}",
"type", "pppoe",
"session-id", session->session_id,
"session-state", session_state_string(session->session_state),
"interface", session->interface->name,
"outer-vlan", session->vlan_key.outer_vlan_id,
"inner-vlan", session->vlan_key.inner_vlan_id,
"mac", format_mac_address(session->client_mac),
"username", session->username,
"agent-circuit-id", session->agent_circuit_id,
"agent-remote-id", session->agent_remote_id,
"reply-message", session->reply_message,
"connection-status-message", session->connections_status_message,
"lcp-state", ppp_state_string(session->lcp_state),
"ipcp-state", ppp_state_string(session->ipcp_state),
"ip6cp-state", ppp_state_string(session->ip6cp_state),
"ipv4-address", ipv4,
"ipv4-dns1", dns1,
"ipv4-dns2", dns2,
"ipv6-prefix", ipv6,
"ipv6-delegated-prefix", ipv6pd,
"ipv6-dns1", ipv6_dns1,
"ipv6-dns2", ipv6_dns2,
"dhcpv6-state", dhcp_state_string(session->dhcpv6_state),
"dhcpv6-dns1", dhcpv6_dns1,
"dhcpv6-dns2", dhcpv6_dns2,
"tx-packets", session->stats.packets_tx,
"rx-packets", session->stats.packets_rx,
"rx-fragmented-packets", session->stats.ipv4_fragmented_rx,
"session-traffic", session_traffic,
"a10nsp", a10nsp_session);
} else {
clock_gettime(CLOCK_MONOTONIC, &now);
if(session->dhcp_lease_timestamp.tv_sec && now.tv_sec > session->dhcp_lease_timestamp.tv_sec) {
seconds = now.tv_sec - session->dhcp_lease_timestamp.tv_sec;
}
if(seconds <= session->dhcp_lease_time) dhcp_lease_expire = session->dhcp_lease_time - seconds;
if(seconds <= session->dhcp_t1) dhcp_lease_expire_t1 = session->dhcp_t1 - seconds;
if(seconds <= session->dhcp_t2) dhcp_lease_expire_t2 = session->dhcp_t2 - seconds;
if(session->dhcpv6_lease_timestamp.tv_sec && now.tv_sec > session->dhcpv6_lease_timestamp.tv_sec) {
seconds = now.tv_sec - session->dhcpv6_lease_timestamp.tv_sec;
}
if(seconds <= session->dhcpv6_lease_time) dhcpv6_lease_expire = session->dhcpv6_lease_time - seconds;
if(seconds <= session->dhcpv6_t1) dhcpv6_lease_expire_t1 = session->dhcpv6_t1 - seconds;
if(seconds <= session->dhcpv6_t2) dhcpv6_lease_expire_t2 = session->dhcpv6_t2 - seconds;
root = json_pack("{ss si ss ss si si ss ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* ss* si si si si si si si si si si si si ss* si si si si si si si si si si si si ss* ss* si si si so* so*}",
"type", "ipoe",
"session-id", session->session_id,
"session-state", session_state_string(session->session_state),
"interface", session->interface->name,
"outer-vlan", session->vlan_key.outer_vlan_id,
"inner-vlan", session->vlan_key.inner_vlan_id,
"mac", format_mac_address(session->client_mac),
"agent-circuit-id", session->agent_circuit_id,
"agent-remote-id", session->agent_remote_id,
"ipv4-address", ipv4,
"ipv4-netmask", ipv4_netmask,
"ipv4-gateway", ipv4_gw,
"ipv4-dns1", dns1,
"ipv4-dns2", dns2,
"ipv6-prefix", ipv6,
"ipv6-delegated-prefix", ipv6pd,
"ipv6-dns1", ipv6_dns1,
"ipv6-dns2", ipv6_dns2,
"dhcp-state", dhcp_state_string(session->dhcp_state),
"dhcp-server", format_ipv4_address(&session->dhcp_server_identifier),
"dhcp-lease-time", session->dhcp_lease_time,
"dhcp-lease-expire", dhcp_lease_expire,
"dhcp-lease-expire-t1", dhcp_lease_expire_t1,
"dhcp-lease-expire-t2", dhcp_lease_expire_t2,
"dhcp-tx", session->stats.dhcp_tx,
"dhcp-rx", session->stats.dhcp_rx,
"dhcp-tx-discover", session->stats.dhcp_tx_discover,
"dhcp-rx-offer", session->stats.dhcp_rx_offer,
"dhcp-tx-request", session->stats.dhcp_tx_request,
"dhcp-rx-ack", session->stats.dhcp_rx_ack,
"dhcp-rx-nak", session->stats.dhcp_rx_nak,
"dhcp-tx-release", session->stats.dhcp_tx_release,
"dhcpv6-state", dhcp_state_string(session->dhcpv6_state),
"dhcpv6-lease-time", session->dhcpv6_lease_time,
"dhcpv6-lease-expire", dhcpv6_lease_expire,
"dhcpv6-lease-expire-t1", dhcpv6_lease_expire_t1,
"dhcpv6-lease-expire-t2", dhcpv6_lease_expire_t2,
"dhcpv6-tx", session->stats.dhcpv6_tx,
"dhcpv6-rx", session->stats.dhcpv6_rx,
"dhcpv6-tx-solicit", session->stats.dhcpv6_tx_solicit,
"dhcpv6-rx-advertise", session->stats.dhcpv6_rx_advertise,
"dhcpv6-tx-request", session->stats.dhcpv6_tx_request,
"dhcpv6-rx-reply", session->stats.dhcpv6_rx_reply,
"dhcpv6-tx-renew", session->stats.dhcpv6_tx_renew,
"dhcpv6-tx-release", session->stats.dhcpv6_tx_release,
"dhcpv6-dns1", dhcpv6_dns1,
"dhcpv6-dns2", dhcpv6_dns2,
"tx-packets", session->stats.packets_tx,
"rx-packets", session->stats.packets_rx,
"rx-fragmented-packets", session->stats.ipv4_fragmented_rx,
"session-traffic", session_traffic,
"a10nsp", a10nsp_session);
}
if(!root) {
if(a10nsp_session) json_decref(a10nsp_session);
if(session_traffic) json_decref(session_traffic);
}
return root;
}
+3
View File
@@ -417,4 +417,7 @@ bbl_session_clear(bbl_ctx_s *ctx, bbl_session_s *session);
bool
bbl_sessions_init(bbl_ctx_s *ctx);
json_t *
bbl_session_json(bbl_session_s *session);
#endif
+5 -3
View File
@@ -10,6 +10,8 @@
#include "bbl.h"
#include "bbl_session.h"
extern bool g_traffic;
void
bbl_session_traffic_ipv4(timer_s *timer)
{
@@ -31,7 +33,7 @@ bbl_session_traffic_ipv4(timer_s *timer)
return;
}
}
if(session->session_traffic) {
if(g_traffic && session->session_traffic) {
session->send_requests |= BBL_SEND_SESSION_IPV4;
bbl_session_tx_qnode_insert(session);
session->network_send_requests |= BBL_SEND_SESSION_IPV4;
@@ -56,7 +58,7 @@ bbl_session_traffic_ipv6(timer_s *timer)
return;
}
}
if(session->session_traffic) {
if(g_traffic && session->session_traffic) {
if(session->ipv6_prefix.len) {
session->send_requests |= BBL_SEND_SESSION_IPV6;
session->network_send_requests |= BBL_SEND_SESSION_IPV6;
@@ -83,7 +85,7 @@ bbl_session_traffic_ipv6pd(timer_s *timer)
return;
}
}
if(session->session_traffic) {
if(g_traffic && session->session_traffic) {
if(session->delegated_ipv6_prefix.len) {
session->send_requests |= BBL_SEND_SESSION_IPV6PD;
session->network_send_requests |= BBL_SEND_SESSION_IPV6PD;
+305 -235
View File
@@ -10,7 +10,8 @@
#include "bbl.h"
#include "bbl_stats.h"
#include <jansson.h>
#include "bbl_session.h"
#include "bbl_stream.h"
extern const char banner[];
@@ -196,13 +197,15 @@ bbl_stats_stdout (bbl_ctx_s *ctx, bbl_stats_t * stats) {
printf("%s", banner);
printf("Report:\n\n");
printf("Sessions PPPoE: %u IPoE: %u\n", ctx->sessions_pppoe, ctx->sessions_ipoe);
printf("Sessions established: %u/%u\n", ctx->sessions_established_max, ctx->config.sessions);
printf("DHCPv6 sessions established: %u\n", ctx->dhcpv6_established_max);
printf("Setup Time: %u ms\n", ctx->stats.setup_time);
printf("Setup Rate: %0.02lf CPS (MIN: %0.02lf AVG: %0.02lf MAX: %0.02lf)\n",
ctx->stats.cps, ctx->stats.cps_min, ctx->stats.cps_avg, ctx->stats.cps_max);
printf("Flapped: %u\n", ctx->sessions_flapped);
if(ctx->sessions) {
printf("Sessions PPPoE: %u IPoE: %u\n", ctx->sessions_pppoe, ctx->sessions_ipoe);
printf("Sessions established: %u/%u\n", ctx->sessions_established_max, ctx->sessions);
printf("DHCPv6 sessions established: %u\n", ctx->dhcpv6_established_max);
printf("Setup Time: %u ms\n", ctx->stats.setup_time);
printf("Setup Rate: %0.02lf CPS (MIN: %0.02lf AVG: %0.02lf MAX: %0.02lf)\n",
ctx->stats.cps, ctx->stats.cps_min, ctx->stats.cps_avg, ctx->stats.cps_max);
printf("Flapped: %u\n", ctx->sessions_flapped);
}
if(dict_count(ctx->li_flow_dict)) {
printf("\nLI Statistics:\n");
@@ -229,18 +232,20 @@ bbl_stats_stdout (bbl_ctx_s *ctx, bbl_stats_t * stats) {
printf("\nNetwork Interface ( %s ):\n", interface->name);
printf(" TX: %10lu packets\n", interface->stats.packets_tx);
printf(" RX: %10lu packets\n", interface->stats.packets_rx);
printf(" TX Session: %10lu packets\n",
interface->stats.session_ipv4_tx);
printf(" RX Session: %10lu packets (%lu loss)\n",
interface->stats.session_ipv4_rx, interface->stats.session_ipv4_loss);
printf(" TX Session IPv6: %10lu packets\n",
interface->stats.session_ipv6_tx);
printf(" RX Session IPv6: %10lu packets (%lu loss)\n",
interface->stats.session_ipv6_rx, interface->stats.session_ipv6_loss);
printf(" TX Session IPv6PD: %10lu packets\n",
interface->stats.session_ipv6pd_tx);
printf(" RX Session IPv6PD: %10lu packets (%lu loss)\n",
interface->stats.session_ipv6pd_rx, interface->stats.session_ipv6pd_loss);
if(ctx->stats.session_traffic_flows) {
printf(" TX Session: %10lu packets\n",
interface->stats.session_ipv4_tx);
printf(" RX Session: %10lu packets (%lu loss)\n",
interface->stats.session_ipv4_rx, interface->stats.session_ipv4_loss);
printf(" TX Session IPv6: %10lu packets\n",
interface->stats.session_ipv6_tx);
printf(" RX Session IPv6: %10lu packets (%lu loss)\n",
interface->stats.session_ipv6_rx, interface->stats.session_ipv6_loss);
printf(" TX Session IPv6PD: %10lu packets\n",
interface->stats.session_ipv6pd_tx);
printf(" RX Session IPv6PD: %10lu packets (%lu loss)\n",
interface->stats.session_ipv6pd_rx, interface->stats.session_ipv6pd_loss);
}
printf(" TX Multicast: %10lu packets\n",
interface->stats.mc_tx);
printf(" RX Drop Unknown: %10lu packets\n",
@@ -261,15 +266,17 @@ bbl_stats_stdout (bbl_ctx_s *ctx, bbl_stats_t * stats) {
printf("\nAccess Interface ( %s ):\n", interface->name);
printf(" TX: %10lu packets\n", interface->stats.packets_tx);
printf(" RX: %10lu packets\n", interface->stats.packets_rx);
printf(" TX Session: %10lu packets\n", interface->stats.session_ipv4_tx);
printf(" RX Session: %10lu packets (%lu loss, %lu wrong session)\n", interface->stats.session_ipv4_rx,
interface->stats.session_ipv4_loss, interface->stats.session_ipv4_wrong_session);
printf(" TX Session IPv6: %10lu packets\n", interface->stats.session_ipv6_tx);
printf(" RX Session IPv6: %10lu packets (%lu loss, %lu wrong session)\n", interface->stats.session_ipv6_rx,
interface->stats.session_ipv6_loss, interface->stats.session_ipv6_wrong_session);
printf(" TX Session IPv6PD: %10lu packets\n", interface->stats.session_ipv6pd_tx);
printf(" RX Session IPv6PD: %10lu packets (%lu loss, %lu wrong session)\n", interface->stats.session_ipv6pd_rx,
interface->stats.session_ipv6pd_loss, interface->stats.session_ipv6pd_wrong_session);
if(ctx->stats.session_traffic_flows) {
printf(" TX Session: %10lu packets\n", interface->stats.session_ipv4_tx);
printf(" RX Session: %10lu packets (%lu loss, %lu wrong session)\n", interface->stats.session_ipv4_rx,
interface->stats.session_ipv4_loss, interface->stats.session_ipv4_wrong_session);
printf(" TX Session IPv6: %10lu packets\n", interface->stats.session_ipv6_tx);
printf(" RX Session IPv6: %10lu packets (%lu loss, %lu wrong session)\n", interface->stats.session_ipv6_rx,
interface->stats.session_ipv6_loss, interface->stats.session_ipv6_wrong_session);
printf(" TX Session IPv6PD: %10lu packets\n", interface->stats.session_ipv6pd_tx);
printf(" RX Session IPv6PD: %10lu packets (%lu loss, %lu wrong session)\n", interface->stats.session_ipv6pd_rx,
interface->stats.session_ipv6pd_loss, interface->stats.session_ipv6pd_wrong_session);
}
printf(" RX Multicast: %10lu packets (%lu loss)\n", interface->stats.mc_rx,
interface->stats.mc_loss);
printf(" RX Drop Unknown: %10lu packets\n", interface->stats.packets_rx_drop_unknown);
@@ -316,9 +323,21 @@ bbl_stats_stdout (bbl_ctx_s *ctx, bbl_stats_t * stats) {
printf("\nA10NSP Interface ( %s ):\n", interface->name);
printf(" TX: %10lu packets\n", interface->stats.packets_tx);
printf(" RX: %10lu packets\n", interface->stats.packets_rx);
printf(" TX Session: %10lu packets\n", interface->stats.session_ipv4_tx);
printf(" RX Session: %10lu packets (%lu loss, %lu wrong session)\n", interface->stats.session_ipv4_rx,
interface->stats.session_ipv4_loss, interface->stats.session_ipv4_wrong_session);
if(ctx->stats.session_traffic_flows) {
printf(" TX Session: %10lu packets\n",
interface->stats.session_ipv4_tx);
printf(" RX Session: %10lu packets (%lu loss)\n",
interface->stats.session_ipv4_rx, interface->stats.session_ipv4_loss);
printf(" TX Session IPv6: %10lu packets\n",
interface->stats.session_ipv6_tx);
printf(" RX Session IPv6: %10lu packets (%lu loss)\n",
interface->stats.session_ipv6_rx, interface->stats.session_ipv6_loss);
printf(" TX Session IPv6PD: %10lu packets\n",
interface->stats.session_ipv6pd_tx);
printf(" RX Session IPv6PD: %10lu packets (%lu loss)\n",
interface->stats.session_ipv6pd_rx, interface->stats.session_ipv6pd_loss);
}
printf(" RX Drop Unknown: %10lu packets\n", interface->stats.packets_rx_drop_unknown);
printf(" TX Encode Error: %10lu packets\n", interface->stats.encode_errors);
printf(" RX Decode Error: %10lu packets\n", interface->stats.packets_rx_drop_decode_error);
@@ -364,6 +383,12 @@ bbl_stats_stdout (bbl_ctx_s *ctx, bbl_stats_t * stats) {
stats->max_network_ipv6pd_rx_first_seq, stats->max_network_ipv6pd_rx_seconds);
}
if(ctx->stats.stream_traffic_flows) {
printf("\nTraffic Streams:\n");
printf(" Verified Traffic Flows: %u/%u\n",
ctx->stats.stream_traffic_flows_verified, ctx->stats.stream_traffic_flows);
}
if(ctx->config.igmp_group_count > 1) {
printf("\nIGMP Config:\n");
printf(" Version: %d\n", ctx->config.igmp_version);
@@ -392,85 +417,85 @@ bbl_stats_stdout (bbl_ctx_s *ctx, bbl_stats_t * stats) {
void
bbl_stats_json (bbl_ctx_s *ctx, bbl_stats_t * stats) {
struct bbl_interface_ *interface;
bbl_session_s *session;
bbl_stream *stream;
int i;
struct dict_itor *itor;
uint32_t i;
json_t *root = NULL;
json_t *jobj = NULL;
json_t *jobj_array = NULL;
json_t *jobj_access_if = NULL;
json_t *jobj_network_if = NULL;
json_t *jobj_a10nsp_if = NULL;
json_t *jobj_l2tp = NULL;
json_t *jobj_li = NULL;
json_t *jobj_straffic = NULL;
json_t *jobj_multicast = NULL;
json_t *jobj_protocols = NULL;
json_t *root = NULL;
json_t *jobj = NULL;
json_t *jobj_array = NULL;
json_t *jobj_sub = NULL;
json_t *jobj_sub2 = NULL;
if(!ctx->config.json_report_filename) return;
root = json_object();
jobj = json_object();
json_object_set(jobj, "sessions", json_integer(ctx->config.sessions));
json_object_set(jobj, "sessions-pppoe", json_integer(ctx->sessions_pppoe));
json_object_set(jobj, "sessions-ipoe", json_integer(ctx->sessions_ipoe));
json_object_set(jobj, "sessions-established", json_integer(ctx->sessions_established_max));
json_object_set(jobj, "sessions-flapped", json_integer(ctx->sessions_flapped));
json_object_set(jobj, "setup-time-ms", json_integer(ctx->stats.setup_time));
json_object_set(jobj, "setup-rate-cps", json_real(ctx->stats.cps));
json_object_set(jobj, "setup-rate-cps-min", json_real(ctx->stats.cps_min));
json_object_set(jobj, "setup-rate-cps-avg", json_real(ctx->stats.cps_avg));
json_object_set(jobj, "setup-rate-cps-max", json_real(ctx->stats.cps_max));
json_object_set(jobj, "dhcp-sessions-established", json_integer(ctx->dhcp_established_max));
json_object_set(jobj, "dhcpv6-sessions-established", json_integer(ctx->dhcpv6_established_max));
if(ctx->sessions) {
json_object_set(jobj, "sessions", json_integer(ctx->config.sessions));
json_object_set(jobj, "sessions-pppoe", json_integer(ctx->sessions_pppoe));
json_object_set(jobj, "sessions-ipoe", json_integer(ctx->sessions_ipoe));
json_object_set(jobj, "sessions-established", json_integer(ctx->sessions_established_max));
json_object_set(jobj, "sessions-flapped", json_integer(ctx->sessions_flapped));
json_object_set(jobj, "setup-time-ms", json_integer(ctx->stats.setup_time));
json_object_set(jobj, "setup-rate-cps", json_real(ctx->stats.cps));
json_object_set(jobj, "setup-rate-cps-min", json_real(ctx->stats.cps_min));
json_object_set(jobj, "setup-rate-cps-avg", json_real(ctx->stats.cps_avg));
json_object_set(jobj, "setup-rate-cps-max", json_real(ctx->stats.cps_max));
json_object_set(jobj, "dhcp-sessions-established", json_integer(ctx->dhcp_established_max));
json_object_set(jobj, "dhcpv6-sessions-established", json_integer(ctx->dhcpv6_established_max));
}
if(dict_count(ctx->li_flow_dict)) {
jobj_li = json_object();
json_object_set(jobj_li, "flows", json_integer(dict_count(ctx->li_flow_dict)));
json_object_set(jobj_li, "rx-packets", json_integer(stats->li_rx));
json_object_set(jobj, "li-statistics", jobj_li);
jobj_sub = json_object();
json_object_set(jobj_sub, "flows", json_integer(dict_count(ctx->li_flow_dict)));
json_object_set(jobj_sub, "rx-packets", json_integer(stats->li_rx));
json_object_set(jobj, "li-statistics", jobj_sub);
}
if(ctx->config.l2tp_server) {
jobj_l2tp = json_object();
json_object_set(jobj_l2tp, "tunnels", json_integer(ctx->l2tp_tunnels_max));
json_object_set(jobj_l2tp, "tunnels-established", json_integer(ctx->l2tp_tunnels_established_max));
json_object_set(jobj_l2tp, "sessions", json_integer(ctx->l2tp_sessions_max));
json_object_set(jobj_l2tp, "tx-control-packets", json_integer(stats->l2tp_control_tx));
json_object_set(jobj_l2tp, "tx-control-packets-retry", json_integer(stats->l2tp_control_retry));
json_object_set(jobj_l2tp, "rx-control-packets", json_integer(stats->l2tp_control_rx));
json_object_set(jobj_l2tp, "rx-control-packets-duplicate", json_integer(stats->l2tp_control_rx_dup));
json_object_set(jobj_l2tp, "rx-control-packets-out-of-order", json_integer(stats->l2tp_control_rx_ooo));
json_object_set(jobj_l2tp, "tx-data-packets", json_integer(stats->l2tp_data_tx));
json_object_set(jobj_l2tp, "rx-data-packets", json_integer(stats->l2tp_data_rx));
json_object_set(jobj, "l2tp", jobj_l2tp);
jobj_sub = json_object();
json_object_set(jobj_sub, "tunnels", json_integer(ctx->l2tp_tunnels_max));
json_object_set(jobj_sub, "tunnels-established", json_integer(ctx->l2tp_tunnels_established_max));
json_object_set(jobj_sub, "sessions", json_integer(ctx->l2tp_sessions_max));
json_object_set(jobj_sub, "tx-control-packets", json_integer(stats->l2tp_control_tx));
json_object_set(jobj_sub, "tx-control-packets-retry", json_integer(stats->l2tp_control_retry));
json_object_set(jobj_sub, "rx-control-packets", json_integer(stats->l2tp_control_rx));
json_object_set(jobj_sub, "rx-control-packets-duplicate", json_integer(stats->l2tp_control_rx_dup));
json_object_set(jobj_sub, "rx-control-packets-out-of-order", json_integer(stats->l2tp_control_rx_ooo));
json_object_set(jobj_sub, "tx-data-packets", json_integer(stats->l2tp_data_tx));
json_object_set(jobj_sub, "rx-data-packets", json_integer(stats->l2tp_data_rx));
json_object_set(jobj, "l2tp", jobj_sub);
}
jobj_array = json_array();
for(i=0; i < ctx->interfaces.network_if_count; i++) {
interface = ctx->interfaces.network_if[i];
if (interface) {
jobj_network_if = json_object();
json_object_set(jobj_network_if, "name", json_string(interface->name));
json_object_set(jobj_network_if, "tx-packets", json_integer(interface->stats.packets_tx));
json_object_set(jobj_network_if, "rx-packets", json_integer(interface->stats.packets_rx));
json_object_set(jobj_network_if, "tx-session-packets", json_integer(interface->stats.session_ipv4_tx));
json_object_set(jobj_network_if, "rx-session-packets", json_integer(interface->stats.session_ipv4_rx));
json_object_set(jobj_network_if, "rx-session-packets-loss", json_integer(interface->stats.session_ipv4_loss));
json_object_set(jobj_network_if, "tx-session-packets-avg-pps-max", json_integer(interface->stats.rate_session_ipv4_tx.avg_max));
json_object_set(jobj_network_if, "rx-session-packets-avg-pps-max", json_integer(interface->stats.rate_session_ipv4_rx.avg_max));
json_object_set(jobj_network_if, "tx-session-packets-ipv6", json_integer(interface->stats.session_ipv6_tx));
json_object_set(jobj_network_if, "rx-session-packets-ipv6", json_integer(interface->stats.session_ipv6_rx));
json_object_set(jobj_network_if, "rx-session-packets-ipv6-loss", json_integer(interface->stats.session_ipv6_loss));
json_object_set(jobj_network_if, "tx-session-packets-avg-pps-max-ipv6", json_integer(interface->stats.rate_session_ipv6_tx.avg_max));
json_object_set(jobj_network_if, "rx-session-packets-avg-pps-max-ipv6", json_integer(interface->stats.rate_session_ipv6_rx.avg_max));
json_object_set(jobj_network_if, "tx-session-packets-ipv6pd", json_integer(interface->stats.session_ipv6pd_tx));
json_object_set(jobj_network_if, "rx-session-packets-ipv6pd", json_integer(interface->stats.session_ipv6pd_rx));
json_object_set(jobj_network_if, "rx-session-packets-ipv6pd-loss", json_integer(interface->stats.session_ipv6pd_loss));
json_object_set(jobj_network_if, "tx-session-packets-avg-pps-max-ipv6pd", json_integer(interface->stats.rate_session_ipv6pd_tx.avg_max));
json_object_set(jobj_network_if, "rx-session-packets-avg-pps-max-ipv6pd", json_integer(interface->stats.rate_session_ipv6pd_rx.avg_max));
json_object_set(jobj_network_if, "tx-multicast-packets", json_integer(interface->stats.mc_tx));
json_array_append(jobj_array, jobj_network_if);
jobj_sub = json_object();
json_object_set(jobj_sub, "name", json_string(interface->name));
json_object_set(jobj_sub, "tx-packets", json_integer(interface->stats.packets_tx));
json_object_set(jobj_sub, "rx-packets", json_integer(interface->stats.packets_rx));
if(ctx->stats.session_traffic_flows) {
json_object_set(jobj_sub, "tx-session-packets", json_integer(interface->stats.session_ipv4_tx));
json_object_set(jobj_sub, "rx-session-packets", json_integer(interface->stats.session_ipv4_rx));
json_object_set(jobj_sub, "rx-session-packets-loss", json_integer(interface->stats.session_ipv4_loss));
json_object_set(jobj_sub, "tx-session-packets-avg-pps-max", json_integer(interface->stats.rate_session_ipv4_tx.avg_max));
json_object_set(jobj_sub, "rx-session-packets-avg-pps-max", json_integer(interface->stats.rate_session_ipv4_rx.avg_max));
json_object_set(jobj_sub, "tx-session-packets-ipv6", json_integer(interface->stats.session_ipv6_tx));
json_object_set(jobj_sub, "rx-session-packets-ipv6", json_integer(interface->stats.session_ipv6_rx));
json_object_set(jobj_sub, "rx-session-packets-ipv6-loss", json_integer(interface->stats.session_ipv6_loss));
json_object_set(jobj_sub, "tx-session-packets-avg-pps-max-ipv6", json_integer(interface->stats.rate_session_ipv6_tx.avg_max));
json_object_set(jobj_sub, "rx-session-packets-avg-pps-max-ipv6", json_integer(interface->stats.rate_session_ipv6_rx.avg_max));
json_object_set(jobj_sub, "tx-session-packets-ipv6pd", json_integer(interface->stats.session_ipv6pd_tx));
json_object_set(jobj_sub, "rx-session-packets-ipv6pd", json_integer(interface->stats.session_ipv6pd_rx));
json_object_set(jobj_sub, "rx-session-packets-ipv6pd-loss", json_integer(interface->stats.session_ipv6pd_loss));
json_object_set(jobj_sub, "tx-session-packets-avg-pps-max-ipv6pd", json_integer(interface->stats.rate_session_ipv6pd_tx.avg_max));
json_object_set(jobj_sub, "rx-session-packets-avg-pps-max-ipv6pd", json_integer(interface->stats.rate_session_ipv6pd_rx.avg_max));
}
json_object_set(jobj_sub, "tx-multicast-packets", json_integer(interface->stats.mc_tx));
json_array_append(jobj_array, jobj_sub);
}
}
json_object_set(jobj, "network-interfaces", jobj_array);
@@ -479,71 +504,73 @@ bbl_stats_json (bbl_ctx_s *ctx, bbl_stats_t * stats) {
for(i=0; i < ctx->interfaces.access_if_count; i++) {
interface = ctx->interfaces.access_if[i];
if (interface) {
jobj_access_if = json_object();
json_object_set(jobj_access_if, "name", json_string(interface->name));
json_object_set(jobj_access_if, "tx-packets", json_integer(interface->stats.packets_tx));
json_object_set(jobj_access_if, "rx-packets", json_integer(interface->stats.packets_rx));
json_object_set(jobj_access_if, "tx-session-packets", json_integer(interface->stats.session_ipv4_tx));
json_object_set(jobj_access_if, "rx-session-packets", json_integer(interface->stats.session_ipv4_rx));
json_object_set(jobj_access_if, "rx-session-packets-loss", json_integer(interface->stats.session_ipv4_loss));
json_object_set(jobj_access_if, "rx-session-packets-wrong-session", json_integer(interface->stats.session_ipv4_wrong_session));
json_object_set(jobj_access_if, "tx-session-packets-avg-pps-max", json_integer(interface->stats.rate_session_ipv4_tx.avg_max));
json_object_set(jobj_access_if, "rx-session-packets-avg-pps-max", json_integer(interface->stats.rate_session_ipv4_rx.avg_max));
json_object_set(jobj_access_if, "tx-session-packets-ipv6", json_integer(interface->stats.session_ipv6_tx));
json_object_set(jobj_access_if, "rx-session-packets-ipv6", json_integer(interface->stats.session_ipv6_rx));
json_object_set(jobj_access_if, "rx-session-packets-ipv6-loss", json_integer(interface->stats.session_ipv6_loss));
json_object_set(jobj_access_if, "rx-session-packets-ipv6-wrong-session", json_integer(interface->stats.session_ipv6_wrong_session));
json_object_set(jobj_access_if, "tx-session-packets-avg-pps-max-ipv6", json_integer(interface->stats.rate_session_ipv6_tx.avg_max));
json_object_set(jobj_access_if, "rx-session-packets-avg-pps-max-ipv6", json_integer(interface->stats.rate_session_ipv6_rx.avg_max));
json_object_set(jobj_access_if, "tx-session-packets-ipv6pd", json_integer(interface->stats.session_ipv6pd_tx));
json_object_set(jobj_access_if, "rx-session-packets-ipv6pd", json_integer(interface->stats.session_ipv6pd_rx));
json_object_set(jobj_access_if, "rx-session-packets-ipv6pd-loss", json_integer(interface->stats.session_ipv6pd_loss));
json_object_set(jobj_access_if, "rx-session-packets-ipv6pd-wrong-session", json_integer(interface->stats.session_ipv6pd_wrong_session));
json_object_set(jobj_access_if, "tx-session-packets-avg-pps-max-ipv6pd", json_integer(interface->stats.rate_session_ipv6pd_tx.avg_max));
json_object_set(jobj_access_if, "rx-session-packets-avg-pps-max-ipv6pd", json_integer(interface->stats.rate_session_ipv6pd_rx.avg_max));
json_object_set(jobj_access_if, "rx-multicast-packets", json_integer(interface->stats.mc_rx));
json_object_set(jobj_access_if, "rx-multicast-packets-loss", json_integer(interface->stats.mc_loss));
jobj_protocols = json_object();
json_object_set(jobj_protocols, "arp-tx", json_integer(interface->stats.arp_tx));
json_object_set(jobj_protocols, "arp-rx", json_integer(interface->stats.arp_rx));
json_object_set(jobj_protocols, "padi-tx", json_integer(interface->stats.padi_tx));
json_object_set(jobj_protocols, "pado-rx", json_integer(interface->stats.pado_rx));
json_object_set(jobj_protocols, "padr-tx", json_integer(interface->stats.padr_tx));
json_object_set(jobj_protocols, "pads-rx", json_integer(interface->stats.pads_rx));
json_object_set(jobj_protocols, "padt-tx", json_integer(interface->stats.padt_tx));
json_object_set(jobj_protocols, "padt-rx", json_integer(interface->stats.padt_rx));
json_object_set(jobj_protocols, "lcp-tx", json_integer(interface->stats.lcp_tx));
json_object_set(jobj_protocols, "lcp-rx", json_integer(interface->stats.lcp_rx));
json_object_set(jobj_protocols, "pap-tx", json_integer(interface->stats.pap_tx));
json_object_set(jobj_protocols, "pap-rx", json_integer(interface->stats.pap_rx));
json_object_set(jobj_protocols, "chap-tx", json_integer(interface->stats.chap_tx));
json_object_set(jobj_protocols, "chap-rx", json_integer(interface->stats.chap_rx));
json_object_set(jobj_protocols, "ipcp-tx", json_integer(interface->stats.ipcp_tx));
json_object_set(jobj_protocols, "ipcp-rx", json_integer(interface->stats.ipcp_rx));
json_object_set(jobj_protocols, "ip6cp-tx", json_integer(interface->stats.ip6cp_tx));
json_object_set(jobj_protocols, "ip6cp-rx", json_integer(interface->stats.ip6cp_rx));
json_object_set(jobj_protocols, "igmp-tx", json_integer(interface->stats.igmp_tx));
json_object_set(jobj_protocols, "igmp-rx", json_integer(interface->stats.igmp_rx));
json_object_set(jobj_protocols, "icmp-tx", json_integer(interface->stats.icmp_tx));
json_object_set(jobj_protocols, "icmp-rx", json_integer(interface->stats.icmp_rx));
json_object_set(jobj_protocols, "dhcp-tx", json_integer(interface->stats.dhcp_tx));
json_object_set(jobj_protocols, "dhcp-rx", json_integer(interface->stats.dhcp_rx));
json_object_set(jobj_protocols, "dhcpv6-tx", json_integer(interface->stats.dhcpv6_tx));
json_object_set(jobj_protocols, "dhcpv6-rx", json_integer(interface->stats.dhcpv6_rx));
json_object_set(jobj_protocols, "icmpv6-tx", json_integer(interface->stats.icmpv6_tx));
json_object_set(jobj_protocols, "icmpv6-rx", json_integer(interface->stats.icmpv6_rx));
json_object_set(jobj_protocols, "ipv4-fragmented-rx", json_integer(interface->stats.ipv4_fragmented_rx));
json_object_set(jobj_protocols, "lcp-echo-timeout", json_integer(interface->stats.lcp_echo_timeout));
json_object_set(jobj_protocols, "lcp-request-timeout", json_integer(interface->stats.lcp_timeout));
json_object_set(jobj_protocols, "ipcp-request-timeout", json_integer(interface->stats.ipcp_timeout));
json_object_set(jobj_protocols, "ip6cp-request-timeout", json_integer(interface->stats.ip6cp_timeout));
json_object_set(jobj_protocols, "pap-timeout", json_integer(interface->stats.pap_timeout));
json_object_set(jobj_protocols, "chap-timeout", json_integer(interface->stats.chap_timeout));
json_object_set(jobj_protocols, "dhcp-timeout", json_integer(interface->stats.dhcp_timeout));
json_object_set(jobj_protocols, "dhcpv6-timeout", json_integer(interface->stats.dhcpv6_timeout));
json_object_set(jobj_protocols, "icmpv6-rs-timeout", json_integer(interface->stats.dhcpv6_timeout));
json_object_set(jobj_access_if, "protocol-stats", jobj_protocols);
json_array_append(jobj_array, jobj_access_if);
jobj_sub = json_object();
json_object_set(jobj_sub, "name", json_string(interface->name));
json_object_set(jobj_sub, "tx-packets", json_integer(interface->stats.packets_tx));
json_object_set(jobj_sub, "rx-packets", json_integer(interface->stats.packets_rx));
if(ctx->stats.session_traffic_flows) {
json_object_set(jobj_sub, "tx-session-packets", json_integer(interface->stats.session_ipv4_tx));
json_object_set(jobj_sub, "rx-session-packets", json_integer(interface->stats.session_ipv4_rx));
json_object_set(jobj_sub, "rx-session-packets-loss", json_integer(interface->stats.session_ipv4_loss));
json_object_set(jobj_sub, "rx-session-packets-wrong-session", json_integer(interface->stats.session_ipv4_wrong_session));
json_object_set(jobj_sub, "tx-session-packets-avg-pps-max", json_integer(interface->stats.rate_session_ipv4_tx.avg_max));
json_object_set(jobj_sub, "rx-session-packets-avg-pps-max", json_integer(interface->stats.rate_session_ipv4_rx.avg_max));
json_object_set(jobj_sub, "tx-session-packets-ipv6", json_integer(interface->stats.session_ipv6_tx));
json_object_set(jobj_sub, "rx-session-packets-ipv6", json_integer(interface->stats.session_ipv6_rx));
json_object_set(jobj_sub, "rx-session-packets-ipv6-loss", json_integer(interface->stats.session_ipv6_loss));
json_object_set(jobj_sub, "rx-session-packets-ipv6-wrong-session", json_integer(interface->stats.session_ipv6_wrong_session));
json_object_set(jobj_sub, "tx-session-packets-avg-pps-max-ipv6", json_integer(interface->stats.rate_session_ipv6_tx.avg_max));
json_object_set(jobj_sub, "rx-session-packets-avg-pps-max-ipv6", json_integer(interface->stats.rate_session_ipv6_rx.avg_max));
json_object_set(jobj_sub, "tx-session-packets-ipv6pd", json_integer(interface->stats.session_ipv6pd_tx));
json_object_set(jobj_sub, "rx-session-packets-ipv6pd", json_integer(interface->stats.session_ipv6pd_rx));
json_object_set(jobj_sub, "rx-session-packets-ipv6pd-loss", json_integer(interface->stats.session_ipv6pd_loss));
json_object_set(jobj_sub, "rx-session-packets-ipv6pd-wrong-session", json_integer(interface->stats.session_ipv6pd_wrong_session));
json_object_set(jobj_sub, "tx-session-packets-avg-pps-max-ipv6pd", json_integer(interface->stats.rate_session_ipv6pd_tx.avg_max));
json_object_set(jobj_sub, "rx-session-packets-avg-pps-max-ipv6pd", json_integer(interface->stats.rate_session_ipv6pd_rx.avg_max));
}
json_object_set(jobj_sub, "rx-multicast-packets", json_integer(interface->stats.mc_rx));
json_object_set(jobj_sub, "rx-multicast-packets-loss", json_integer(interface->stats.mc_loss));
jobj_sub2 = json_object();
json_object_set(jobj_sub2, "arp-tx", json_integer(interface->stats.arp_tx));
json_object_set(jobj_sub2, "arp-rx", json_integer(interface->stats.arp_rx));
json_object_set(jobj_sub2, "padi-tx", json_integer(interface->stats.padi_tx));
json_object_set(jobj_sub2, "pado-rx", json_integer(interface->stats.pado_rx));
json_object_set(jobj_sub2, "padr-tx", json_integer(interface->stats.padr_tx));
json_object_set(jobj_sub2, "pads-rx", json_integer(interface->stats.pads_rx));
json_object_set(jobj_sub2, "padt-tx", json_integer(interface->stats.padt_tx));
json_object_set(jobj_sub2, "padt-rx", json_integer(interface->stats.padt_rx));
json_object_set(jobj_sub2, "lcp-tx", json_integer(interface->stats.lcp_tx));
json_object_set(jobj_sub2, "lcp-rx", json_integer(interface->stats.lcp_rx));
json_object_set(jobj_sub2, "pap-tx", json_integer(interface->stats.pap_tx));
json_object_set(jobj_sub2, "pap-rx", json_integer(interface->stats.pap_rx));
json_object_set(jobj_sub2, "chap-tx", json_integer(interface->stats.chap_tx));
json_object_set(jobj_sub2, "chap-rx", json_integer(interface->stats.chap_rx));
json_object_set(jobj_sub2, "ipcp-tx", json_integer(interface->stats.ipcp_tx));
json_object_set(jobj_sub2, "ipcp-rx", json_integer(interface->stats.ipcp_rx));
json_object_set(jobj_sub2, "ip6cp-tx", json_integer(interface->stats.ip6cp_tx));
json_object_set(jobj_sub2, "ip6cp-rx", json_integer(interface->stats.ip6cp_rx));
json_object_set(jobj_sub2, "igmp-tx", json_integer(interface->stats.igmp_tx));
json_object_set(jobj_sub2, "igmp-rx", json_integer(interface->stats.igmp_rx));
json_object_set(jobj_sub2, "icmp-tx", json_integer(interface->stats.icmp_tx));
json_object_set(jobj_sub2, "icmp-rx", json_integer(interface->stats.icmp_rx));
json_object_set(jobj_sub2, "dhcp-tx", json_integer(interface->stats.dhcp_tx));
json_object_set(jobj_sub2, "dhcp-rx", json_integer(interface->stats.dhcp_rx));
json_object_set(jobj_sub2, "dhcpv6-tx", json_integer(interface->stats.dhcpv6_tx));
json_object_set(jobj_sub2, "dhcpv6-rx", json_integer(interface->stats.dhcpv6_rx));
json_object_set(jobj_sub2, "icmpv6-tx", json_integer(interface->stats.icmpv6_tx));
json_object_set(jobj_sub2, "icmpv6-rx", json_integer(interface->stats.icmpv6_rx));
json_object_set(jobj_sub2, "ipv4-fragmented-rx", json_integer(interface->stats.ipv4_fragmented_rx));
json_object_set(jobj_sub2, "lcp-echo-timeout", json_integer(interface->stats.lcp_echo_timeout));
json_object_set(jobj_sub2, "lcp-request-timeout", json_integer(interface->stats.lcp_timeout));
json_object_set(jobj_sub2, "ipcp-request-timeout", json_integer(interface->stats.ipcp_timeout));
json_object_set(jobj_sub2, "ip6cp-request-timeout", json_integer(interface->stats.ip6cp_timeout));
json_object_set(jobj_sub2, "pap-timeout", json_integer(interface->stats.pap_timeout));
json_object_set(jobj_sub2, "chap-timeout", json_integer(interface->stats.chap_timeout));
json_object_set(jobj_sub2, "dhcp-timeout", json_integer(interface->stats.dhcp_timeout));
json_object_set(jobj_sub2, "dhcpv6-timeout", json_integer(interface->stats.dhcpv6_timeout));
json_object_set(jobj_sub2, "icmpv6-rs-timeout", json_integer(interface->stats.dhcpv6_timeout));
json_object_set(jobj_sub, "protocol-stats", jobj_sub2);
json_array_append(jobj_array, jobj_sub);
}
}
json_object_set(jobj, "access-interfaces", jobj_array);
@@ -552,90 +579,133 @@ bbl_stats_json (bbl_ctx_s *ctx, bbl_stats_t * stats) {
for(i=0; i < ctx->interfaces.a10nsp_if_count; i++) {
interface = ctx->interfaces.a10nsp_if[i];
if (interface) {
jobj_a10nsp_if = json_object();
json_object_set(jobj_a10nsp_if, "name", json_string(interface->name));
json_object_set(jobj_a10nsp_if, "tx-packets", json_integer(interface->stats.packets_tx));
json_object_set(jobj_a10nsp_if, "rx-packets", json_integer(interface->stats.packets_rx));
json_object_set(jobj_a10nsp_if, "tx-session-packets", json_integer(interface->stats.session_ipv4_tx));
json_object_set(jobj_a10nsp_if, "rx-session-packets", json_integer(interface->stats.session_ipv4_rx));
json_object_set(jobj_a10nsp_if, "rx-session-packets-loss", json_integer(interface->stats.session_ipv4_loss));
json_object_set(jobj_a10nsp_if, "tx-session-packets-avg-pps-max", json_integer(interface->stats.rate_session_ipv4_tx.avg_max));
json_object_set(jobj_a10nsp_if, "rx-session-packets-avg-pps-max", json_integer(interface->stats.rate_session_ipv4_rx.avg_max));
json_object_set(jobj_a10nsp_if, "tx-session-packets-ipv6", json_integer(interface->stats.session_ipv6_tx));
json_object_set(jobj_a10nsp_if, "rx-session-packets-ipv6", json_integer(interface->stats.session_ipv6_rx));
json_object_set(jobj_a10nsp_if, "rx-session-packets-ipv6-loss", json_integer(interface->stats.session_ipv6_loss));
json_object_set(jobj_a10nsp_if, "tx-session-packets-avg-pps-max-ipv6", json_integer(interface->stats.rate_session_ipv6_tx.avg_max));
json_object_set(jobj_a10nsp_if, "rx-session-packets-avg-pps-max-ipv6", json_integer(interface->stats.rate_session_ipv6_rx.avg_max));
json_object_set(jobj_a10nsp_if, "tx-session-packets-ipv6pd", json_integer(interface->stats.session_ipv6pd_tx));
json_object_set(jobj_a10nsp_if, "rx-session-packets-ipv6pd", json_integer(interface->stats.session_ipv6pd_rx));
json_object_set(jobj_a10nsp_if, "rx-session-packets-ipv6pd-loss", json_integer(interface->stats.session_ipv6pd_loss));
json_object_set(jobj_a10nsp_if, "tx-session-packets-avg-pps-max-ipv6pd", json_integer(interface->stats.rate_session_ipv6pd_tx.avg_max));
json_object_set(jobj_a10nsp_if, "rx-session-packets-avg-pps-max-ipv6pd", json_integer(interface->stats.rate_session_ipv6pd_rx.avg_max));
json_object_set(jobj_a10nsp_if, "tx-multicast-packets", json_integer(interface->stats.mc_tx));
json_array_append(jobj_array, jobj_a10nsp_if);
jobj_sub = json_object();
json_object_set(jobj_sub, "name", json_string(interface->name));
json_object_set(jobj_sub, "tx-packets", json_integer(interface->stats.packets_tx));
json_object_set(jobj_sub, "rx-packets", json_integer(interface->stats.packets_rx));
if(ctx->stats.session_traffic_flows) {
json_object_set(jobj_sub, "tx-session-packets", json_integer(interface->stats.session_ipv4_tx));
json_object_set(jobj_sub, "rx-session-packets", json_integer(interface->stats.session_ipv4_rx));
json_object_set(jobj_sub, "rx-session-packets-loss", json_integer(interface->stats.session_ipv4_loss));
json_object_set(jobj_sub, "tx-session-packets-avg-pps-max", json_integer(interface->stats.rate_session_ipv4_tx.avg_max));
json_object_set(jobj_sub, "rx-session-packets-avg-pps-max", json_integer(interface->stats.rate_session_ipv4_rx.avg_max));
json_object_set(jobj_sub, "tx-session-packets-ipv6", json_integer(interface->stats.session_ipv6_tx));
json_object_set(jobj_sub, "rx-session-packets-ipv6", json_integer(interface->stats.session_ipv6_rx));
json_object_set(jobj_sub, "rx-session-packets-ipv6-loss", json_integer(interface->stats.session_ipv6_loss));
json_object_set(jobj_sub, "tx-session-packets-avg-pps-max-ipv6", json_integer(interface->stats.rate_session_ipv6_tx.avg_max));
json_object_set(jobj_sub, "rx-session-packets-avg-pps-max-ipv6", json_integer(interface->stats.rate_session_ipv6_rx.avg_max));
json_object_set(jobj_sub, "tx-session-packets-ipv6pd", json_integer(interface->stats.session_ipv6pd_tx));
json_object_set(jobj_sub, "rx-session-packets-ipv6pd", json_integer(interface->stats.session_ipv6pd_rx));
json_object_set(jobj_sub, "rx-session-packets-ipv6pd-loss", json_integer(interface->stats.session_ipv6pd_loss));
json_object_set(jobj_sub, "tx-session-packets-avg-pps-max-ipv6pd", json_integer(interface->stats.rate_session_ipv6pd_tx.avg_max));
json_object_set(jobj_sub, "rx-session-packets-avg-pps-max-ipv6pd", json_integer(interface->stats.rate_session_ipv6pd_rx.avg_max));
}
json_array_append(jobj_array, jobj_sub);
}
}
json_object_set(jobj, "a10nsp-interfaces", jobj_array);
if(ctx->stats.session_traffic_flows) {
jobj_straffic = json_object();
json_object_set(jobj_straffic, "config-ipv4-pps", json_integer(ctx->config.session_traffic_ipv4_pps));
json_object_set(jobj_straffic, "config-ipv6-pps", json_integer(ctx->config.session_traffic_ipv6_pps));
json_object_set(jobj_straffic, "config-ipv6pd-pps", json_integer(ctx->config.session_traffic_ipv6pd_pps));
json_object_set(jobj_straffic, "total-flows", json_integer(ctx->stats.session_traffic_flows));
json_object_set(jobj_straffic, "verified-flows", json_integer(ctx->stats.session_traffic_flows_verified));
json_object_set(jobj_straffic, "verified-flows-access-ipv4", json_integer(stats->sessions_access_ipv4_rx));
json_object_set(jobj_straffic, "verified-flows-access-ipv6", json_integer(stats->sessions_access_ipv6_rx));
json_object_set(jobj_straffic, "verified-flows-access-ipv6pd", json_integer(stats->sessions_access_ipv6pd_rx));
json_object_set(jobj_straffic, "verified-flows-network-ipv4", json_integer(stats->sessions_network_ipv4_rx));
json_object_set(jobj_straffic, "verified-flows-network-ipv6", json_integer(stats->sessions_network_ipv6_rx));
json_object_set(jobj_straffic, "verified-flows-network-ipv6pd", json_integer(stats->sessions_network_ipv6pd_rx));
json_object_set(jobj_straffic, "first-seq-rx-access-ipv4-min", json_integer(stats->min_access_ipv4_rx_first_seq));
json_object_set(jobj_straffic, "first-seq-rx-access-ipv4-max", json_integer(stats->max_access_ipv4_rx_first_seq));
json_object_set(jobj_straffic, "first-seq-rx-access-ipv6-min", json_integer(stats->min_access_ipv6_rx_first_seq));
json_object_set(jobj_straffic, "first-seq-rx-access-ipv6-max", json_integer(stats->max_access_ipv6_rx_first_seq));
json_object_set(jobj_straffic, "first-seq-rx-access-ipv6pd-min", json_integer(stats->min_access_ipv6pd_rx_first_seq));
json_object_set(jobj_straffic, "first-seq-rx-access-ipv6pd-max", json_integer(stats->max_access_ipv6pd_rx_first_seq));
json_object_set(jobj_straffic, "first-seq-rx-network-ipv4-min", json_integer(stats->min_network_ipv4_rx_first_seq));
json_object_set(jobj_straffic, "first-seq-rx-network-ipv4-max", json_integer(stats->max_network_ipv4_rx_first_seq));
json_object_set(jobj_straffic, "first-seq-rx-network-ipv6-min", json_integer(stats->min_network_ipv6_rx_first_seq));
json_object_set(jobj_straffic, "first-seq-rx-network-ipv6-max", json_integer(stats->max_network_ipv6_rx_first_seq));
json_object_set(jobj_straffic, "first-seq-rx-network-ipv6pd-min", json_integer(stats->min_network_ipv6pd_rx_first_seq));
json_object_set(jobj_straffic, "first-seq-rx-network-ipv6pd-max", json_integer(stats->max_network_ipv6pd_rx_first_seq));
json_object_set(jobj_straffic, "first-seq-rx-access-ipv4-min-seconds", json_real(stats->min_access_ipv4_rx_seconds));
json_object_set(jobj_straffic, "first-seq-rx-access-ipv4-max-seconds", json_real(stats->max_access_ipv4_rx_seconds));
json_object_set(jobj_straffic, "first-seq-rx-access-ipv6-min-seconds", json_real(stats->min_access_ipv6_rx_seconds));
json_object_set(jobj_straffic, "first-seq-rx-access-ipv6-max-seconds", json_real(stats->max_access_ipv6_rx_seconds));
json_object_set(jobj_straffic, "first-seq-rx-access-ipv6pd-min-seconds", json_real(stats->min_access_ipv6pd_rx_seconds));
json_object_set(jobj_straffic, "first-seq-rx-access-ipv6pd-max-seconds", json_real(stats->max_access_ipv6pd_rx_seconds));
json_object_set(jobj_straffic, "first-seq-rx-network-ipv4-min-seconds", json_real(stats->min_network_ipv4_rx_seconds));
json_object_set(jobj_straffic, "first-seq-rx-network-ipv4-max-seconds", json_real(stats->max_network_ipv4_rx_seconds));
json_object_set(jobj_straffic, "first-seq-rx-network-ipv6-min-seconds", json_real(stats->min_network_ipv6_rx_seconds));
json_object_set(jobj_straffic, "first-seq-rx-network-ipv6-max-seconds", json_real(stats->max_network_ipv6_rx_seconds));
json_object_set(jobj_straffic, "first-seq-rx-network-ipv6pd-min-seconds", json_real(stats->min_network_ipv6pd_rx_seconds));
json_object_set(jobj_straffic, "first-seq-rx-network-ipv6pd-max-seconds", json_real(stats->max_network_ipv6pd_rx_seconds));
json_object_set(jobj, "session-traffic", jobj_straffic);
jobj_sub = json_object();
json_object_set(jobj_sub, "config-ipv4-pps", json_integer(ctx->config.session_traffic_ipv4_pps));
json_object_set(jobj_sub, "config-ipv6-pps", json_integer(ctx->config.session_traffic_ipv6_pps));
json_object_set(jobj_sub, "config-ipv6pd-pps", json_integer(ctx->config.session_traffic_ipv6pd_pps));
json_object_set(jobj_sub, "total-flows", json_integer(ctx->stats.session_traffic_flows));
json_object_set(jobj_sub, "verified-flows", json_integer(ctx->stats.session_traffic_flows_verified));
json_object_set(jobj_sub, "verified-flows-access-ipv4", json_integer(stats->sessions_access_ipv4_rx));
json_object_set(jobj_sub, "verified-flows-access-ipv6", json_integer(stats->sessions_access_ipv6_rx));
json_object_set(jobj_sub, "verified-flows-access-ipv6pd", json_integer(stats->sessions_access_ipv6pd_rx));
json_object_set(jobj_sub, "verified-flows-network-ipv4", json_integer(stats->sessions_network_ipv4_rx));
json_object_set(jobj_sub, "verified-flows-network-ipv6", json_integer(stats->sessions_network_ipv6_rx));
json_object_set(jobj_sub, "verified-flows-network-ipv6pd", json_integer(stats->sessions_network_ipv6pd_rx));
json_object_set(jobj_sub, "first-seq-rx-access-ipv4-min", json_integer(stats->min_access_ipv4_rx_first_seq));
json_object_set(jobj_sub, "first-seq-rx-access-ipv4-max", json_integer(stats->max_access_ipv4_rx_first_seq));
json_object_set(jobj_sub, "first-seq-rx-access-ipv6-min", json_integer(stats->min_access_ipv6_rx_first_seq));
json_object_set(jobj_sub, "first-seq-rx-access-ipv6-max", json_integer(stats->max_access_ipv6_rx_first_seq));
json_object_set(jobj_sub, "first-seq-rx-access-ipv6pd-min", json_integer(stats->min_access_ipv6pd_rx_first_seq));
json_object_set(jobj_sub, "first-seq-rx-access-ipv6pd-max", json_integer(stats->max_access_ipv6pd_rx_first_seq));
json_object_set(jobj_sub, "first-seq-rx-network-ipv4-min", json_integer(stats->min_network_ipv4_rx_first_seq));
json_object_set(jobj_sub, "first-seq-rx-network-ipv4-max", json_integer(stats->max_network_ipv4_rx_first_seq));
json_object_set(jobj_sub, "first-seq-rx-network-ipv6-min", json_integer(stats->min_network_ipv6_rx_first_seq));
json_object_set(jobj_sub, "first-seq-rx-network-ipv6-max", json_integer(stats->max_network_ipv6_rx_first_seq));
json_object_set(jobj_sub, "first-seq-rx-network-ipv6pd-min", json_integer(stats->min_network_ipv6pd_rx_first_seq));
json_object_set(jobj_sub, "first-seq-rx-network-ipv6pd-max", json_integer(stats->max_network_ipv6pd_rx_first_seq));
json_object_set(jobj_sub, "first-seq-rx-access-ipv4-min-seconds", json_real(stats->min_access_ipv4_rx_seconds));
json_object_set(jobj_sub, "first-seq-rx-access-ipv4-max-seconds", json_real(stats->max_access_ipv4_rx_seconds));
json_object_set(jobj_sub, "first-seq-rx-access-ipv6-min-seconds", json_real(stats->min_access_ipv6_rx_seconds));
json_object_set(jobj_sub, "first-seq-rx-access-ipv6-max-seconds", json_real(stats->max_access_ipv6_rx_seconds));
json_object_set(jobj_sub, "first-seq-rx-access-ipv6pd-min-seconds", json_real(stats->min_access_ipv6pd_rx_seconds));
json_object_set(jobj_sub, "first-seq-rx-access-ipv6pd-max-seconds", json_real(stats->max_access_ipv6pd_rx_seconds));
json_object_set(jobj_sub, "first-seq-rx-network-ipv4-min-seconds", json_real(stats->min_network_ipv4_rx_seconds));
json_object_set(jobj_sub, "first-seq-rx-network-ipv4-max-seconds", json_real(stats->max_network_ipv4_rx_seconds));
json_object_set(jobj_sub, "first-seq-rx-network-ipv6-min-seconds", json_real(stats->min_network_ipv6_rx_seconds));
json_object_set(jobj_sub, "first-seq-rx-network-ipv6-max-seconds", json_real(stats->max_network_ipv6_rx_seconds));
json_object_set(jobj_sub, "first-seq-rx-network-ipv6pd-min-seconds", json_real(stats->min_network_ipv6pd_rx_seconds));
json_object_set(jobj_sub, "first-seq-rx-network-ipv6pd-max-seconds", json_real(stats->max_network_ipv6pd_rx_seconds));
json_object_set(jobj, "session-traffic", jobj_sub);
}
if(ctx->stats.stream_traffic_flows) {
jobj_sub = json_object();
json_object_set(jobj_sub, "total-flows", json_integer(ctx->stats.stream_traffic_flows));
json_object_set(jobj_sub, "verified-flows", json_integer(ctx->stats.stream_traffic_flows_verified));
json_object_set(jobj, "traffic-streams", jobj_sub);
}
if(ctx->config.igmp_group_count > 1) {
jobj_multicast = json_object();
json_object_set(jobj_multicast, "config-version", json_integer(ctx->config.igmp_version));
json_object_set(jobj_multicast, "config-start-delay", json_integer(ctx->config.igmp_start_delay));
json_object_set(jobj_multicast, "config-group-count", json_integer(ctx->config.igmp_group_count));
json_object_set(jobj_multicast, "config-zapping-interval", json_integer(ctx->config.igmp_zap_interval));
json_object_set(jobj_multicast, "config-zapping-count", json_integer(ctx->config.igmp_zap_count));
json_object_set(jobj_multicast, "config-zapping-view-duration", json_integer(ctx->config.igmp_zap_view_duration));
jobj_sub = json_object();
json_object_set(jobj_sub, "config-version", json_integer(ctx->config.igmp_version));
json_object_set(jobj_sub, "config-start-delay", json_integer(ctx->config.igmp_start_delay));
json_object_set(jobj_sub, "config-group-count", json_integer(ctx->config.igmp_group_count));
json_object_set(jobj_sub, "config-zapping-interval", json_integer(ctx->config.igmp_zap_interval));
json_object_set(jobj_sub, "config-zapping-count", json_integer(ctx->config.igmp_zap_count));
json_object_set(jobj_sub, "config-zapping-view-duration", json_integer(ctx->config.igmp_zap_view_duration));
if(ctx->config.igmp_zap_interval > 0) {
json_object_set(jobj_multicast, "zapping-join-delay-ms-min", json_integer(stats->min_join_delay));
json_object_set(jobj_multicast, "zapping-join-delay-ms-avg", json_integer(stats->avg_join_delay));
json_object_set(jobj_multicast, "zapping-join-delay-ms-max", json_integer(stats->max_join_delay));
json_object_set(jobj_multicast, "zapping-leave-delay-ms-min", json_integer(stats->min_leave_delay));
json_object_set(jobj_multicast, "zapping-leave-delay-ms-avg", json_integer(stats->avg_leave_delay));
json_object_set(jobj_multicast, "zapping-leave-delay-ms-max", json_integer(stats->max_leave_delay));
json_object_set(jobj_multicast, "zapping-multicast-packets-overlap", json_integer(stats->mc_old_rx_after_first_new));
json_object_set(jobj_multicast, "zapping-multicast-not-received", json_integer(stats->mc_not_received));
json_object_set(jobj, "multicast", jobj_multicast);
json_object_set(jobj_sub, "zapping-join-delay-ms-min", json_integer(stats->min_join_delay));
json_object_set(jobj_sub, "zapping-join-delay-ms-avg", json_integer(stats->avg_join_delay));
json_object_set(jobj_sub, "zapping-join-delay-ms-max", json_integer(stats->max_join_delay));
json_object_set(jobj_sub, "zapping-leave-delay-ms-min", json_integer(stats->min_leave_delay));
json_object_set(jobj_sub, "zapping-leave-delay-ms-avg", json_integer(stats->avg_leave_delay));
json_object_set(jobj_sub, "zapping-leave-delay-ms-max", json_integer(stats->max_leave_delay));
json_object_set(jobj_sub, "zapping-multicast-packets-overlap", json_integer(stats->mc_old_rx_after_first_new));
json_object_set(jobj_sub, "zapping-multicast-not-received", json_integer(stats->mc_not_received));
json_object_set(jobj, "multicast", jobj_sub);
}
}
if(ctx->config.json_report_sessions) {
jobj_array = json_array();
for(i = 0; i < ctx->sessions; i++) {
session = ctx->session_list[i];
if(session) {
jobj_sub = bbl_session_json(session);
if(jobj_sub) {
json_array_append(jobj_array, jobj_sub);
}
}
}
json_object_set(jobj, "sessions", jobj_array);
}
if(ctx->config.json_report_streams) {
jobj_array = json_array();
itor = dict_itor_new(ctx->stream_flow_dict);
dict_itor_first(itor);
for (; dict_itor_valid(itor); dict_itor_next(itor)) {
stream = (bbl_stream*)*dict_itor_datum(itor);
if(stream) {
jobj_sub = bbl_stream_json(stream);
if(jobj_sub) {
json_array_append(jobj_array, jobj_sub);
}
}
}
json_object_set(jobj, "streams", jobj_array);
}
json_object_set(root, "report", jobj);
if(json_dump_file(root, ctx->config.json_report_filename, JSON_REAL_PRECISION(4)) != 0) {
LOG(ERROR, "Failed to create JSON report file %s\n", ctx->config.json_report_filename);
@@ -644,7 +714,7 @@ bbl_stats_json (bbl_ctx_s *ctx, bbl_stats_t * stats) {
}
/*
* Compute a pps rate using a moving average of <BBL_AVG_SAMPLE> samples.
* Compute a PPS rate using a moving average of <BBL_AVG_SAMPLE> samples.
*/
void
bbl_compute_avg_rate (bbl_rate_s *rate, uint64_t current_value)
+50 -3
View File
@@ -15,10 +15,17 @@
#include <pthread.h>
extern volatile bool g_teardown;
extern bool g_init_phase;
extern bool g_traffic;
bool
static bool
bbl_stream_can_send(bbl_stream *stream) {
bbl_session_s *session = stream->session;
if(g_init_phase) {
return false;
}
if(stream->config->stream_group_id == 0) {
/* RAW stream */
return true;
@@ -774,7 +781,7 @@ bbl_stream_tx_thread (void *thread_data) {
}
}
if(stream->session && !stream->session->stream_traffic) {
if(!g_traffic || (stream->session && !stream->session->stream_traffic)) {
/* Close send window */
stream->send_window_packets = 0;
sleep.tv_nsec = 10 * MSEC;
@@ -885,7 +892,7 @@ bbl_stream_tx_job (timer_s *timer) {
}
}
if(session && !session->stream_traffic) {
if(!g_traffic || (session && !session->stream_traffic)) {
/* Close send window */
stream->send_window_packets = 0;
return;
@@ -1028,6 +1035,7 @@ bbl_stream_add(bbl_ctx_s *ctx, bbl_access_config_s *access_config, bbl_session_s
timer_add_periodic(&ctx->timer_root, &stream->timer, config->name, timer_sec, timer_nsec, stream, &bbl_stream_tx_job);
}
timer_add_periodic(&ctx->timer_root, &stream->timer_rate, "Rate Computation", 1, 0, stream, &bbl_stream_rate_job);
ctx->stats.stream_traffic_flows++;
LOG(DEBUG, "Traffic stream %s added in upstream with %u PPS (timer: %lu sec %lu nsec)\n", config->name, config->pps, timer_sec, timer_nsec);
}
if(config->direction & STREAM_DIRECTION_DOWN) {
@@ -1062,6 +1070,7 @@ bbl_stream_add(bbl_ctx_s *ctx, bbl_access_config_s *access_config, bbl_session_s
timer_add_periodic(&ctx->timer_root, &stream->timer, config->name, timer_sec, timer_nsec, stream, &bbl_stream_tx_job);
}
timer_add_periodic(&ctx->timer_root, &stream->timer_rate, "Rate Computation", 1, 0, stream, &bbl_stream_rate_job);
ctx->stats.stream_traffic_flows++;
LOG(DEBUG, "Traffic stream %s added in downstream with %u PPS (timer %lu sec %lu nsec)\n", config->name, config->pps, timer_sec, timer_nsec);
}
timer_smear_bucket(&ctx->timer_root, timer_sec, timer_nsec);
@@ -1121,6 +1130,7 @@ bbl_stream_raw_add(bbl_ctx_s *ctx) {
timer_add_periodic(&ctx->timer_root, &stream->timer, config->name, timer_sec, timer_nsec, stream, &bbl_stream_tx_job);
}
timer_add_periodic(&ctx->timer_root, &stream->timer_rate, "Rate Computation", 1, 0, stream, &bbl_stream_rate_job);
ctx->stats.stream_traffic_flows++;
LOG(DEBUG, "RAW traffic stream %s added in downstream with %u PPS (timer %lu sec %lu nsec)\n", config->name, config->pps, timer_sec, timer_nsec);
}
timer_smear_bucket(&ctx->timer_root, timer_sec, timer_nsec);
@@ -1129,4 +1139,41 @@ bbl_stream_raw_add(bbl_ctx_s *ctx) {
}
return true;
}
json_t *
bbl_stream_json(bbl_stream *stream)
{
json_t *root = NULL;
if(!stream) {
return NULL;
}
root = json_pack("{ss* ss si si si si si si si si si si si si si si si si si si sf sf sf}",
"name", stream->config->name,
"direction", stream->direction == STREAM_DIRECTION_UP ? "upstream" : "downstream",
"flow-id", stream->flow_id,
"rx-first-seq", stream->rx_first_seq,
"rx-last-seq", stream->rx_last_seq,
"rx-tos-tc", stream->rx_priority,
"rx-outer-vlan-pbit", stream->rx_outer_vlan_pbit,
"rx-inner-vlan-pbit", stream->rx_inner_vlan_pbit,
"rx-len", stream->rx_len,
"tx-len", stream->tx_len,
"rx-packets", stream->packets_rx,
"tx-packets", stream->packets_tx,
"rx-loss", stream->loss,
"rx-delay-nsec-min", stream->min_delay_ns,
"rx-delay-nsec-max", stream->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,
"rx-bps-l2", stream->rate_packets_rx.avg * stream->rx_len * 8,
"rx-bps-l3", stream->rate_packets_rx.avg * stream->config->length * 8,
"tx-mbps-l2", (double)(stream->rate_packets_tx.avg * stream->tx_len * 8) / 1000000.0,
"rx-mbps-l2", (double)(stream->rate_packets_rx.avg * stream->rx_len * 8) / 1000000.0,
"rx-mbps-l3", (double)(stream->rate_packets_rx.avg * stream->config->length * 8) / 1000000.0);
return root;
}
+3
View File
@@ -99,4 +99,7 @@ bbl_stream_raw_add(bbl_ctx_s *ctx);
void
bbl_stream_tx_job (timer_s *timer);
json_t *
bbl_stream_json(bbl_stream *stream);
#endif
+1 -1
View File
@@ -1610,7 +1610,7 @@ void
bbl_network_arp_timeout (timer_s *timer)
{
bbl_interface_s *interface = timer->data;
interface->send_requests |= BBL_SEND_ARP_REQUEST;
interface->send_requests |= BBL_IF_SEND_ARP_REQUEST;
}
void