Merge pull request #19 from rtbrick/dev

Dev
This commit is contained in:
Christian Giese
2021-03-12 15:32:07 +01:00
committed by GitHub
10 changed files with 90 additions and 15 deletions
+1 -1
View File
@@ -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.
+1
View File
@@ -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
+1 -1
View File
@@ -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
+7 -3
View File
@@ -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,11 @@ 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,
"data-ipv4-packets-rx": 15,
"data-ipv4-packets-tx": 15
}
]
}
+16 -3
View File
@@ -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.
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.
+22
View File
@@ -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
+1 -1
View File
@@ -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");
}
+25 -4
View File
@@ -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;
@@ -768,8 +784,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 +807,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 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 +820,11 @@ 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,
"data-ipv4-packets-rx", l2tp_session->stats.data_ipv4_rx,
"data-ipv4-packets-tx", l2tp_session->stats.data_ipv4_tx);
}
ssize_t
@@ -940,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},
+8 -2
View File
@@ -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));
@@ -491,7 +491,11 @@ 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++;
if(protocol == PROTOCOL_IPV4) {
l2tp_session->stats.data_ipv4_tx++;
}
} else {
LOG(ERROR, "L2TP Data Encode Error!\n");
free(q);
@@ -788,7 +792,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),
@@ -847,6 +851,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;
@@ -944,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;
+8
View File
@@ -212,6 +212,13 @@ 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 */
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;
bool data_sequencing;
@@ -250,6 +257,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);