mirror of
https://github.com/rtbrick/bngblaster.git
synced 2024-05-06 15:54:57 +00:00
@@ -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. ...
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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. It’s 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.
|
||||
|
||||

|
||||
@@ -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.
|
||||
|
||||

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