mirror of
https://github.com/rtbrick/bngblaster.git
synced 2024-05-06 15:54:57 +00:00
@@ -3,7 +3,7 @@
|
||||

|
||||
|
||||
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.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user