Repository navigation
Conversation
+ increased troughput + increased instructions per cycle + reduced cache misses + reduced stream memory consumtion
+ upgrade to 25.11.3 + performance optimisations
Introduces a new PPPoL2TP access type that lets BNG Blaster act as an L2TPv2 LAC, tunneling PPPoE/PPP client sessions to an LNS: L2TP client configuration and tunnel/session lifecycle, PPP session bring-up over L2TP (including LCP/IPCP/IPv6CP and DHCPv6), upstream/downstream data forwarding through the tunnel, and session-traffic streams for PPPoL2TP sessions. Also adds LNS-side LCP server handling and related stats, docs, and config schema updates. Special thanks to Oliver Matz, who is the original author of this feature. Original-Author: Oliver Matz Co-Authored-By: Olivier Matz <olivier.matz@6wind.com>
Addresses the remaining code-quality findings from review of the LAC feature: factor tunnel-level config (receive-window, max-retry, congestion-mode, data-*, control-tos, hello-interval, lcp-padding, secret) into a shared bbl_l2tp_tunnel_config_s embedded in both the LNS and LAC config structs, with a config pointer on the tunnel object so state-machine code no longer branches on is_lac to read them. Also: - factor the repeated JSON parsing of those fields for l2tp-server and l2tp-client into one helper - factor the repeated MD5 challenge/response digest computation into bbl_l2tp_challenge_digest() - collapse the LAC tunnel-selection loop from three full passes to two - rename bbl_l2tp_session_s.pppoe_session to session, since it holds the LAC's own PPP session (not a PPPoE session) in LAC mode - account PPPoL2TP received bytes using the PPP protocol field instead of the (absent) ethernet header length - add a comment to the LCP CONF_ACK branch mirroring its sibling No behavior change intended beyond the accounting byte count fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The l2tp-client-group-id row added while resolving the LAC merge was 1-2 characters narrower than the table's other rows. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- BNG Blaster BGP against GoBGP: unicast, connection collision, MD5, TCP-AO and EVPN - BNG Blaster LAC against BNG Blaster LNS - all examples of the quickstart guide - GitHub workflow for PRs to main and nightly runs - ignore Python cache files Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Follow RFC 2328 for broadcast interfaces: stay in Waiting until the wait timer expires or BackupSeen, trigger NeighborChange on 2-Way transitions and run AdjOK? after each election. Fix the DBD duplicate check and do not send opaque LSAs to neighbors without O-bit. Add IS-IS and OSPFv2 integration tests against FRR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Test OSPFv2 and OSPFv3 adjacency, DR/BDR election (including an existing DR), database synchronization and OSPFv2 authentication against BIRD 2. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FRR daemons exit on start if the user is not member of the frrvty group, which root is not with the packaged FRR on CI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mgmtd binds its frontend and backend sockets in /var/run/frr regardless of --vty_socket and does not remove them on exit, so stale sockets from the system FRR or previous tests made it fail to start. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
FRR daemons drop CAP_DAC_OVERRIDE, so they can't access the test directory if it is below a 0750 home directory (e.g. /home/runner on CI), and mgmtd exits as it can't create its pid file. Logs and config are still kept in the test directory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The adjacency can reach Full before the next hello from the neighbor triggers the NeighborChange that settles the DR/BDR roles. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Encode the 32-bit flow-id at offset 24 followed by 32 reserved bits instead of reserved bits followed by the flow-id. This matches the former 64-bit little-endian flow-id, so streams keep working between old and new BNG Blaster versions and existing decoders. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The StopCCN sent in reply to a received StopCCN and the StopCCN sent by the LAC after the last session was closed did not set a result code, which resulted in the reserved result code 0 on the wire. Send result code 1 (general request to clear control connection) instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lspgen moved from /usr/sbin to /usr/bin together with bngblaster and bngblaster-cli, but the postinst/postrm scripts only handled the latter two, breaking scripts that call /usr/sbin/lspgen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The parser only accepts DRAFT-LIHAWI-00 and DRAFT-LIHAWI-04, not the documented short values 00 and 04. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The CHAP algorithm byte was written without moving the write buffer, so the following option overwrote it and the LCP length exceeded the packet, causing the peer to drop LCP Conf-Requests proposing CHAP. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add l2tp-server option lcp-conf-request (default true) to control if the LNS sends its own LCP Conf-Request after receiving a Conf-Request from the client, which is required for LACs without proxy LCP. The LNS still proposes PAP, but now switches to CHAP if the client responds with a Conf-Nak for CHAP (MD5) and sends the CHAP challenge once LCP is opened. Before, CHAP clients never completed LCP. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bbl_txq_s contains cache line aligned members to prevent false sharing between producer and consumer thread, but was allocated with calloc, which only guarantees 16 byte alignment. Add bbl_txq_alloc using aligned_alloc and check for allocation failures. Add missing NULL check for aligned stream allocation. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The stream attribute Gbps-upstream was parsed but missing in the config schema validation, which rejected it as invalid attribute. Add missing stream count to the JSON schema and document the K/M/G prefixes for bps-upstream. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reserve TX ring slots for the whole burst at once and publish them with a single producer update per round instead of per packet. Submitting per packet lets NAPI (running on another core) consume the ring in tiny chunks and bounces the producer cache line for every packet, limiting TX throughput. The burst is capped at the number of free TX frames, so the reservation can not fail since the TX ring has as many slots as there are TX frames. Unused reserved slots are released again at the end of the round. no_buffer is now counted once per round limited by free TX frames.
bbl_compute_avg_rate() assumed exactly one sample per second. If a rate job ran late, the rate was too high. During warm-up, and for the final partial sample in bbl_stream_final(), it was too low. Pass the timestamp and store the elapsed time for each sample. The average is now the sum of the counter deltas divided by the elapsed time. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Full stream groups were never removed from the group list, so every new group required walking all full groups. With 10M streams this took most of the startup time (31s for 1000 sessions with 10k flows each, 80s for 10M raw streams). Remove groups from the list once full, so the list holds at most one group per PPS. Stream setup now takes about 4s for both. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The new IO mode loopback connects two links of the same instance back to back via in-memory rings, without any kernel interface, driver or NIC in between. This allows to measure the IO performance of the BNG Blaster itself and runs without special privileges. Each TX IO handle owns a lock-free single-producer/single-consumer ring to the peer link, read by exactly one RX IO handle (round-robin if the peer has fewer RX threads). Indices are published once per burst and the slots are backed by pre-faulted huge pages. The peer is configured per link with loopback-peer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
bgp_rib_format_as_path() added the snprintf return value to the buffer index without checking it (CodeQL). This could not overflow as the AS_PATH is bounded by the maximum message size, but relied on checks done in bgp_rib_attr_build(). Check the snprintf return value, keep room for the closing bracket and NUL, close the bracket if truncated and check the segment length to prevent reading beyond the AS_PATH. Replace constant numbers in bgp_rib.c with defines. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
decode_dhcp() read a length byte for the END option before handling it, so a DHCP message with non-zero bytes after END was rejected as a decode error whenever the byte following END exceeded the remaining length. RFC 2132 section 3.2 defines END as a single octet that marks the end of valid information, so stop parsing at END. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Build the test packet with ether_header, iphdr, udphdr and dhcp_header instead of raw buffer offsets and use the existing defines for header lengths, ethertype and BOOTREPLY. Add missing newline at end of file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stream packets received on a LAG member with RX threads enabled were dropped without being counted if the frame was larger than 4074 bytes, so the stream was reported as never received even though the frames arrived on the interface. This affects, for example, downstream jumbo streams to access sessions on a LAG, which can be configured since jumbo-frames support was added (#385). bbl_rx_thread() looked up the network and access interfaces on the receiving member, but these are bound to the LAG interface. The lookup failed, so every stream packet was redirected to the main thread through the TXQ, whose slots hold at most BBL_TXQ_BUFFER_LEN (4074) bytes; larger frames were rejected by redirect() without a counter. Resolve a LAG member to its LAG interface, as bbl_rx_handler() already does on the main thread. Stream packets on LAG members are then handled in the RX threads instead of all going through the main thread. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RX threads redirect all packets not handled in the thread to the main thread via the TXQ. Packets longer than BBL_TXQ_BUFFER_LEN (4074 bytes) were dropped without being counted, and so were packets dropped because the TXQ was full, except for packet_mmap, which waits for the main thread instead. Count packets too long to redirect as RX to-long and packets dropped due to a full TXQ as RX dropped, and add both to the interface stats output (rx-to-long, rx-dropped). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The rx-polled counter of the interface stats JSON reported the RX bytes instead of the polled counter. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This merges the current
devbranch intomain(56 commits, 180 files changed). The main additions are:PPPoL2TPaccess type, so BNG Blaster can act as an L2TPv2 LAC.A full changelog is in the beta document.
New Features
PPPoL2TP, configured in the newl2tp-clientsection and assigned withl2tp-client-group-id. It supports LCP, IPCP, IPv6CP and DHCPv6 over L2TP, and session-traffic streams. Original author: Oliver Matz.lcp-keepalive-interval,lcp-keepalive-retry).lcp-conf-requestoption, needed for LACs without proxy LCP.hmac-sha-1-96,hmac-sha-256-128,aes-128-cmac-96).learn-routesoption.bgp-routes,bgp-routes-statsandbgp-evpn-routes.bgp-sessionsoutput.vpws-*options andrx-control-word.-DBNGBLASTER_AF_XDP=on.loopback-peer. It measures BNG Blaster's own IO performance and needs no special privileges.Performance
Fixes
stream-summaryPrometheus export and stream prefetch.Gbps-upstreamandcountare now in the config schema.session-counters.Interface stats: rx-polled in the JSON stats reported the RX byte count instead of the polled counter.
Upgrade Notes
bngblaster,bngblaster-cliandlspgenare now installed to/usr/bin. The deb post-install script creates compatibility symlinks in/usr/sbin.mlockallis now used only with DPDK and AF_XDP.typeandsub-type.Testing
New integration tests run over veth pairs on every PR to
mainand nightly:🤖 Generated with Claude Code