Merge pull request #52 from rtbrick/dev

Cleanup / Docu
This commit is contained in:
Christian Giese
2021-11-02 16:25:06 +01:00
committed by GitHub
45 changed files with 345 additions and 311 deletions
+2 -2
View File
@@ -13,7 +13,7 @@ A clear and concise description of what the bug is.
**To Reproduce**
Version (`bngblaster -v`):
Version (`bngblaster -v`):
```
```
@@ -22,7 +22,7 @@ JSON configuration:
```json
{
}
```
```
Steps to reproduce the behavior:
1. ...
+3 -3
View File
@@ -10,7 +10,7 @@
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ dev ]
@@ -50,11 +50,11 @@ jobs:
- name: Download RtBrick libdict
shell: bash
run: wget https://github.com/rtbrick/libdict/releases/download/v1.0.1/libdict-debian.zip
- name: Install RtBrick libdict
shell: bash
run: unzip libdict-debian.zip; sudo dpkg -i libdict_1.0.1_amd64.deb; sudo dpkg -i libdict-dev_1.0.1_amd64.deb
- name: Install Dependencies
shell: bash
run: sudo apt install -y libcunit1-dev libncurses5-dev libssl-dev libjansson-dev libcmocka-dev libpcap-dev
+2 -2
View File
@@ -1,4 +1,4 @@
## BNG Blaster Documentation
# BNG Blaster Documentation
- [Introduction](intro.md)
- [Installation](install.md)
@@ -12,4 +12,4 @@
- [IPoE](ipoe.md)
- [Legal Interception](li.md)
- [Traffic Streams](streams.md)
- [A10NSP](a10nsp.md)
- [A10NSP](a10nsp.md)
+6 -6
View File
@@ -1,14 +1,14 @@
# A10NSP
The A10NSP interface emulates an layer two provider interface. The term A10
refers to the end-to-end ADSL network reference model from TR-025.
The A10NSP interface emulates an layer two provider interface. The term A10
refers to the end-to-end ADSL network reference model from TR-025.
Following a basic PPPoE/A10NSP configuration example which is
Following a basic PPPoE/A10NSP configuration example which is
detailed explained in the configuration section.
```json
{
"interfaces": {
"interfaces": {
"rx-interval": 1,
"a10nsp": [
{
@@ -32,7 +32,7 @@ detailed explained in the configuration section.
"inner-vlan": 7,
"stream-group-id": 1
}
]
]
},
"pppoe": {
"reconnect": true,
@@ -71,4 +71,4 @@ detailed explained in the configuration section.
}
]
}
```
```
+28 -23
View File
@@ -1,6 +1,7 @@
# Configuration
Following an example configuration file which is explained in detail below.
```json
{
"interfaces": {
@@ -127,7 +128,7 @@ ring buffer and send directly trough RAW packet sockets.
The interfaces used in BNG Blaster do not need IP addresses configured in the host
operating system but they need to be in up state.
```
```cli
sudo ip link set dev <interface> up
```
@@ -135,12 +136,12 @@ It is not possible to send packets larger than the interface MTU which is 1500 p
but for PPPoE with multiple VLAN headers this might be not enough for large packets.
Therefore the interface MTU should be increased using the following commands.
```
```cli
sudo ip link set mtu 9000 dev <interface>
```
This can be also archived via netplan using the following configuration for each BNG Blaster
interface.
interface.
```yaml
network:
@@ -168,12 +169,12 @@ The number of interfaces is currently limited to 32!
Attribute | Description | Default
--------- | ----------- | -------
`interface` | Network interface name (e.g. eth0, ...)
`address` | `Local network interface IPv4 address
`address` | Local network interface IPv4 address
`gateway` | Gateway network interface IPv4 address
`address-ipv6` | Local network interface IPv6 address (implicitly /64) | -
`gateway-ipv6` | Gateway network interface IPv6 address (implicitly /64)
`vlan` | Network interface VLAN | 0 (untagged)
`gateway-mac`| Optional set gateway MAC address manually
`gateway-mac`| Optional set gateway MAC address manually
`gateway-resolve-wait` | Sessions will not start until gateways are resolved | true
The BNG Blaster supports also multiple access interfaces
@@ -216,7 +217,7 @@ the option `network-interface` is supported in different sections.
Attribute | Description | Default
--------- | ----------- | -------
`interface` | Access interface name (e.g. eth0, ...)
`network-interface` | Select the corresponding network interface for this session |
`network-interface` | Select the corresponding network interface for this session |
`type` | Switch the access type between `pppoe` (PPP over Ethernet) and `ipoe` (IP over Ethernet) | pppoe
`vlan-mode` | Set VLAN mode `1:1` or `N:1` | 1:1
`qinq` | Set outer VLAN ethertype to QinQ (0x88a8) | false
@@ -261,13 +262,14 @@ Attribute | Description | Default
For all modes it is possible to configure between zero and three VLAN
tags on the access interface as shown below.
```
```text
[ethernet][outer-vlan][inner-vlan][third-vlan][pppoe]...
```
**Untagged**
#### Untagged
With untagged only one session is possible.
```json
{
"access": {
@@ -280,7 +282,8 @@ With untagged only one session is possible.
}
```
**Single Tagged**
#### Single Tagged
```json
{
"access": {
@@ -293,7 +296,8 @@ With untagged only one session is possible.
}
```
**Double Tagged**
#### Double Tagged
```json
{
"access": {
@@ -306,7 +310,8 @@ With untagged only one session is possible.
}
```
**Triple Tagged**
#### Triple Tagged
```json
{
"access": {
@@ -367,7 +372,6 @@ or VLAN ranges as shown in the example below.
}
```
Both network and access interfaces are optional but obviously at least
one interface is required to start the BNG Blaster.
@@ -409,7 +413,7 @@ Attribute | Description | Default
--------- | ----------- | -------
`interface` | A10nSP interface name (e.g. eth0, ...)
`qinq` | Set outer VLAN ethertype to QinQ (0x88a8) | false
`mac`| Optional set gateway interface address manually
`mac`| Optional set gateway interface address manually
The BNG Blaster supports also multiple A10NSP interfaces
as shown in the example below.
@@ -451,6 +455,7 @@ Per default sessions are created by iteration over inner VLAN range first and ou
Which can be changed by `iterate-vlan-outer` to iterate on outer VLAN first and inner VLAN second.
Therefore the following configuration generates the sessions on VLAN (outer:inner) 1:3, 1:4, 2:3, 2:4 per default or alternative 1:3, 2:3, 1:4, 2:4 with `iterate-vlan-outer` enabled.
```json
{
"outer-vlan-min": 1,
@@ -526,7 +531,7 @@ Attribute | Description | Default
Attribute | Description | Default
--------- | ----------- | -------
`enable` | This option allows to enable or disable the IPCP protocol | true
`request-ip` | Include IP-Address with 0.0.0.0 in initial LCP configuration request | true
`request-ip` | Include IP-Address with 0.0.0.0 in initial LCP configuration request | true
`request-dns1` | Request Primary DNS Server Address (option 129) | true
`request-dns2` | Request Secondary DNS Server Address (option 131) | true
`conf-request-timeout` | IPCP configuration request timeout in seconds | 5
@@ -588,7 +593,7 @@ Attribute | Description | Default
`send-multicast-traffic` | Generate multicast traffic | false
`multicast-traffic-length` | Multicast traffic IP length | 76
`multicast-traffic-tos` | Multicast traffic TOS priority | 0
`network-interface` | Multicast traffic source interface |
`network-interface` | Multicast traffic source interface |
Per default join and leave requests are send using dedicated reports. The option `combined-leave-join` allows
the combination of leave and join records within a single IGMPv3 report using multiple group records.
@@ -683,8 +688,8 @@ Attribute | Description | Default
`length` | Layer 3 (IP + payload) traffic length (76 - 9000) | 128
`pps` | Stream traffic rate in packets per second | 1
`bps` | Stream traffic rate in bits per second (layer 3) |
`a10nsp-interface` | Select the corresponding A10NSP interface for this stream |
`network-interface` | Select the corresponding network interface for this stream |
`a10nsp-interface` | Select the corresponding A10NSP interface for this stream |
`network-interface` | Select the corresponding network interface for this stream |
`network-ipv4-address` | Overwrite network interface IPv4 address |
`network-ipv6-address` | Overwrite network interface IPv6 address |
`destination-ipv4-address` | Overwrite the IPv4 destination address |
@@ -694,8 +699,8 @@ Attribute | Description | Default
For L2TP downstream traffic the IPv4 TOS is applied to the outer IPv4 and inner IPv4 header.
The `pps` option supports also float numbers like 0.1, or 2.5 PPS and has priority over `bps`
where second is only a helper to calculate the `pps` based on given `bps` and `length`.
The `pps` option supports also float numbers like 0.1, or 2.5 PPS and has priority over `bps`
where second is only a helper to calculate the `pps` based on given `bps` and `length`.
## Access-Line
@@ -748,10 +753,10 @@ Attribute | Description | Default
`pon-max-up` | PON Tree Maximum Data Rate Upstream | 0
`pon-max-down` | PON Tree Maximum Data Rate Downstream | 0
Attributes with value set to 0 will not be send.
Attributes with value set to 0 will not be send.
The values for `rate-up`, `rate-down` and `dsl-type` defined in the
access-line or interface section have priority over those defined
The values for `rate-up`, `rate-down` and `dsl-type` defined in the
access-line or interface section have priority over those defined
here.
```json
@@ -798,4 +803,4 @@ here.
}
]
}
```
```
+13 -3
View File
@@ -9,12 +9,15 @@ The control socket will be optionally enabled by providing the path to the socke
using the argument `-S` (`bngblaster -S test.socket`).
`$ cat command.json | jq .`
```json
{
"command": "session-counters"
}
```
`$ cat command.json | sudo nc -U test.socket | jq .`
```json
{
"status": "ok",
@@ -32,6 +35,7 @@ Each request must contain at least the `command` element which carries
the actual command which is invoked with optional arguments.
`$ cat command.json | jq .`
```json
{
"command": "session-info",
@@ -42,6 +46,7 @@ the actual command which is invoked with optional arguments.
```
`$ cat command.json | sudo nc -U test.socket | jq .`
```json
{
"status": "ok",
@@ -110,6 +115,7 @@ if request was successfully. The status can be also set to `warning` or
`error` with corresponding error code and an optional error message.
`$ cat command.json | sudo nc -U test.socket | jq .`
```json
{
"status": "warning",
@@ -123,7 +129,7 @@ if request was successfully. The status can be also set to `warning` or
The python script `bngblaster-cli` provides a simple CLI tool
for interactive communication with the BNG Blaster.
```
```cli
$ sudo bngblaster-cli
BNG Blaster Control Socket Client
@@ -137,6 +143,7 @@ Examples:
```
`$ sudo bngblaster-cli run.sock session-counters | jq .`
```json
{
"status": "ok",
@@ -149,6 +156,7 @@ Examples:
}
}
```
## Control Socket Commands
### Global Commands
@@ -186,6 +194,7 @@ command. For N:1 sessions only `session-id` is supported because multiple sessio
be assigned to a single VLAN in this mode.
`$ cat command.json | jq .`
```json
{
"command": "session-info",
@@ -238,6 +247,7 @@ The L2TP CSURQ command expects the local tunnel-id and a list of remote
session-id for which a connect speed update is requested.
`$ cat command.json | jq .`
```json
{
"command": "l2tp-csurq",
@@ -257,6 +267,6 @@ This command can be executed as shown below using the CLI tool.
`$ sudo bngblaster-cli run.sock l2tp-csurq tunnel-id 1 sessions [1,2,3,4]`
The L2TP session terminate command allows to test result (RFC2661) and disconnect (RFC3145) codes.
The L2TP session terminate command allows to test result (RFC2661) and disconnect (RFC3145) codes.
`$ sudo bngblaster-cli run.sock l2tp-session-terminate session-id 1 result-code 2 error-message "LCP request" disconnect-code 3 disconnect-message "LCP terminate request"`
`$ sudo bngblaster-cli run.sock l2tp-session-terminate session-id 1 result-code 2 error-message "LCP request" disconnect-code 3 disconnect-message "LCP terminate request"`
+2 -2
View File
@@ -24,8 +24,8 @@ This command installs the BNG Blaster to `/usr/sbin/bngblaster`.
### Dependencies
The BNG Blaster has dependencies to the RtBrick
[libdict fork](https://github.com/rtbrick/libdict)
The BNG Blaster has dependencies to the RtBrick
[libdict fork](https://github.com/rtbrick/libdict)
and the following standard dependencies:
```cli
+23 -23
View File
@@ -4,8 +4,8 @@ Building a BNG from scratch requires a lot of testing but commercial BNG test so
is often very expensive, resource intensive and provide a lot of administrative overhead
to maintain such.
Therefore we decided to build an open source network test software initially focused on BNG
and IPTV testing but constantly enhanced and planned for more common (non-BNG) network testing.
Therefore we decided to build an open source network test software initially focused on BNG
and IPTV testing but constantly enhanced and planned for more common (non-BNG) network testing.
The BNG Blaster was completely build from scratch, targeted for max scaling with small
resource footprint, simple to use and easy to integrate in any test automation infrastructure.
@@ -23,19 +23,19 @@ IPTV, L2TPv2 (LNS emulation), L2BSA, QoS, forwarding verification and convergenc
**Info:** _The BNG Blaster Controller is not yet published but you can send
a mail to bngblaster@rtbrick.com if you are interested to get early access!_
```
```cli
$ bngblaster --help
____ __ ____ _ __ ,/
/ __ \ / /_ / __ ) _____ (_)_____ / /__ ,'/
/ /_/ // __// __ |/ ___// // ___// //_/ ,' /
/ _, _// /_ / /_/ // / / // /__ / ,< ,' /_____,
/_/ |_| \__//_____//_/ /_/ \___//_/|_| .'____ ,'
/ _, _// /_ / /_/ // / / // /__ / ,< ,' /_____,
/_/ |_| \__//_____//_/ /_/ \___//_/|_| .'____ ,'
____ _ _ ______ ____ _ _ / ,'
/ __ ) / | / // ____/ / __ ) / /____ _ _____ / /_ ___ ____ / ,'
/ __ |/ |/ // / __ / __ |/ // __ `// ___// __// _ \ / ___/ /,'
/ /_/ // /| // /_/ / / /_/ // // /_/ /(__ )/ /_ / __// / /
/ /_/ // /| // /_/ / / /_/ // // /_/ /(__ )/ /_ / __// / /
/_____//_/ |_/ \____/ /_____//_/ \__,_//____/ \__/ \___//_/
Usage: bngblaster [OPTIONS]
@@ -72,19 +72,19 @@ log viewer as shown below.
The BNG Blaster has been completely built from scratch, including user-space implementations of the entire protocol
stack you need for interfacing with a BNG. Its core is based on a very simple event loop which serves timers and signals.
The timers have been built using a lightweight constant time (`O(1)`) library which we built purposely to start, restart
The timers have been built using a lightweight constant time (`O(1)`) library which we built purposely to start, restart
and delete the protocol session FSM timers quickly and at scale.
The BNG Blaster expects a Linux kernel network interface which is up, but not configured with any IP addresses or VLAN as it
expects to receive and transmit RAW ethernet packets.
The BNG Blaster expects a Linux kernel network interface which is up, but not configured with any IP addresses or VLAN as it
expects to receive and transmit RAW ethernet packets.
The BNG Blaster does I/O using high-speed polling timers with a mix of Linux
[RAW Packet Sockets](https://man7.org/linux/man-pages/man7/packet.7.html) and
[Packet MMAP](https://www.kernel.org/doc/html/latest/networking/packet_mmap.html).
The BNG Blaster does I/O using high-speed polling timers with a mix of Linux
[RAW Packet Sockets](https://man7.org/linux/man-pages/man7/packet.7.html) and
[Packet MMAP](https://www.kernel.org/doc/html/latest/networking/packet_mmap.html).
The second one is a so-called PACKET_RX_RING/PACKET_TX_RING abstraction where a user-space program gets a fast-lane into reading
and writing to kernel interfaces using a shared ring buffer. The shared ring buffer is a memory mapped "window" that is shared
between kernel and user-space. This low overhead abstraction allows to transmit and receive traffic without doing expensive system calls.
The second one is a so-called PACKET_RX_RING/PACKET_TX_RING abstraction where a user-space program gets a fast-lane into reading
and writing to kernel interfaces using a shared ring buffer. The shared ring buffer is a memory mapped "window" that is shared
between kernel and user-space. This low overhead abstraction allows to transmit and receive traffic without doing expensive system calls.
Sending and transmitting traffic via Packet MMAP is as easy as just by copying a packet into a buffer and setting a flag.
![BNG Blaster Architecture](images/bbl_arch.png)
@@ -95,21 +95,21 @@ buffer and send directly trough RAW packet sockets. This combination was the mos
BNG Blasters primary design goal is to simulate thousands of subscriber CPE's with a small hardware resource footprint. Simple
to use and easy to integrate in our robot test automation infrastructure. This allows to simulate more than hundred thousand
PPPoE or IPoE (DHCP) subscribers including IPTV, traffic verification and convergence testing from a single medium scale
PPPoE or IPoE (DHCP) subscribers including IPTV, traffic verification and convergence testing from a single medium scale
virtual machine or to run the blaster directly from a laptop.
The BNG Blaster provides three types of interfaces. The first interface is called the access interface which emulates the PPPoE
sessions. The second interface-type is called network interface. This is used for emulating the core-facing side of the
internet. The last type is called a10nsp interface which emulates an layer two provider interface. The term A10
refers to the end-to-end ADSL network reference model from TR-025.
internet. The last type is called a10nsp interface which emulates an layer two provider interface. The term A10
refers to the end-to-end ADSL network reference model from TR-025.
![BNG Blaster Interfaces](images/bbl_interfaces.png)
This allows to verify IP reachability by sending bidirectional traffic between all PPPoE sessions on access-interface and the
network interface. The network interface is also used to inject downstream multicast test traffic for IPTV tests. It is also
possible to send RAW traffic streams between multiple network interfaces without any access interface defined for non-BNG
testing.
network interface. The network interface is also used to inject downstream multicast test traffic for IPTV tests. It is also
possible to send RAW traffic streams between multiple network interfaces without any access interface defined for non-BNG
testing.
One popular example for non-BNG tests with the BNG Blaster is the verification of a BGP full-table by injecting around 1M
One popular example for non-BNG tests with the BNG Blaster is the verification of a BGP full-table by injecting around 1M
prefixes and setting up traffic streams for all prefixes with at least one PPS (1M PPS). The BNG Blaster is able to verify
and analyze every single flow with detailed per flow statistics (receive rate, loss, latency, ...).
and analyze every single flow with detailed per flow statistics (receive rate, loss, latency, ...).
+2 -1
View File
@@ -61,9 +61,10 @@ The most common case for IPoE is using DHCPv4/v6 as shown below.
## IPoE Session Information
The control socket command `session-info session-id <id>` provides
detailed information for IPoE sessions.
detailed information for IPoE sessions.
`$ sudo bngblaster-cli run.sock session-info session-id 1 | jq .`
```json
{
"status": "ok",
+2
View File
@@ -259,6 +259,7 @@ Following an example with 30 L2TP LNS servers.
## Receive Tunnel Information
`$ sudo bngblaster-cli run.sock l2tp-tunnels`
```json
{
"status": "ok",
@@ -291,6 +292,7 @@ Following an example with 30 L2TP LNS servers.
The `l2tp-sessions` command returns all L2TP sessions.
`$ sudo bngblaster-cli run.sock l2tp-sessions`
```json
{
"status": "ok",
+3 -2
View File
@@ -5,7 +5,8 @@ about the received flows. Today only the BCM QMX LI header format is supported b
headers can be easily integrated.
*BCM QMX LI Header Format*
```
```text
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| D | PT | SPT | LIID |
@@ -33,6 +34,7 @@ mediation device as shown in the following example.
The received flows can be queried using the control socket.
`$ sudo bngblaster-cli run.sock li-flows`
```json
{
"status": "ok",
@@ -88,4 +90,3 @@ The `packets-rx-ipv4-host-internal` refers to the IPv4 protocol number 61 (any h
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.
+10 -5
View File
@@ -24,6 +24,7 @@ BNG Blaster instance.
The following example shows generates traffic for 100 multicast groups
with one packet per millisecond for every group as required to measure the join and leave
delay in milliseconds.
```json
{
"interfaces": {
@@ -48,11 +49,11 @@ delay in milliseconds.
The `tx-interval` and `rx-interval` should be set to at to at least `1.0` (1ms) for more
precise IGMP join/leave delay measurements.
It is also possible to generate multicast traffic using RAW streams as shown in the
It is also possible to generate multicast traffic using RAW streams as shown in the
example below:
```json
{
{
"streams": [
{
"name": "MC1",
@@ -80,10 +81,10 @@ example below:
}
```
Using RAW streams allows to generate streams distributed over multiple network interfaces.
Using RAW streams allows to generate streams distributed over multiple network interfaces.
Setting the `destination-ipv4-address` to an multicast IPv4 address is enough to generate
proper multicast streams. All headers including the BNG Blaster header will be automatically
set for multicast. Therefore such streams can be also used to measure the IGMP join and leave
set for multicast. Therefore such streams can be also used to measure the IGMP join and leave
delay.
## Manual Join/Leave Testing
@@ -92,6 +93,7 @@ It is possible to join and leave multicast groups manually using the <<Control S
shown in the example below.
`$ sudo bngblaster-cli run.sock igmp-join session-id 1 group 232.1.1.1 source1 202.11.23.101 source2 202.11.23.102 source3 202.11.23.103`
```json
{
"status": "ok"
@@ -99,6 +101,7 @@ shown in the example below.
```
`$ sudo bngblaster-cli run.sock igmp-info session-id 1`
```json
{
"status": "ok",
@@ -119,7 +122,8 @@ shown in the example below.
}
```
`$ sudo bngblaster-cli run.sock igmp-leave session-id 1 group 232.1.1.1 `
`$ sudo bngblaster-cli run.sock igmp-leave session-id 1 group 232.1.1.1`
```json
{
"status": "ok"
@@ -127,6 +131,7 @@ shown in the example below.
```
`$ sudo bngblaster-cli run.sock igmp-info session-id 1`
```json
{
"status": "ok",
+7 -6
View File
@@ -4,7 +4,7 @@ Emulating PPP over Ethernet (PPPoE) sessions was initial
use case of the BNG Blaster supporting 1:1 and N:1 VLAN
mode.
Following a basic PPPoE configuration example which is
Following a basic PPPoE configuration example which is
detailed explained in the configuration section.
```json
@@ -102,20 +102,21 @@ This chapter refers to RFC 2153 PPP vendor extensions.
Per default all LCP vendor specific requests will be rejected sending a
LCP code reject message. With `ppp->lcp->ignore-vendor-specific` enabled,
those messages will be ignored as required to emulate different CPE
those messages will be ignored as required to emulate different CPE
behaviors.
The option `ppp->lcp->connection-status-message` allows to accept LCP vendor requests
with any OUI if kind is set to `1` by responding with vendor request of
The option `ppp->lcp->connection-status-message` allows to accept LCP vendor requests
with any OUI if kind is set to `1` by responding with vendor request of
kind `2`. The OUI from request is copied to response in this case.
The value from request is stored in the session as `connection-status-message`.
## PPPoE Session Information
The control socket command `session-info session-id <id>` provides
detailed information for PPPoE sessions.
detailed information for PPPoE sessions.
`$ sudo bngblaster-cli run.sock session-info session-id 1 | jq .`
```json
{
"status": "ok",
@@ -177,4 +178,4 @@ detailed information for PPPoE sessions.
}
}
}
```
```
+12 -4
View File
@@ -5,7 +5,7 @@ at the end of of the test execution.
## Standard Output Reports
```
```text
____ __ ____ _ __ ,/
/ __ \ / /_ / __ ) _____ (_)_____ / /__ ,'/
@@ -245,7 +245,7 @@ as shown in the example below.
}
```
The optional argument `-j sessions` allows to include per session statistics
The optional argument `-j sessions` allows to include per session statistics
in the report file. Similar with `-j streams` which allows to include per stream
statistics. Both options could be also combined.
@@ -276,7 +276,8 @@ Assuming session traffic is enabled for IPv4, IPv6 and IPv6PD, in this case
all statics should be equal matching the number of sessions.
*Example report output for 100 sessions:*
```
```text
Session Traffic:
Config:
IPv4 PPS: 1
@@ -299,6 +300,7 @@ Session Traffic:
```
JSON:
```json
{
"session-traffic": {
@@ -333,6 +335,7 @@ The flow verification status can be also queried via
global control socket command `session-traffic`.
`$ cat command.json | jq .`
```json
{
"command": "session-traffic"
@@ -340,6 +343,7 @@ global control socket command `session-traffic`.
```
`$ cat command.json | sudo nc -U test.socket | jq .`
```json
{
"status": "ok",
@@ -359,6 +363,7 @@ established using the rate as configured starting with sequence number 1 for
each flow.
*Example config output with 1 packet per second:*
```json
{
"session-traffic": {
@@ -374,7 +379,8 @@ combined with a rate of 1 PPS would mean that it took between 4
and 5 seconds until forwarding is working.
*Example report output with 1 packet per second:*
```
```text
STDOUT:
First Sequence Number Received:
@@ -385,7 +391,9 @@ STDOUT:
Network IPv6 MIN: 1 MAX: 1
Network IPv6PD MIN: 1 MAX: 1
```
JSON:
```json
{
"first-seq-rx-access-ipv4-min": 1,
+16 -15
View File
@@ -108,7 +108,7 @@ Following a simple example using streams as described in
## Stream Configuration File
The command line argument `-T <filename>` allows to include
The command line argument `-T <filename>` allows to include
streams defined from a separate file. The format is equal to
streams defined in the actual configuration file. Such stream
configuration files could be generated by scripts and
@@ -125,6 +125,7 @@ easily merged with the base configuration.
The `session-streams` command returns detailed stream statistics per session.
`$ sudo bngblaster-cli run.sock session-streams session-id 1`
```json
{
"status": "ok",
@@ -244,6 +245,7 @@ accounting of the BNG, meaning session rx/tx packets excluding control traffic.
Each flow can be queried separately using jsonpath expression with name and direction or flow-id.
`$ sudo bngblaster-cli run.sock session-streams session-id 1 | jq '."session-streams".streams[] | select(.name == "BE" and .direction == "downstream" )'`
```json
{
"name": "BE",
@@ -278,8 +280,8 @@ Streams with default `stream-group-id` set to zero are considered as raw streams
bound to any session which is supported in downstream only. For those streams the
destination address must be explicitly set.
RAW streams can be used for traffic between two or network interfaces but also to send traffic
from network to access interfaces.
RAW streams can be used for traffic between two or network interfaces but also to send traffic
from network to access interfaces.
```json
{
@@ -304,18 +306,18 @@ multicast MAC address automatically. For unicast traffic the network gateway MAC
## Threaded Streams
With threading enabled, those streams will be started per default in a dedicated thread per flow.
With threading enabled, those streams will be started per default in a dedicated thread per flow.
This means one thread per session and stream direction. A threaded, bidirectional stream assigned
to 10 sessions will therefore run in 20 threads. It is also possible to assign multiple
steams to a single thread using thread groups.
steams to a single thread using thread groups.
In most environments we see between 200.000 and 300.000 PPS single threaded is working. Depending
on actual setup this can be also much more. With threaded streams we are also able to scale up to
10 million PPS depending on actual configuration and setup. This allows to start 1 million flows
with 1 PPS per flow over 4 threads in example to verify all prefixes of a BGP full table.
In most environments we see between 200.000 and 300.000 PPS single threaded is working. Depending
on actual setup this can be also much more. With threaded streams we are also able to scale up to
10 million PPS depending on actual configuration and setup. This allows to start 1 million flows
with 1 PPS per flow over 4 threads in example to verify all prefixes of a BGP full table.
The BNG Blaster is currently tested for up to 1 million flows which is not a hard limitation but
everything above should be considered as experimental.
The BNG Blaster is currently tested for up to 1 million flows which is not a hard limitation but
everything above should be considered as experimental.
```json
{
@@ -360,7 +362,6 @@ session identifier.
`$ sudo bngblaster-cli run.sock stream-traffic-disabled`
Alternatively all session and stream traffic (including RAW streams)
can be started or stopped globally using the `traffic-start` and
`traffic-stop` commands.
Alternatively all session and stream traffic (including RAW streams)
can be started or stopped globally using the `traffic-start` and
`traffic-stop` commands.
+5 -5
View File
@@ -23,7 +23,7 @@ The 64 bit session key is used for all traffic from access (upstream)
and to access (downstream) interfaces to identify the corresponding
session which has send or should receive the packet.
```
```text
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| BNG Blaster Magic Sequence |
@@ -52,7 +52,7 @@ session which has send or should receive the packet.
### Multicast Traffic
```
```text
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| BNG Blaster Magic Sequence |
@@ -84,7 +84,8 @@ stored in host byte order for faster processing
### BNG Blaster Magic Sequence
The 64 bit magic sequence is the word `RtBrick!` decoded as ASCII:
```
```text
0x5274427269636b21
```
@@ -109,7 +110,7 @@ This number 0 means that sequencing is disabled.
The 64 bit nanoseconds send timestamp is used for optional latency and
jitter calculations.
```
```text
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Seconds |
@@ -119,4 +120,3 @@ jitter calculations.
```
The timestamp 0 means that timestamps are disabled.
+5 -5
View File
@@ -256,12 +256,12 @@ bbl_ctrl_job (timer_s *timer)
continue;
}
if(interface->gateway6.len && !interface->icmpv6_nd_resolved) {
LOG(DEBUG, "Wait for %s IPv6 gateway %s to be resolved\n",
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",
LOG(DEBUG, "Wait for %s IPv4 gateway %s to be resolved\n",
interface->name, format_ipv4_address(&interface->gateway));
return;
}
@@ -367,7 +367,7 @@ bbl_ctrl_job (timer_s *timer)
/**
* @brief BNG BLASTER MAIN FUNCTION
*
*
* @param argc number of argument values
* @param argv argument values
* @return int return code
@@ -565,7 +565,7 @@ main (int argc, char *argv[])
}
}
/* Start smear job. Use a crazy nsec bucket '12345678',
/* Start smear job. Use a crazy nsec bucket '12345678',
* such that we do not accidentally smear ourselves. */
timer_add_periodic(&ctx->timer_root, &ctx->smear_timer, "Timer Smearing", 45, 12345678, ctx, &bbl_smear_job);
@@ -620,4 +620,4 @@ main (int argc, char *argv[])
}
bbl_ctx_del(ctx);
ctx = NULL;
}
}
+11 -11
View File
@@ -11,7 +11,7 @@
#include "bbl_stream.h"
void
bbl_a10nsp_session_free(bbl_session_s *session)
bbl_a10nsp_session_free(bbl_session_s *session)
{
if(session->a10nsp_session) {
if(session->a10nsp_session->pppoe_aci) {
@@ -28,7 +28,7 @@ bbl_a10nsp_session_free(bbl_session_s *session)
static void
bbl_a10nsp_pppoed_handler(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth)
bbl_ethernet_header_t *eth)
{
bbl_a10nsp_session_t *a10nsp_session = session->a10nsp_session;
bbl_pppoe_discovery_t *pppoed = (bbl_pppoe_discovery_t*)eth->next;
@@ -44,7 +44,7 @@ bbl_a10nsp_pppoed_handler(bbl_interface_s *interface,
}
pppoed->ac_cookie = ac_cookie;
pppoed->ac_cookie_len = sizeof(ac_cookie);
if(pppoed->access_line) {
if(pppoed->access_line->aci) {
if(a10nsp_session->pppoe_aci) {
@@ -152,7 +152,7 @@ bbl_a10nsp_ipcp_handler(bbl_interface_s *interface,
bbl_ipcp_t ipcp_request = {0};
UNUSED(session);
switch(ipcp->code) {
case PPP_CODE_CONF_REQUEST:
if(ipcp->address == A10NSP_IP_REMOTE) {
@@ -233,7 +233,7 @@ bbl_a10nsp_ip6cp_handler(bbl_interface_s *interface,
static void
bbl_a10nsp_pppoes_handler(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth)
bbl_ethernet_header_t *eth)
{
bbl_ctx_s *ctx = interface->ctx;
bbl_pppoe_session_t *pppoes = (bbl_pppoe_session_t*)eth->next;
@@ -254,7 +254,7 @@ bbl_a10nsp_pppoes_handler(bbl_interface_s *interface,
break;
case PROTOCOL_PAP:
bbl_a10nsp_pap_handler(interface, session, eth);
break;
break;
case PROTOCOL_IPCP:
bbl_a10nsp_ipcp_handler(interface, session, eth);
break;
@@ -323,7 +323,7 @@ bbl_a10nsp_pppoes_handler(bbl_interface_s *interface,
/**
* bbl_a10nsp_rx
*
* This function handles all received session
* This function handles all received session
* traffic on a10nsp interfaces.
*
* @param interface Receiving interface.
@@ -331,13 +331,13 @@ bbl_a10nsp_pppoes_handler(bbl_interface_s *interface,
* @param eth Received ethernet packet.
*/
void
bbl_a10nsp_rx(bbl_interface_s *interface,
bbl_session_s *session,
bbl_a10nsp_rx(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth)
{
/* Create A10NSP session if not already present */
if(!session->a10nsp_session) {
LOG(DEBUG, "A10NSP (ID: %u) Session created on interface %s with S-VLAN %d\n",
LOG(DEBUG, "A10NSP (ID: %u) Session created on interface %s with S-VLAN %d\n",
session->session_id, interface->name, eth->vlan_outer);
session->a10nsp_session = calloc(1, sizeof(bbl_a10nsp_session_t));
session->a10nsp_session->session = session;
@@ -363,4 +363,4 @@ bbl_a10nsp_rx(bbl_interface_s *interface,
break;
}
return;
}
}
+4 -4
View File
@@ -29,7 +29,7 @@ typedef struct bbl_a10nsp_session_
char *pppoe_ari;
char *pppoe_aci;
struct {
uint64_t packets_tx;
uint64_t packets_rx;
@@ -41,8 +41,8 @@ void
bbl_a10nsp_session_free(bbl_session_s *session);
void
bbl_a10nsp_rx(bbl_interface_s *interface,
bbl_session_s *session,
bbl_a10nsp_rx(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth);
#endif
#endif
+9 -9
View File
@@ -269,7 +269,7 @@ json_parse_network_interface (bbl_ctx_s *ctx, json_t *network_interface, bbl_net
&network_config->gateway_mac[2],
&network_config->gateway_mac[3],
&network_config->gateway_mac[4],
&network_config->gateway_mac[5]) < 6)
&network_config->gateway_mac[5]) < 6)
{
fprintf(stderr, "JSON config error: Invalid value for network->gateway-mac\n");
return false;
@@ -525,7 +525,7 @@ json_parse_access_interface (bbl_ctx_s *ctx, json_t *access_interface, bbl_acces
access_config->ipv4_enable = false;
}
} else {
/* Disable IPv4 on IPoE if neither DHCP is enabled or
/* Disable IPv4 on IPoE if neither DHCP is enabled or
* a static IPv4 address is configured. */
if (!(access_config->dhcp_enable || access_config->static_ip)) {
access_config->ipv4_enable = false;
@@ -637,7 +637,7 @@ json_parse_a10nsp_interface (bbl_ctx_s *ctx, json_t *a10nsp_interface, bbl_a10ns
&a10nsp_config->mac[2],
&a10nsp_config->mac[3],
&a10nsp_config->mac[4],
&a10nsp_config->mac[5]) < 6)
&a10nsp_config->mac[5]) < 6)
{
fprintf(stderr, "JSON config error: Invalid value for a10nsp->mac\n");
return false;
@@ -1321,7 +1321,7 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) {
return false;
}
}
/* Access Interface Configuration Section */
sub = json_object_get(section, "access");
if (json_is_array(sub)) {
@@ -1517,8 +1517,8 @@ json_parse_config (json_t *root, bbl_ctx_s *ctx) {
* This function populates the BBL context
* from given JSON configuration file returning
* true if successfull or false if failed with
* error message printed to stderr.
*
* error message printed to stderr.
*
* @param ctx JSON filename
* @param ctx global context
*/
@@ -1571,14 +1571,14 @@ json_parse_config_streams (json_t *root, bbl_ctx_s *ctx) {
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
*/
@@ -1659,4 +1659,4 @@ bbl_config_init_defaults (bbl_ctx_s *ctx) {
ctx->config.igmp_group_count = 1;
ctx->config.igmp_zap_wait = true;
ctx->config.session_traffic_autostart = true;
}
}
+2 -2
View File
@@ -76,7 +76,7 @@ typedef struct bbl_access_config_
uint16_t access_third_vlan;
bool qinq; /* use ethertype 0x8818 */
/* Static */
uint32_t static_ip;
uint32_t static_ip_iter;
@@ -160,4 +160,4 @@ bbl_config_streams_load_json(const char *filename, bbl_ctx_s *ctx);
void
bbl_config_init_defaults(bbl_ctx_s *ctx);
#endif
#endif
+1 -1
View File
@@ -373,7 +373,7 @@ bbl_ctrl_session_info(int fd, bbl_ctx_s *ctx, uint32_t session_id, json_t* argum
}
session = bbl_session_get(ctx, session_id);
if(session) {
if(session) {
session_json = bbl_session_json(session);
if(!session_json) {
bbl_ctrl_status(fd, "error", 500, "internal error");
+2 -2
View File
@@ -87,10 +87,10 @@ typedef struct bbl_ctx_
uint8_t access_if_count;
struct bbl_interface_ *access_if[BBL_MAX_INTERFACES];
uint8_t network_if_count;
struct bbl_interface_ *network_if[BBL_MAX_INTERFACES];
uint8_t a10nsp_if_count;
struct bbl_interface_ *a10nsp_if[BBL_MAX_INTERFACES];
} interfaces;
+1 -1
View File
@@ -97,7 +97,7 @@ bbl_dhcp_start(bbl_session_s *session) {
session->dhcp_xid = rand();
session->dhcp_retry = 0;
session->send_requests |= BBL_SEND_DHCP_REQUEST;
LOG(DHCP, "DHCP (ID: %u) Start DHCP\n", session->session_id);
}
}
+2 -2
View File
@@ -87,7 +87,7 @@ bbl_dhcpv6_start(bbl_session_s *session) {
session->dhcpv6_ia_na_iaid = rand();
if(!session->dhcpv6_ia_na_iaid) session->dhcpv6_ia_na_iaid = 1;
}
session->dhcpv6_ia_pd_iaid = rand();
if(session->dhcpv6_ia_pd_iaid == session->dhcpv6_ia_na_iaid) {
session->dhcpv6_ia_pd_iaid = session->dhcpv6_ia_na_iaid + 1;
@@ -183,7 +183,7 @@ bbl_dhcpv6_rx(bbl_ethernet_header_t *eth, bbl_dhcpv6_t *dhcpv6, bbl_session_s *s
bbl_session_clear(ctx, session);
}
return;
}
}
/* Establish DHCPv6 */
if(!session->dhcpv6_established) {
session->dhcpv6_established = true;
+1 -1
View File
@@ -236,7 +236,7 @@ bbl_stats_job (timer_s *timer)
int i;
int pos = 1; /* position */
bool visible = false;
bool visible = false;
access_if = ctx->interfaces.access_if[g_access_if_selected];
network_if = ctx->interfaces.network_if[g_network_if_selected];
+14 -14
View File
@@ -13,15 +13,15 @@
/**
* bbl_interface_lock
*
* @brief This functions locks the interface
* @brief This functions locks the interface
* creating the file "/run/lock/bngblaster_<interface>.lock".
*
*
* @param ctx global context
* @param interface interface
* @return false if failed to lock (e.g. in use)
*/
static bool
bbl_interface_lock(bbl_ctx_s *ctx, char *interface_name)
bbl_interface_lock(bbl_ctx_s *ctx, char *interface_name)
{
FILE *lock_file;
char lock_path[FILE_PATH_LEN];
@@ -158,7 +158,7 @@ bbl_add_interface(bbl_ctx_s *ctx, char *interface_name)
/**
* bbl_interface_present
*
*
* @param ctx global context
* @param interface_name interface name
* @return true if interface is already added
@@ -267,7 +267,7 @@ bbl_add_network_interfaces(bbl_ctx_s *ctx)
memcpy(&network_if->ip6, &network_config->ip6, sizeof(ipv6_prefix));
memcpy(&network_if->gateway6, &network_config->gateway6, sizeof(ipv6_prefix));
memcpy(&network_if->gateway6_solicited_node_multicast, &ipv6_solicited_node_multicast, sizeof(ipv6addr_t));
memcpy(((uint8_t*)&network_if->gateway6_solicited_node_multicast)+13,
memcpy(((uint8_t*)&network_if->gateway6_solicited_node_multicast)+13,
((uint8_t*)&network_if->gateway6.address)+13, 3);
/* Send initial ICMPv6 NS */
@@ -318,7 +318,7 @@ bbl_add_a10nsp_interfaces(bbl_ctx_s *ctx)
}
bbl_send_init_interface(a10nsp_if, BBL_SEND_DEFAULT_SIZE);
a10nsp_config = a10nsp_config->next;
}
return true;
@@ -329,9 +329,9 @@ bbl_add_a10nsp_interfaces(bbl_ctx_s *ctx)
*
* @brief This function will add and initialize
* all interfaces defined in the configuration.
*
*
* @param ctx global context
* @return true if all interfaces are
* @return true if all interfaces are
* added and initialised successfully
*/
bool
@@ -357,9 +357,9 @@ bbl_add_interfaces(bbl_ctx_s *ctx)
* bbl_get_network_interface
*
* @brief This function returns the network interface
* with the given name or the first interface
* if name is NULL.
*
* with the given name or the first interface
* if name is NULL.
*
* @param ctx global context
* @param interface interface name
* @return interface
@@ -374,7 +374,7 @@ bbl_get_network_interface(bbl_ctx_s *ctx, char *interface_name)
return ctx->interfaces.network_if[i];
}
} else {
return ctx->interfaces.network_if[i];
return ctx->interfaces.network_if[i];
}
}
}
@@ -385,8 +385,8 @@ bbl_get_network_interface(bbl_ctx_s *ctx, char *interface_name)
* bbl_get_a10nsp_interface
*
* @brief This function returns the network interface
* with the given name.
*
* with the given name.
*
* @param ctx global context
* @param interface interface name
* @return interface
+2 -2
View File
@@ -74,7 +74,7 @@ typedef struct bbl_interface_
bool icmpv6_nd_resolved;
bool gateway_resolve_wait;
uint8_t *mc_packets;
uint16_t mc_packet_len;
uint64_t mc_packet_seq;
@@ -180,7 +180,7 @@ typedef struct bbl_interface_
uint64_t l2tp_data_tx;
bbl_rate_s rate_l2tp_data_rx;
bbl_rate_s rate_l2tp_data_tx;
uint64_t li_rx;
bbl_rate_s rate_li_rx;
} stats;
+1 -1
View File
@@ -854,7 +854,7 @@ bbl_l2tp_avp_encode_attributes(bbl_l2tp_tunnel_t *l2tp_tunnel, bbl_l2tp_session_
l2tp_session->result_code,
l2tp_session->error_code,
l2tp_session->error_message);
/* RFC3145 PPP Disconnect Cause Code AVP */
/* RFC3145 PPP Disconnect Cause Code AVP */
bbl_l2tp_avp_encode_disconnect_code(&buf, len, l2tp_session);
}
break;
+1 -1
View File
@@ -26,7 +26,7 @@
#define PCAPNG_EPB_FLAGS_INBOUND 0x1
#define PCAPNG_EPB_FLAGS_OUTBOUND 0x2
/* Ethernet (10Mb, 100Mb, 1000Mb, and up);
/* Ethernet (10Mb, 100Mb, 1000Mb, and up);
* the 10MB in the DLT_ name is historical. */
#define DLT_EN10MB 1 /* Ethernet (10Mb) */
#define DLT_NULL 0 /* RAW IP */
+17 -17
View File
@@ -84,10 +84,10 @@ bbl_ipv6_icmpv6_checksum(ipv6addr_t src, ipv6addr_t dst, uint8_t *icmp, uint16_t
* ENCODE
* ------------------------------------------------------------------------*/
static uint16_t
static uint16_t
encode_dhcpv6_access_line(uint8_t *buf, access_line_t *access_line) {
uint16_t len = 0;
uint16_t *option_len;
uint16_t *option_len;
/* DHCPv6 Vendor Option (17) */
*(uint16_t*)buf = htobe16(DHCPV6_OPTION_VENDOR_OPTS);
@@ -272,11 +272,11 @@ encode_dhcpv6(uint8_t *buf, uint16_t *len,
return PROTOCOL_SUCCESS;
}
static uint8_t
static uint8_t
encode_dhcp_access_line(uint8_t *buf, access_line_t *access_line) {
uint8_t len = 0;
uint8_t *option_len;
uint8_t *data_len;
uint8_t *option_len;
uint8_t *data_len;
*buf = DHCP_RELAY_AGENT_VENDOR_SUBOPT;
BUMP_WRITE_BUFFER(buf, &len, sizeof(uint8_t));
@@ -1725,7 +1725,7 @@ encode_cfm(uint8_t *buf, uint16_t *len, bbl_cfm_t *cfm) {
*buf |= 128;
}
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
/* Remember first TLV offset position */
*buf = 70;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
@@ -1765,7 +1765,7 @@ encode_cfm(uint8_t *buf, uint16_t *len, bbl_cfm_t *cfm) {
/* CFM TLVs */
/* Sender ID TLV */
*buf = 1;
*buf = 1;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
*(uint16_t*)buf = htobe16(1);
BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t));
@@ -1773,7 +1773,7 @@ encode_cfm(uint8_t *buf, uint16_t *len, bbl_cfm_t *cfm) {
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
/* Port Status TLV */
*buf = 2;
*buf = 2;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
*(uint16_t*)buf = htobe16(1);
BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t));
@@ -1781,7 +1781,7 @@ encode_cfm(uint8_t *buf, uint16_t *len, bbl_cfm_t *cfm) {
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
/* Interface Status TLV */
*buf = 4;
*buf = 4;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
*(uint16_t*)buf = htobe16(1);
BUMP_WRITE_BUFFER(buf, len, sizeof(uint16_t));
@@ -1789,7 +1789,7 @@ encode_cfm(uint8_t *buf, uint16_t *len, bbl_cfm_t *cfm) {
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
/* End TLV */
*buf = 0;
*buf = 0;
BUMP_WRITE_BUFFER(buf, len, sizeof(uint8_t));
return PROTOCOL_SUCCESS;
@@ -2066,7 +2066,7 @@ decode_dhcpv6_ia_na(uint8_t *buf, uint16_t len, bbl_dhcpv6_t *dhcpv6) {
uint16_t ia_option;
uint16_t ia_option_len;
if(len < 12) {
return DECODE_ERROR;
}
@@ -2108,7 +2108,7 @@ decode_dhcpv6_ia_pd(uint8_t *buf, uint16_t len, bbl_dhcpv6_t *dhcpv6) {
uint16_t ia_option;
uint16_t ia_option_len;
if(len < 12) {
return DECODE_ERROR;
}
@@ -3201,7 +3201,7 @@ static protocol_error_t
decode_pppoe_vendor(uint8_t *buf, uint16_t len,
uint8_t *sp, uint16_t sp_len,
bbl_pppoe_discovery_t *pppoe) {
uint32_t vendor;
uint8_t tlv_type;
uint8_t tlv_length;
@@ -3237,7 +3237,7 @@ decode_pppoe_vendor(uint8_t *buf, uint16_t len,
memcpy(sp, buf, tlv_length);
/* zero terminate string */
sp += tlv_length; *sp = 0; sp++;
} else {
} else {
return DECODE_ERROR;
}
break;
@@ -3247,21 +3247,21 @@ decode_pppoe_vendor(uint8_t *buf, uint16_t len,
memcpy(sp, buf, tlv_length);
/* zero terminate string */
sp += tlv_length; *sp = 0; sp++;
} else {
} else {
return DECODE_ERROR;
}
break;
case ACCESS_LINE_ACT_UP:
if(tlv_length == sizeof(uint32_t)) {
access_line->up = be32toh(*(uint32_t*)buf);
} else {
} else {
return DECODE_ERROR;
}
break;
case ACCESS_LINE_ACT_DOWN:
if(tlv_length == sizeof(uint32_t)) {
access_line->down = be32toh(*(uint32_t*)buf);
} else {
} else {
return DECODE_ERROR;
}
break;
+2 -2
View File
@@ -48,7 +48,7 @@
#define ETH_VLAN_ID_MAX 4095
#define ETH_VLAN_PBIT_MAX 7
#define OUI_LEN 3
#define OUI_LEN 3
#define IPV4_RF 0x8000 /* reserved fragment flag */
#define IPV4_DF 0x4000 /* dont fragment flag */
@@ -498,7 +498,7 @@ typedef struct bbl_pppoe_discovery_ {
uint8_t *service_name;
uint16_t service_name_len;
uint8_t *ac_name;
uint16_t ac_name_len;
uint16_t ac_name_len;
uint8_t *ac_cookie;
uint16_t ac_cookie_len;
uint8_t *host_uniq;
+8 -8
View File
@@ -414,13 +414,13 @@ bbl_rx_established_ipoe(bbl_ethernet_header_t *eth, bbl_interface_s *interface,
bool ipv6 = true;
if(session->access_config->ipv4_enable) {
if(!session->arp_resolved ||
if(!session->arp_resolved ||
(session->access_config->dhcp_enable && session->dhcp_state < BBL_DHCP_BOUND)) {
ipv4 = false;
}
}
if(session->access_config->ipv6_enable) {
if(!session->icmpv6_ra_received ||
if(!session->icmpv6_ra_received ||
(session->access_config->dhcpv6_enable && session->dhcpv6_state < BBL_DHCP_BOUND)) {
ipv6 = false;
}
@@ -461,7 +461,7 @@ bbl_rx_icmpv6(bbl_ethernet_header_t *eth, bbl_ipv6_t *ipv6, bbl_interface_s *int
session->stats.icmpv6_rx++;
if(session->a10nsp_session) {
/* There is currently no IPv6 support
/* There is currently no IPv6 support
* for A10NSP terminated sessions today. */
return;
}
@@ -925,7 +925,7 @@ bbl_rx_established(bbl_ethernet_header_t *eth, bbl_interface_s *interface, bbl_s
timer_add(&ctx->timer_root, &session->timer_session, "Session", ctx->config.pppoe_session_time, 0, session, &bbl_session_timeout);
}
if(session->access_config->ipv4_enable) {
if(session->l2tp == false && !session->a10nsp_session &&
if(session->l2tp == false && !session->a10nsp_session &&
ctx->config.igmp_group && ctx->config.igmp_autostart && ctx->config.igmp_start_delay) {
/* Start IGMP */
timer_add(&ctx->timer_root, &session->timer_igmp, "IGMP", ctx->config.igmp_start_delay, 0, session, &bbl_igmp_initial_join);
@@ -1153,8 +1153,8 @@ bbl_rx_lcp(bbl_ethernet_header_t *eth, bbl_interface_s *interface, bbl_session_s
case PPP_CODE_VENDOR_SPECIFIC:
if(ctx->config.lcp_vendor_ignore) {
return;
}
if(ctx->config.lcp_connection_status_message &&
}
if(ctx->config.lcp_connection_status_message &&
lcp->vendor_kind == 1 && lcp->vendor_value_len > 2) {
/* Skip the 2 byte option header (type, length) */
lcp->vendor_value_len -= 2;
@@ -1620,8 +1620,8 @@ bbl_rx_handler_access(bbl_ethernet_header_t *eth, bbl_interface_s *interface) {
return bbl_rx_handler_access_broadcast(eth, interface);
}
} else if(*eth->dst & 0x01) {
/* Ethernet frames with a value of 1 in the least-significant bit
* of the first octet of the destination MAC address are treated
/* Ethernet frames with a value of 1 in the least-significant bit
* of the first octet of the destination MAC address are treated
* as multicast frames- */
session_id = bbl_rx_session_id_from_vlan(eth, interface);
if(!session_id) {
+25 -25
View File
@@ -44,17 +44,17 @@ bbl_send_is_full(bbl_interface_s *interface)
}
/**
* @brief Receive packet from interface send
* @brief Receive packet from interface send
* buffer and copy to target buffer (buf).
*
*
* @param interface interface
* @param buf target buffer
* @return number of bytes copied
*/
uint16_t
bbl_send_from_buffer(bbl_interface_s *interface, uint8_t *buf)
bbl_send_from_buffer(bbl_interface_s *interface, uint8_t *buf)
{
bbl_send_slot_t *slot;
bbl_send_slot_t *slot;
if(interface->send.read == interface->send.write) {
return 0;
@@ -71,17 +71,17 @@ bbl_send_from_buffer(bbl_interface_s *interface, uint8_t *buf)
}
/**
* @brief Encode packet to interface send
* @brief Encode packet to interface send
* buffer.
*
*
* @param interface interface
* @param eth ethernet structure
* @return bbl_send_result_t
* @return bbl_send_result_t
*/
bbl_send_result_t
bbl_send_to_buffer(bbl_interface_s *interface, bbl_ethernet_header_t *eth)
bbl_send_to_buffer(bbl_interface_s *interface, bbl_ethernet_header_t *eth)
{
bbl_send_slot_t *slot;
bbl_send_slot_t *slot;
if(interface->send.read == interface->send.next) {
return BBL_SEND_FULL;
@@ -100,7 +100,7 @@ bbl_send_to_buffer(bbl_interface_s *interface, bbl_ethernet_header_t *eth)
}
static void
swap_eth_src_dst(bbl_ethernet_header_t *eth)
swap_eth_src_dst(bbl_ethernet_header_t *eth)
{
uint8_t *dst = eth->dst;
eth->dst = eth->src;
@@ -108,7 +108,7 @@ swap_eth_src_dst(bbl_ethernet_header_t *eth)
}
static void
swap_ipv4_src_dst(bbl_ipv4_t *ipv4)
swap_ipv4_src_dst(bbl_ipv4_t *ipv4)
{
uint32_t dst = ipv4->dst;
ipv4->dst = ipv4->src;
@@ -116,9 +116,9 @@ swap_ipv4_src_dst(bbl_ipv4_t *ipv4)
}
static void
update_eth(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth)
update_eth(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth)
{
if(session) {
swap_eth_src_dst(eth);
@@ -136,10 +136,10 @@ update_eth(bbl_interface_s *interface,
}
}
bbl_send_result_t
bbl_send_result_t
bbl_send_arp_reply(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth,
bbl_ethernet_header_t *eth,
bbl_arp_t *arp)
{
update_eth(interface, session, eth);
@@ -151,11 +151,11 @@ bbl_send_arp_reply(bbl_interface_s *interface,
return bbl_send_to_buffer(interface, eth);
}
bbl_send_result_t
bbl_send_result_t
bbl_send_icmpv6_na(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth,
bbl_ipv6_t *ipv6,
bbl_ethernet_header_t *eth,
bbl_ipv6_t *ipv6,
bbl_icmpv6_t *icmpv6)
{
update_eth(interface, session, eth);
@@ -176,11 +176,11 @@ bbl_send_icmpv6_na(bbl_interface_s *interface,
return bbl_send_to_buffer(interface, eth);
}
bbl_send_result_t
bbl_send_result_t
bbl_send_icmp_reply(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth,
bbl_ipv4_t *ipv4,
bbl_ethernet_header_t *eth,
bbl_ipv4_t *ipv4,
bbl_icmp_t *icmp)
{
update_eth(interface, session, eth);
@@ -190,11 +190,11 @@ bbl_send_icmp_reply(bbl_interface_s *interface,
return bbl_send_to_buffer(interface, eth);
}
bbl_send_result_t
bbl_send_result_t
bbl_send_icmpv6_echo_reply(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth,
bbl_ipv6_t *ipv6,
bbl_ethernet_header_t *eth,
bbl_ipv6_t *ipv6,
bbl_icmpv6_t *icmpv6)
{
update_eth(interface, session, eth);
+13 -13
View File
@@ -2,8 +2,8 @@
* BNG Blaster (BBL) - Send Functions
*
* This interface allows to "directly" send
* packets to an interface.
*
* packets to an interface.
*
* Hannes Gredler, July 2020
* Christian Giese, October 2020
*
@@ -42,31 +42,31 @@ bbl_send_from_buffer(bbl_interface_s *interface, uint8_t *buf);
bbl_send_result_t
bbl_send_to_buffer(bbl_interface_s *interface, bbl_ethernet_header_t *eth);
bbl_send_result_t
bbl_send_result_t
bbl_send_arp_reply(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth,
bbl_ethernet_header_t *eth,
bbl_arp_t *arp);
bbl_send_result_t
bbl_send_result_t
bbl_send_icmpv6_na(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth,
bbl_ipv6_t *ipv6,
bbl_ethernet_header_t *eth,
bbl_ipv6_t *ipv6,
bbl_icmpv6_t *icmpv6);
bbl_send_result_t
bbl_send_result_t
bbl_send_icmp_reply(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth,
bbl_ipv4_t *ipv4,
bbl_ethernet_header_t *eth,
bbl_ipv4_t *ipv4,
bbl_icmp_t *icmp);
bbl_send_result_t
bbl_send_result_t
bbl_send_icmpv6_echo_reply(bbl_interface_s *interface,
bbl_session_s *session,
bbl_ethernet_header_t *eth,
bbl_ipv6_t *ipv6,
bbl_ethernet_header_t *eth,
bbl_ipv6_t *ipv6,
bbl_icmpv6_t *icmpv6);
#endif
+3 -3
View File
@@ -164,8 +164,8 @@ bbl_session_update_state(bbl_ctx_s *ctx, bbl_session_s *session, session_state_t
session->dhcpv6_requested = false;
ctx->dhcpv6_requested--;
}
}
}
if(state == BBL_ESTABLISHED) {
/* Increment sessions established and decrement outstanding
* if new state is established. */
@@ -552,7 +552,7 @@ bbl_sessions_init(bbl_ctx_s *ctx)
session->link_local_ipv6_address[9] = 0xff;
session->link_local_ipv6_address[10] = 0xff;
session->link_local_ipv6_address[11] = 0xff;
session->link_local_ipv6_address[12] = 0xff;
session->link_local_ipv6_address[12] = 0xff;
session->link_local_ipv6_address[13] = session->client_mac[3];
session->link_local_ipv6_address[14] = session->client_mac[4];
session->link_local_ipv6_address[15] = session->client_mac[5];
+5 -5
View File
@@ -98,7 +98,7 @@ typedef struct bbl_session_
bool l2tp;
bbl_l2tp_session_t *l2tp_session;
/* Set to true if session is connected to
/* Set to true if session is connected to
* BNG Blaster A10NSP Interface */
bbl_a10nsp_session_t *a10nsp_session;
@@ -117,7 +117,7 @@ typedef struct bbl_session_
uint32_t dsl_type;
void *access_line_profile;
/* Ethernet */
uint8_t server_mac[ETH_ADDR_LEN];
uint8_t client_mac[ETH_ADDR_LEN];
@@ -390,13 +390,13 @@ typedef struct bbl_session_
} bbl_session_s;
void
void
bbl_session_tx_qnode_insert(struct bbl_session_ *session);
void
void
bbl_session_tx_qnode_remove(struct bbl_session_ *session);
void
void
bbl_session_network_tx_qnode_insert(struct bbl_session_ *session);
void
+3 -3
View File
@@ -96,7 +96,7 @@ bbl_session_traffic_ipv6pd(timer_s *timer)
}
static bool
bbl_session_traffic_add_ipv4_l2tp(bbl_ctx_s *ctx, bbl_session_s *session,
bbl_session_traffic_add_ipv4_l2tp(bbl_ctx_s *ctx, bbl_session_s *session,
struct bbl_interface_ *network_if)
{
bbl_ethernet_header_t eth = {0};
@@ -170,7 +170,7 @@ bbl_session_traffic_add_ipv4_l2tp(bbl_ctx_s *ctx, bbl_session_s *session,
}
static bool
bbl_session_traffic_add_ipv4_a10nsp(bbl_ctx_s *ctx, bbl_session_s *session,
bbl_session_traffic_add_ipv4_a10nsp(bbl_ctx_s *ctx, bbl_session_s *session,
struct bbl_interface_ *a10nsp_if)
{
bbl_ethernet_header_t eth = {0};
@@ -494,7 +494,7 @@ bbl_session_traffic_start_ipv4(bbl_ctx_s *ctx, bbl_session_s *session) {
uint64_t tx_interval;
if(ctx->config.session_traffic_ipv4_pps && session->ip_address &&
if(ctx->config.session_traffic_ipv4_pps && session->ip_address &&
(ctx->interfaces.network_if_count || session->a10nsp_session)) {
/* Start IPv4 Session Traffic */
if(bbl_session_traffic_add_ipv4(ctx, session)) {
+28 -28
View File
@@ -222,7 +222,7 @@ bbl_stats_generate (bbl_ctx_s *ctx, bbl_stats_t * stats) {
stats->min_stream_rx_first_seq = stream->rx_first_seq;
}
if(stream->rx_first_seq > stats->max_stream_rx_first_seq) stats->max_stream_rx_first_seq = stream->rx_first_seq;
if(stats->min_stream_delay_ns) {
if(stream->min_delay_ns < stats->min_stream_delay_ns) stats->min_stream_delay_ns = stream->min_delay_ns;
} else {
@@ -277,25 +277,25 @@ bbl_stats_stdout (bbl_ctx_s *ctx, bbl_stats_t * stats) {
printf(" TX: %10lu packets\n", interface->stats.packets_tx);
printf(" RX: %10lu packets\n", interface->stats.packets_rx);
if(ctx->stats.session_traffic_flows) {
printf(" TX Session: %10lu packets\n",
printf(" TX Session: %10lu packets\n",
interface->stats.session_ipv4_tx);
printf(" RX Session: %10lu packets (%lu loss)\n",
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",
printf(" TX Session IPv6: %10lu packets\n",
interface->stats.session_ipv6_tx);
printf(" RX Session IPv6: %10lu packets (%lu loss)\n",
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",
printf(" TX Session IPv6PD: %10lu packets\n",
interface->stats.session_ipv6pd_tx);
printf(" RX Session IPv6PD: %10lu packets (%lu loss)\n",
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",
printf(" TX Multicast: %10lu packets\n",
interface->stats.mc_tx);
printf(" RX Drop Unknown: %10lu packets\n",
printf(" RX Drop Unknown: %10lu packets\n",
interface->stats.packets_rx_drop_unknown);
printf(" TX Encode Error: %10lu\n", interface->stats.encode_errors);
printf(" RX Decode Error: %10lu packets\n",
printf(" RX Decode Error: %10lu packets\n",
interface->stats.packets_rx_drop_decode_error);
printf(" TX Send Failed: %10lu\n", interface->stats.sendto_failed);
printf(" TX No Buffer: %10lu\n", interface->stats.no_tx_buffer);
@@ -368,17 +368,17 @@ bbl_stats_stdout (bbl_ctx_s *ctx, bbl_stats_t * stats) {
printf(" TX: %10lu packets\n", interface->stats.packets_tx);
printf(" RX: %10lu packets\n", interface->stats.packets_rx);
if(ctx->stats.session_traffic_flows) {
printf(" TX Session: %10lu packets\n",
printf(" TX Session: %10lu packets\n",
interface->stats.session_ipv4_tx);
printf(" RX Session: %10lu packets (%lu loss)\n",
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",
printf(" TX Session IPv6: %10lu packets\n",
interface->stats.session_ipv6_tx);
printf(" RX Session IPv6: %10lu packets (%lu loss)\n",
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",
printf(" TX Session IPv6PD: %10lu packets\n",
interface->stats.session_ipv6pd_tx);
printf(" RX Session IPv6PD: %10lu packets (%lu loss)\n",
printf(" RX Session IPv6PD: %10lu packets (%lu loss)\n",
interface->stats.session_ipv6pd_rx, interface->stats.session_ipv6pd_loss);
}
@@ -398,7 +398,7 @@ bbl_stats_stdout (bbl_ctx_s *ctx, bbl_stats_t * stats) {
printf(" IPv4 PPS: %8u\n", ctx->config.session_traffic_ipv4_pps);
printf(" IPv6 PPS: %8u\n", ctx->config.session_traffic_ipv6_pps);
printf(" IPv6PD PPS: %8u\n", ctx->config.session_traffic_ipv6pd_pps);
printf(" Verified Traffic Flows: %u/%u\n",
printf(" Verified Traffic Flows: %u/%u\n",
ctx->stats.session_traffic_flows_verified, ctx->stats.session_traffic_flows);
printf(" Access IPv4: %8u\n", stats->sessions_access_ipv4_rx);
printf(" Access IPv6: %8u\n", stats->sessions_access_ipv6_rx);
@@ -407,37 +407,37 @@ bbl_stats_stdout (bbl_ctx_s *ctx, bbl_stats_t * stats) {
printf(" Network IPv6: %8u\n", stats->sessions_network_ipv6_rx);
printf(" Network IPv6PD: %8u\n", stats->sessions_network_ipv6pd_rx);
printf(" First Sequence Number Received:\n");
printf(" Access IPv4 MIN: %8lu (%6.3fs) MAX: %8lu (%6.3fs)\n",
printf(" Access IPv4 MIN: %8lu (%6.3fs) MAX: %8lu (%6.3fs)\n",
stats->min_access_ipv4_rx_first_seq, stats->min_access_ipv4_rx_seconds,
stats->max_access_ipv4_rx_first_seq, stats->max_access_ipv4_rx_seconds);
printf(" Access IPv6 MIN: %8lu (%6.3fs) MAX: %8lu (%6.3fs)\n",
printf(" Access IPv6 MIN: %8lu (%6.3fs) MAX: %8lu (%6.3fs)\n",
stats->min_access_ipv6_rx_first_seq, stats->min_access_ipv6_rx_seconds,
stats->max_access_ipv6_rx_first_seq, stats->max_access_ipv6_rx_seconds);
printf(" Access IPv6PD MIN: %8lu (%6.3fs) MAX: %8lu (%6.3fs)\n",
stats->min_access_ipv6pd_rx_first_seq, stats->min_access_ipv6pd_rx_seconds,
printf(" Access IPv6PD MIN: %8lu (%6.3fs) MAX: %8lu (%6.3fs)\n",
stats->min_access_ipv6pd_rx_first_seq, stats->min_access_ipv6pd_rx_seconds,
stats->max_access_ipv6pd_rx_first_seq, stats->max_access_ipv6pd_rx_seconds);
printf(" Network IPv4 MIN: %8lu (%6.3fs) MAX: %8lu (%6.3fs)\n",
printf(" Network IPv4 MIN: %8lu (%6.3fs) MAX: %8lu (%6.3fs)\n",
stats->min_network_ipv4_rx_first_seq, stats->min_network_ipv4_rx_seconds,
stats->max_network_ipv4_rx_first_seq, stats->max_network_ipv4_rx_seconds);
printf(" Network IPv6 MIN: %8lu (%6.3fs) MAX: %8lu (%6.3fs)\n",
printf(" Network IPv6 MIN: %8lu (%6.3fs) MAX: %8lu (%6.3fs)\n",
stats->min_network_ipv6_rx_first_seq, stats->min_network_ipv6_rx_seconds,
stats->max_network_ipv6_rx_first_seq, stats->max_network_ipv6_rx_seconds);
printf(" Network IPv6PD MIN: %8lu (%6.3fs) MAX: %8lu (%6.3fs)\n",
printf(" Network IPv6PD MIN: %8lu (%6.3fs) MAX: %8lu (%6.3fs)\n",
stats->min_network_ipv6pd_rx_first_seq, stats->min_network_ipv6pd_rx_seconds,
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",
printf(" Verified Traffic Flows: %u/%u\n",
ctx->stats.stream_traffic_flows_verified, ctx->stats.stream_traffic_flows);
printf(" First Sequence Number Received MIN: %8lu MAX: %8lu\n",
printf(" First Sequence Number Received MIN: %8lu MAX: %8lu\n",
stats->min_stream_rx_first_seq,
stats->max_stream_rx_first_seq);
printf(" Flow Receive Packet Loss MIN: %8lu MAX: %8lu\n",
printf(" Flow Receive Packet Loss MIN: %8lu MAX: %8lu\n",
stats->min_stream_loss,
stats->max_stream_loss);
printf(" Flow Receive Delay (nsec) MIN: %8lu MAX: %8lu\n",
printf(" Flow Receive Delay (nsec) MIN: %8lu MAX: %8lu\n",
stats->min_stream_delay_ns,
stats->max_stream_delay_ns);
}
+24 -24
View File
@@ -20,7 +20,7 @@ extern bool g_traffic;
static bool
bbl_stream_can_send(bbl_stream *stream) {
bbl_session_s *session = stream->session;
if(g_init_phase) {
return false;
}
@@ -601,9 +601,9 @@ bbl_stream_build_l2tp_packet(bbl_stream *stream) {
bbl_l2tp_session_t *l2tp_session = stream->session->l2tp_session;
bbl_l2tp_tunnel_t *l2tp_tunnel = l2tp_session->tunnel;
struct bbl_interface_ *interface = l2tp_tunnel->interface;
uint16_t buf_len;
bbl_ethernet_header_t eth = {0};
@@ -741,10 +741,10 @@ bbl_stream_tx_thread (void *thread_data) {
/**
* This function synchronizes the data
* between TX stream threads and main
* between TX stream threads and main
* thread.
*
* @param thread
*
* @param thread
*/
void
bbl_stream_tx_thread_sync(bbl_stream_thread *thread) {
@@ -756,7 +756,7 @@ bbl_stream_tx_thread_sync(bbl_stream_thread *thread) {
uint64_t bytes_tx;
uint64_t delta_packets;
uint64_t delta_bytes;
pthread_mutex_lock(&stream->thread.mutex);
packets_tx = thread->packets_tx;
@@ -766,7 +766,7 @@ bbl_stream_tx_thread_sync(bbl_stream_thread *thread) {
interface->stats.packets_tx += delta_packets;
interface->stats.bytes_tx += delta_bytes;
thread->packets_tx_last_sync = packets_tx;
thread->bytes_tx_last_sync = bytes_tx;
@@ -826,11 +826,11 @@ bbl_stream_tx_thread_sync(bbl_stream_thread *thread) {
} else {
stream->thread.can_send = false;
stream->send_window_packets = 0;
}
}
}
pthread_mutex_unlock(&stream->thread.mutex);
stream = stream->thread.next;
}
}
}
void
@@ -893,9 +893,9 @@ bbl_stream_thread_create(uint8_t thread_group, bbl_stream *stream) {
/**
* This function will add a stream to an existing
* thread or create a new thread based on thread
* group.
*
* thread or create a new thread based on thread
* group.
*
* @param ctx global context
* @param thread_group thread group
* @param stream traffic stream
@@ -909,8 +909,8 @@ bbl_stream_add_to_thread(bbl_ctx_s *ctx, uint8_t thread_group, bbl_stream *strea
if(ctx->stream_thread) {
thread = ctx->stream_thread;
while(true) {
/* The thread group zero means that this stream
* requests a dedicated thread. The scope of thread
/* The thread group zero means that this stream
* requests a dedicated thread. The scope of thread
* groups is per interface. */
if(thread_group && thread->thread_group == thread_group &&
thread->interface == stream->interface) {
@@ -956,13 +956,13 @@ bbl_stream_add_to_thread(bbl_ctx_s *ctx, uint8_t thread_group, bbl_stream *strea
/**
* This function starts all stream threads.
*
*
* @param ctx global context
* @return true if success and false if failed
*/
bool
bbl_stream_start_threads(bbl_ctx_s *ctx) {
bbl_stream_thread *thread = ctx->stream_thread;
while(thread) {
@@ -981,12 +981,12 @@ bbl_stream_start_threads(bbl_ctx_s *ctx) {
/**
* This function stops all stream threads.
*
*
* @param ctx global context
*/
void
bbl_stream_stop_threads(bbl_ctx_s *ctx) {
bbl_stream_thread *thread = ctx->stream_thread;
while(thread) {
if(thread->active) {
@@ -1161,7 +1161,7 @@ bbl_stream_add(bbl_ctx_s *ctx, bbl_access_config_s *access_config, bbl_session_s
bbl_stream_config *config;
bbl_stream *stream;
bbl_stream *session_stream;
bbl_stream *session_stream;
bbl_stream_thread *thread;
dict_insert_result result;
@@ -1232,7 +1232,7 @@ bbl_stream_add(bbl_ctx_s *ctx, bbl_access_config_s *access_config, bbl_session_s
LOG(ERROR, "Failed to add stream %s to thread\n", config->name);
free(stream);
return false;
}
}
timer_add_periodic(&thread->timer_root, &stream->timer, config->name, timer_sec, timer_nsec, stream, &bbl_stream_tx_job_threaded);
timer_add_periodic(&thread->timer_root, &stream->timer_rate, "Threaded Rate Computation", 1, 0, stream, &bbl_stream_rate_job_threaded);
} else {
@@ -1273,7 +1273,7 @@ bbl_stream_add(bbl_ctx_s *ctx, bbl_access_config_s *access_config, bbl_session_s
LOG(ERROR, "Failed to add stream %s to thread\n", config->name);
free(stream);
return false;
}
}
timer_add_periodic(&thread->timer_root, &stream->timer, config->name, timer_sec, timer_nsec, stream, &bbl_stream_tx_job_threaded);
timer_add_periodic(&thread->timer_root, &stream->timer_rate, "Threaded Rate Computation", 1, 0, stream, &bbl_stream_rate_job_threaded);
} else {
@@ -1337,7 +1337,7 @@ bbl_stream_raw_add(bbl_ctx_s *ctx) {
LOG(ERROR, "Failed to add stream %s to thread\n", config->name);
free(stream);
return false;
}
}
timer_add_periodic(&thread->timer_root, &stream->timer, config->name, timer_sec, timer_nsec, stream, &bbl_stream_tx_job_threaded);
timer_add_periodic(&thread->timer_root, &stream->timer_rate, "Threaded Rate Computation", 1, 0, stream, &bbl_stream_rate_job_threaded);
} else {
@@ -1355,7 +1355,7 @@ bbl_stream_raw_add(bbl_ctx_s *ctx) {
}
json_t *
bbl_stream_json(bbl_stream *stream)
bbl_stream_json(bbl_stream *stream)
{
json_t *root = NULL;
+5 -5
View File
@@ -93,7 +93,7 @@ typedef struct bbl_stream_
/* Attributes used for threaded streams only! */
struct {
bbl_stream_thread *thread;
bbl_stream *next; /* Next stream in same thread */
bbl_stream *next; /* Next stream in same thread */
pthread_mutex_t mutex;
bool can_send;
} thread;
@@ -104,8 +104,8 @@ typedef struct bbl_stream_
typedef struct bbl_stream_thread_
{
/* The thread-group allows to assign
* multiple streams to one thread. The
* group zero has the special meaning of
* multiple streams to one thread. The
* group zero has the special meaning of
* one thread per stream. */
uint8_t thread_group;
pthread_t thread_id;
@@ -115,9 +115,9 @@ typedef struct bbl_stream_thread_
bool active;
/* Root for thread local timers */
struct timer_root_ timer_root;
struct timer_root_ timer_root;
/* Timer for synchronice job of thread
/* Timer for synchronice job of thread
* counters with main counters. */
struct timer_ *sync_timer;
+4 -4
View File
@@ -237,7 +237,7 @@ timer_smear_bucket (timer_root_s *root, time_t sec, long nsec)
step.tv_nsec = step_nsec - (step.tv_sec * 1e9);
LOG(TIMER_DETAIL, "Smear %u timers in bucket %lu.%06lus\n", timer_bucket->timers, sec, nsec);
LOG(TIMER_DETAIL, "Now %lu.%06lus, last expire %lu.%06lus, step %lu.%06lus\n",
LOG(TIMER_DETAIL, "Now %lu.%06lus, last expire %lu.%06lus, step %lu.%06lus\n",
now.tv_sec, now.tv_nsec / 1000,
last_timer->expire.tv_sec, last_timer->expire.tv_nsec / 1000,
step.tv_sec, step.tv_nsec / 1000);
@@ -248,7 +248,7 @@ timer_smear_bucket (timer_root_s *root, time_t sec, long nsec)
CIRCLEQ_FOREACH(timer, &timer_bucket->timer_qhead, timer_qnode) {
timespec_add(&timer->expire, &now, &step);
now = timer->expire;
LOG(TIMER_DETAIL, " Smear %s -> expire %lu.%06lus\n", timer->name,
LOG(TIMER_DETAIL, " Smear %s -> expire %lu.%06lus\n", timer->name,
timer->expire.tv_sec, timer->expire.tv_nsec / 1000);
}
return;
@@ -295,7 +295,7 @@ timer_smear_all_buckets (timer_root_s *root)
CIRCLEQ_FOREACH(timer, &timer_bucket->timer_qhead, timer_qnode) {
timespec_add(&timer->expire, &now, &step);
now = timer->expire;
LOG(TIMER_DETAIL, " Smear %s -> expire %lu.%06lus\n", timer->name,
LOG(TIMER_DETAIL, " Smear %s -> expire %lu.%06lus\n", timer->name,
last_timer->expire.tv_sec, last_timer->expire.tv_nsec / 1000);
}
return;
@@ -514,7 +514,7 @@ timespec_compare (struct timespec *ts1, struct timespec *ts2)
/**
* Process the timer queue.
*
*
* @param root timer root
*/
void
+1 -1
View File
@@ -590,7 +590,7 @@ bbl_dhcpv6_timeout (timer_s *timer)
interface = session->interface;
ctx = interface->ctx;
if(!(session->dhcpv6_state == BBL_DHCP_BOUND ||
if(!(session->dhcpv6_state == BBL_DHCP_BOUND ||
session->dhcpv6_state == BBL_DHCP_INIT)) {
interface->stats.dhcpv6_timeout++;
if(session->dhcpv6_retry < ctx->config.dhcpv6_retry) {
+10 -10
View File
@@ -24,7 +24,7 @@ val2key (struct keyval_ *keyval, uint val)
return "Unknown";
}
/**
/**
* format_mac_address
*
* Format an MAC address as string in one of 16 static buffers.
@@ -44,7 +44,7 @@ format_mac_address (uint8_t *mac)
return ret;
}
/**
/**
* format_ipv4_address
*
* Format an IPv4 address as string in one of 32 static buffers.
@@ -64,7 +64,7 @@ format_ipv4_address (uint32_t *addr4)
return ret;
}
/**
/**
* format_ipv6_address
*
* Format an IPv6 address as string in one of 16 static buffers.
@@ -84,7 +84,7 @@ format_ipv6_address (ipv6addr_t *addr6)
return ret;
}
/**
/**
* format_ipv6_prefix
*
* Format an IPv6 prefix as string in one of 16 static buffers.
@@ -105,9 +105,9 @@ format_ipv6_prefix (ipv6_prefix *addr6)
return ret;
}
/**
/**
* replace_substring
*
*
* Replace subscrtring in one of 4 static buffers.
*
* @param source source string
@@ -131,7 +131,7 @@ replace_substring (const char* source,
size_t result_len = 0;
idx = (idx+1) & 3;
size_t new_len = strlen(new);
size_t old_len = strlen(old);
@@ -154,7 +154,7 @@ replace_substring (const char* source,
} else {
c = strlen(cur);
result_len += c;
if(result_len < STRLEN_MAX) {
if(result_len < STRLEN_MAX) {
memcpy(result_pos, cur, c);
result_pos += c;
}
@@ -165,7 +165,7 @@ replace_substring (const char* source,
return result;
}
/**
/**
* ipv4_multicast_mac
*
* @param ipv4 IPv4 multicast address
@@ -180,7 +180,7 @@ ipv4_multicast_mac(const uint32_t ipv4, uint8_t* mac) {
mac[3] &= 0x7f;
}
/**
/**
* ipv6_multicast_mac
*
* @param ipv6 IPv6 multicast address
+5 -5
View File
@@ -72,12 +72,12 @@ static void
test_replace_substring(void **unused) {
(void) unused;
assert_string_equal(replace_substring("1234{i}90", "{i}", "5678"), "1234567890");
assert_string_equal(replace_substring("{i1}{i2}{i2}", "{i2}", "2"), "{i1}22");
assert_string_equal(replace_substring("1234{long-variable-name}567890", "{long-variable-name}", ""), "1234567890");
assert_string_equal(replace_substring("1234{i}90", "{i}", "5678"), "1234567890");
assert_string_equal(replace_substring("{i1}{i2}{i2}", "{i2}", "2"), "{i1}22");
assert_string_equal(replace_substring("1234{long-variable-name}567890", "{long-variable-name}", ""), "1234567890");
}
static void
static void
test_ipv4_multicast_mac(void **unused) {
(void) unused;
@@ -91,7 +91,7 @@ test_ipv4_multicast_mac(void **unused) {
assert_memory_equal(mac_expected, mac, ETH_ADDR_LEN);
}
static void
static void
test_ipv6_multicast_mac(void **unused) {
(void) unused;