From 087b95120eedd4a49fb07022895630cda600e824 Mon Sep 17 00:00:00 2001 From: Christian Giese Date: Wed, 10 Mar 2021 16:58:18 +0100 Subject: [PATCH 1/6] Fixed #18 typo estbalished --- src/bbl_l2tp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bbl_l2tp.c b/src/bbl_l2tp.c index 6fb2edc9..d9f2404e 100644 --- a/src/bbl_l2tp.c +++ b/src/bbl_l2tp.c @@ -191,7 +191,7 @@ bbl_l2tp_tunnel_update_state(bbl_l2tp_tunnel_t *l2tp_tunnel, l2tp_tunnel_state_t if(ctx->l2tp_tunnels_established > ctx->l2tp_tunnels_established_max) { ctx->l2tp_tunnels_established_max = ctx->l2tp_tunnels_established; } - LOG(L2TP, "L2TP Info (%s) Tunnel %u with %s (%s) estbalished\n", + LOG(L2TP, "L2TP Info (%s) Tunnel %u with %s (%s) established\n", l2tp_tunnel->server->host_name, l2tp_tunnel->tunnel_id, l2tp_tunnel->peer_name, format_ipv4_address(&l2tp_tunnel->peer_ip)); @@ -788,7 +788,7 @@ bbl_l2tp_iccn_rx(bbl_ethernet_header_t *eth, bbl_l2tp_t *l2tp, bbl_interface_s * } if(l2tp_session->state == BBL_L2TP_SESSION_WAIT_CONN) { l2tp_session->state = BBL_L2TP_SESSION_ESTABLISHED; - LOG(L2TP, "L2TP Info (%s) Tunnel (%u) from %s (%s) session (%u) estbalished\n", + LOG(L2TP, "L2TP Info (%s) Tunnel (%u) from %s (%s) session (%u) established\n", l2tp_tunnel->server->host_name, l2tp_tunnel->tunnel_id, l2tp_tunnel->peer_name, format_ipv4_address(&l2tp_tunnel->peer_ip), From 150579e3552db5c7b83086e9ed060e0987e2a743 Mon Sep 17 00:00:00 2001 From: Christian Giese Date: Wed, 10 Mar 2021 17:04:56 +0100 Subject: [PATCH 2/6] Minor docu update --- README.md | 2 +- docs/intro.md | 2 +- docs/li.md | 19 ++++++++++++++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 770a5d83..d9a94cd4 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ![Build](https://github.com/rtbrick/bngblaster/workflows/Build/badge.svg?branch=main) The BNG Blaster is a test tool to simulate thousands of PPPoE or IPoE subscribers including IPTV, -traffic verification and convergence testing capabilities. +L2TPv2, traffic verification and convergence testing capabilities. A short introduction can be found on [YouTube](https://youtu.be/EHJ70p0_Sw0 "BNG Blaster") or checkout the [documentation](https://rtbrick.github.io/bngblaster/) for details. diff --git a/docs/intro.md b/docs/intro.md index 942bf1a2..b828798d 100644 --- a/docs/intro.md +++ b/docs/intro.md @@ -9,7 +9,7 @@ targeted for max scaling with small resource footprint, simple to use and easy t our test automation infrastructure. The BNG Blaster is able to simulate more than hundred thousand PPPoE subscribers including IPTV, -traffic verification and convergence testing capabilities. +L2TPv2, traffic verification and convergence testing capabilities. * *High Scaling:* > 100K sessions * *Low CPU and Memory Footprint:* < 100MB memory for 16K sessions diff --git a/docs/li.md b/docs/li.md index 891344d2..f54a5746 100644 --- a/docs/li.md +++ b/docs/li.md @@ -52,7 +52,12 @@ The received flows can be queried using the control socket. "packets-rx-ipv4": 0, "packets-rx-ipv4-tcp": 0, "packets-rx-ipv4-udp": 0, - "packets-rx-ipv4-host-internal": 0 + "packets-rx-ipv4-host-internal": 0, + "packets-rx-ipv6": 0, + "packets-rx-ipv6-tcp": 0, + "packets-rx-ipv6-udp": 0, + "packets-rx-ipv6-host-internal": 0, + "packets-rx-ipv6-no-next-header": 0 }, { "source-address": "1.1.1.1", @@ -68,11 +73,19 @@ The received flows can be queried using the control socket. "packets-rx-ipv4": 820, "packets-rx-ipv4-tcp": 0, "packets-rx-ipv4-udp": 0, - "packets-rx-ipv4-host-internal": 820 + "packets-rx-ipv4-host-internal": 820, + "packets-rx-ipv6": 0, + "packets-rx-ipv6-tcp": 0, + "packets-rx-ipv6-udp": 0, + "packets-rx-ipv6-host-internal": 0, + "packets-rx-ipv6-no-next-header": 0 } ] } ``` The `packets-rx-ipv4-host-internal` refers to the IPv4 protocol number 61 (any host internal protocol) -which is used by some network testers as default type for traffic streams. \ No newline at end of file +which is used by some network testers as default type for traffic streams. +The same is valid for `packets-rx-ipv6-host-internal` which refers to next header 61 and +`packets-rx-ipv6-no-next-header` with next header 59. + From aa6f0cd0fa4433343a13b79e2b2c09c4d3e1f652 Mon Sep 17 00:00:00 2001 From: Christian Giese Date: Wed, 10 Mar 2021 17:44:11 +0100 Subject: [PATCH 3/6] Add L2TP session data rx/tx stats --- docs/l2tp.md | 8 +++++--- src/bbl_ctrl.c | 10 ++++++---- src/bbl_l2tp.c | 2 ++ src/bbl_l2tp.h | 6 ++++++ 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/docs/l2tp.md b/docs/l2tp.md index 9195adaf..0c27b535 100644 --- a/docs/l2tp.md +++ b/docs/l2tp.md @@ -281,8 +281,8 @@ Following an example with 30 L2TP LNS servers. "control-packets-rx-out-of-order": 0, "control-packets-tx": 102, "control-packets-tx-retry": 0, - "control-data-rx": 1406, - "control-data-tx": 206 + "data-packets-rx": 1406, + "data-packets-tx": 206 } ] } @@ -311,7 +311,9 @@ The `l2tp-sessions` command returns all L2TP sessions. "peer-tx-bps": 48000, "peer-rx-bps": 1000, "peer-ari": "DEU.RTBRICK.1", - "peer-aci": "0.0.0.0/0.0.0.0 eth 0:1" + "peer-aci": "0.0.0.0/0.0.0.0 eth 0:1", + "data-packets-rx": 79, + "data-packets-tx": 79 } ] } diff --git a/src/bbl_ctrl.c b/src/bbl_ctrl.c index 47eca05c..1e2de93a 100644 --- a/src/bbl_ctrl.c +++ b/src/bbl_ctrl.c @@ -768,8 +768,8 @@ bbl_ctrl_l2tp_tunnels(int fd, bbl_ctx_s *ctx, session_key_t *key __attribute__(( "control-packets-rx-out-of-order", l2tp_tunnel->stats.control_rx_ooo, "control-packets-tx", l2tp_tunnel->stats.control_tx, "control-packets-tx-retry", l2tp_tunnel->stats.control_retry, - "control-data-rx", l2tp_tunnel->stats.data_rx, - "control-data-tx", l2tp_tunnel->stats.data_tx); + "data-packets-rx", l2tp_tunnel->stats.data_rx, + "data-packets-tx", l2tp_tunnel->stats.data_tx); json_array_append(tunnels, tunnel); } l2tp_server = l2tp_server->next; @@ -791,7 +791,7 @@ bbl_ctrl_l2tp_tunnels(int fd, bbl_ctx_s *ctx, session_key_t *key __attribute__(( json_t * l2tp_session_json(bbl_l2tp_session_t *l2tp_session) { - return json_pack("{ss si si si si ss ss ss ss si si ss ss}", + return json_pack("{ss si si si si ss ss ss ss si si ss ss si si}", "state", l2tp_session_state_string(l2tp_session->state), "tunnel-id", l2tp_session->key.tunnel_id, "session-id", l2tp_session->key.session_id, @@ -804,7 +804,9 @@ l2tp_session_json(bbl_l2tp_session_t *l2tp_session) { "peer-tx-bps", l2tp_session->peer_tx_bps, "peer-rx-bps", l2tp_session->peer_rx_bps, "peer-ari", string_or_na(l2tp_session->peer_ari), - "peer-aci", string_or_na(l2tp_session->peer_aci)); + "peer-aci", string_or_na(l2tp_session->peer_aci), + "data-packets-rx", l2tp_session->stats.data_rx, + "data-packets-tx", l2tp_session->stats.data_tx); } ssize_t diff --git a/src/bbl_l2tp.c b/src/bbl_l2tp.c index d9f2404e..34a09b03 100644 --- a/src/bbl_l2tp.c +++ b/src/bbl_l2tp.c @@ -491,6 +491,7 @@ bbl_l2tp_send_data(bbl_l2tp_session_t *l2tp_session, uint16_t protocol, void *ne q->packet_len = len; CIRCLEQ_INSERT_TAIL(&interface->l2tp_tx_qhead, q, tx_qnode); l2tp_tunnel->stats.data_tx++; + l2tp_session->stats.data_tx++; interface->stats.l2tp_data_tx++; } else { LOG(ERROR, "L2TP Data Encode Error!\n"); @@ -847,6 +848,7 @@ bbl_l2tp_data_rx(bbl_ethernet_header_t *eth, bbl_l2tp_t *l2tp, bbl_interface_s * return; } + l2tp_session->stats.data_rx++; switch (l2tp->protocol) { case PROTOCOL_LCP: lcp_rx = (bbl_lcp_t*)l2tp->next; diff --git a/src/bbl_l2tp.h b/src/bbl_l2tp.h index 5a300bbf..d38750bb 100644 --- a/src/bbl_l2tp.h +++ b/src/bbl_l2tp.h @@ -212,6 +212,11 @@ typedef struct bbl_l2tp_session_ uint16_t session_id; } key; + struct { + uint64_t data_rx; /* Session data traffic received */ + uint64_t data_tx; /* Session data traffic send */ + } stats; + uint16_t peer_session_id; bool data_sequencing; @@ -250,6 +255,7 @@ typedef struct bbl_l2tp_session_ char *peer_sub_address; char *peer_ari; char *peer_aci; + } bbl_l2tp_session_t; const char* l2tp_message_string(l2tp_message_type type); From a4755f8e48af8fe7557440d1e759faaed09997e6 Mon Sep 17 00:00:00 2001 From: Christian Giese Date: Thu, 11 Mar 2021 11:38:46 +0100 Subject: [PATCH 4/6] Minor config parser bug --- src/bbl_config.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bbl_config.c b/src/bbl_config.c index d4758200..bc1d30bb 100644 --- a/src/bbl_config.c +++ b/src/bbl_config.c @@ -746,7 +746,7 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) { l2tp_server->data_offset = json_boolean_value(value); } } - } else if (json_is_object(sub)) { + } else if (json_is_object(section)) { fprintf(stderr, "JSON config error: List expected in L2TP server configuration but dictionary found\n"); } From 900d276181757d203cf127419b7d35fe1750e7a4 Mon Sep 17 00:00:00 2001 From: Christian Giese Date: Fri, 12 Mar 2021 13:44:41 +0100 Subject: [PATCH 5/6] Add L2TP data ipv4 rx/tx stats --- docs/l2tp.md | 4 +++- src/bbl_ctrl.c | 6 ++++-- src/bbl_l2tp.c | 4 ++++ src/bbl_l2tp.h | 2 ++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/l2tp.md b/docs/l2tp.md index 0c27b535..456d79b8 100644 --- a/docs/l2tp.md +++ b/docs/l2tp.md @@ -313,7 +313,9 @@ The `l2tp-sessions` command returns all L2TP sessions. "peer-ari": "DEU.RTBRICK.1", "peer-aci": "0.0.0.0/0.0.0.0 eth 0:1", "data-packets-rx": 79, - "data-packets-tx": 79 + "data-packets-tx": 79, + "data-ipv4-packets-rx": 15, + "data-ipv4-packets-tx": 15 } ] } diff --git a/src/bbl_ctrl.c b/src/bbl_ctrl.c index 1e2de93a..02f2411e 100644 --- a/src/bbl_ctrl.c +++ b/src/bbl_ctrl.c @@ -791,7 +791,7 @@ bbl_ctrl_l2tp_tunnels(int fd, bbl_ctx_s *ctx, session_key_t *key __attribute__(( json_t * l2tp_session_json(bbl_l2tp_session_t *l2tp_session) { - return json_pack("{ss si si si si ss ss ss ss si si ss ss si si}", + return json_pack("{ss si si si si ss ss ss ss si si ss ss si si si si}", "state", l2tp_session_state_string(l2tp_session->state), "tunnel-id", l2tp_session->key.tunnel_id, "session-id", l2tp_session->key.session_id, @@ -806,7 +806,9 @@ l2tp_session_json(bbl_l2tp_session_t *l2tp_session) { "peer-ari", string_or_na(l2tp_session->peer_ari), "peer-aci", string_or_na(l2tp_session->peer_aci), "data-packets-rx", l2tp_session->stats.data_rx, - "data-packets-tx", l2tp_session->stats.data_tx); + "data-packets-tx", l2tp_session->stats.data_tx, + "data-ipv4-packets-rx", l2tp_session->stats.data_ipv4_rx, + "data-ipv4-packets-tx", l2tp_session->stats.data_ipv4_tx); } ssize_t diff --git a/src/bbl_l2tp.c b/src/bbl_l2tp.c index 34a09b03..c0a42ffd 100644 --- a/src/bbl_l2tp.c +++ b/src/bbl_l2tp.c @@ -493,6 +493,9 @@ bbl_l2tp_send_data(bbl_l2tp_session_t *l2tp_session, uint16_t protocol, void *ne l2tp_tunnel->stats.data_tx++; l2tp_session->stats.data_tx++; interface->stats.l2tp_data_tx++; + if(protocol == PROTOCOL_IPV4) { + l2tp_session->stats.data_ipv4_tx++; + } } else { LOG(ERROR, "L2TP Data Encode Error!\n"); free(q); @@ -946,6 +949,7 @@ bbl_l2tp_data_rx(bbl_ethernet_header_t *eth, bbl_l2tp_t *l2tp, bbl_interface_s * } break; case PROTOCOL_IPV4: + l2tp_session->stats.data_ipv4_rx++; ipv4 = (bbl_ipv4_t*)l2tp->next; if(ipv4->protocol == PROTOCOL_IPV4_UDP) { udp = (bbl_udp_t*)ipv4->next; diff --git a/src/bbl_l2tp.h b/src/bbl_l2tp.h index d38750bb..de62d1c4 100644 --- a/src/bbl_l2tp.h +++ b/src/bbl_l2tp.h @@ -215,6 +215,8 @@ typedef struct bbl_l2tp_session_ struct { uint64_t data_rx; /* Session data traffic received */ uint64_t data_tx; /* Session data traffic send */ + uint64_t data_ipv4_rx; /* Session data ipv4 traffic received */ + uint64_t data_ipv4_tx; /* Session data ppv4 traffic send */ } stats; uint16_t peer_session_id; From ec72cc946e69963bdfcc62a07eb18861fd6f403f Mon Sep 17 00:00:00 2001 From: Christian Giese Date: Fri, 12 Mar 2021 14:09:38 +0100 Subject: [PATCH 6/6] Add session traffic verifcation status command --- docs/ctrl.md | 1 + docs/reports.md | 22 ++++++++++++++++++++++ src/bbl_ctrl.c | 17 +++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/docs/ctrl.md b/docs/ctrl.md index 9a105d5b..8a89c737 100644 --- a/docs/ctrl.md +++ b/docs/ctrl.md @@ -110,6 +110,7 @@ Attribute | Description `interfaces` | List all interfaces with index `session-counters` | Return session counters `terminate` | Terminate all sessions similar to sending SIGINT (ctr+c) +`session-traffic` | Display session traffic statistics | | `session-traffic-enabled` | Enable session traffic for all sessions `session-traffic-disabled` | Disable session traffic for all sessions `multicast-traffic-start` | Start sending multicast traffic from network interface diff --git a/docs/reports.md b/docs/reports.md index 8036a1a4..1b9fca4f 100644 --- a/docs/reports.md +++ b/docs/reports.md @@ -325,6 +325,28 @@ JSON: } ``` +The flow verification status can be also queried via +global control socket command `session-traffic`. + +`$ cat command.json | jq .` +```json +{ + "command": "session-traffic" +} +``` + +`$ cat command.json | sudo nc -U test.socket | jq .` +```json +{ + "status": "ok", + "code": 200, + "session-traffic": { + "total-flows": 3000, + "verified-flows": 3000 + } +} +``` + ### First Sequence Number Received If session traffic is enabled, the BNG Blaster will start sending bidirectional diff --git a/src/bbl_ctrl.c b/src/bbl_ctrl.c index 02f2411e..6cd35c27 100644 --- a/src/bbl_ctrl.c +++ b/src/bbl_ctrl.c @@ -96,6 +96,22 @@ bbl_ctrl_multicast_traffic_stop(int fd, bbl_ctx_s *ctx, session_key_t *key __att return bbl_ctrl_status(fd, "ok", 200, NULL); } +ssize_t +bbl_ctrl_session_traffic_stats(int fd, bbl_ctx_s *ctx, session_key_t *key __attribute__((unused)), json_t* arguments __attribute__((unused))) { + ssize_t result = 0; + json_t *root = json_pack("{ss si s{si si}}", + "status", "ok", + "code", 200, + "session-traffic", + "total-flows", ctx->stats.session_traffic_flows, + "verified-flows", ctx->stats.session_traffic_flows_verified); + if(root) { + result = json_dumpfd(root, fd, 0); + json_decref(root); + } + return result; +} + ssize_t bbl_ctrl_session_traffic(int fd, bbl_ctx_s *ctx, session_key_t *key, bool status) { struct dict_itor *itor; @@ -944,6 +960,7 @@ struct action actions[] = { {"session-counters", bbl_ctrl_session_counters}, {"session-info", bbl_ctrl_session_info}, {"session-traffic-enabled", bbl_ctrl_session_traffic_start}, + {"session-traffic", bbl_ctrl_session_traffic_stats}, {"session-traffic-start", bbl_ctrl_session_traffic_start}, {"session-traffic-disabled", bbl_ctrl_session_traffic_stop}, {"session-traffic-stop", bbl_ctrl_session_traffic_stop},