bgpd: Add support for BGP-LS (RFC 9552) - #20470
Merged
Merged
Conversation
cscarpitta
force-pushed
the
feature/bgp_linkstate
branch
11 times, most recently
from
January 23, 2026 11:03
b9e19ee to
9cb411f
Compare
cscarpitta
force-pushed
the
feature/bgp_linkstate
branch
from
January 23, 2026 23:26
9cb411f to
5eced33
Compare
cscarpitta
force-pushed
the
feature/bgp_linkstate
branch
7 times, most recently
from
January 25, 2026 10:05
0a79731 to
6426098
Compare
Contributor
Author
|
ci:rerun unrelated failure |
cscarpitta
marked this pull request as ready for review
January 25, 2026 14:58
Greptile OverviewGreptile SummaryThis PR implements BGP Link-State (BGP-LS) support per RFC 9552, enabling FRR to distribute link-state and traffic engineering information via BGP. The implementation adds ~8,500 lines across 64 files, introducing new AFI/SAFI (16388/71), NLRI encoding/decoding, TED integration, and comprehensive VTY commands. Key Changes
Issues Found
Confidence Score: 3/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant IGP as IGP (ISIS/OSPF)
participant Zebra as Zebra
participant BGP_LS as BGP-LS Module
participant BGP_Core as BGP Core
participant Peer as BGP Peer
Note over IGP,Peer: BGP-LS Route Origination Flow
IGP->>Zebra: Link-State Update (LSP/LSA)
Zebra->>Zebra: Update TED
Zebra->>BGP_LS: LS_MSG (vertex/edge/subnet)
BGP_LS->>BGP_LS: Process LS message
BGP_LS->>BGP_LS: Create BGP-LS NLRI
BGP_LS->>BGP_LS: bgp_ls_nlri_intern()
BGP_LS->>BGP_Core: bgp_ls_update()
BGP_Core->>BGP_Core: Create synthetic prefix (AF_UNSPEC)
BGP_Core->>BGP_Core: Store ls_nlri in path_info->extra
BGP_Core->>BGP_Core: bgp_process()
BGP_Core->>Peer: UPDATE (MP_REACH_NLRI)
Note over IGP,Peer: BGP-LS Route Reception Flow
Peer->>BGP_Core: UPDATE (MP_REACH_NLRI)
BGP_Core->>BGP_LS: bgp_nlri_parse_ls()
BGP_LS->>BGP_LS: bgp_ls_decode_nlri()
BGP_LS->>BGP_LS: bgp_ls_nlri_get()
BGP_LS->>BGP_Core: bgp_update()
BGP_Core->>BGP_Core: Store ls_nlri in path_info->extra
BGP_Core->>BGP_Core: Install in RIB
BGP_Core->>BGP_LS: Update TED (consumer mode)
|
Add function to create deep copy of BGP-LS NLRI structures. Used in subsequent commits for NLRI storage and management. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add hash table infrastructure to store BGP-LS NLRIs originated by the local node and received from peers. - Add nlri_hash to bgp_ls structure for NLRI storage - Add hash functions to compute hash keys and compare NLRIs - Add bgp_ls_nlri_intern() to insert NLRI and increment reference count - Add bgp_ls_nlri_unintern() to remove NLRI and decrement reference count - Add bgp_ls_entry_lookup() to lookup NLRI in the hash table - Add bgp_ls_nlri_get() to return existing NLRI or create new entry - Integrate ID allocator to assign unique IDs when NLRI is interned NLRIs are reference counted and automatically freed when refcount reaches zero. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Implement unified hash table for BGP-LS attribute interning and lookup. - Implement bgp_ls_attr_get(): Insert BGP-LS attribute into unified hash table, returning existing entry if already present or creating and inserting new entry - Implement bgp_ls_attr_lookup(): Search hash table for BGP-LS attribute matching the provided attributes - Implement bgp_ls_attr_intern(): Perform attribute interning by looking up attribute in hash table, incrementing reference counter if found, storing pointer for later unintern - Implement bgp_ls_attr_unintern(): Decrement reference counter for interned attribute and remove from hash table when counter reaches zero The unified hash table ensures that duplicate BGP-LS attributes across multiple paths and peers are deduplicated, reducing memory consumption and improving lookup performance for route decision making. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add EC_BGP_LS_PACKET error code for BGP-LS NLRI and attribute packet parsing/encoding errors. This error code is used by BGP-LS decode functions to log warnings when malformed packets are received from peers, such as invalid TLV lengths, missing mandatory fields, or unknown NLRI types. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add functions to serialize BGP-LS NLRIs to wire format per RFC 9552. The encode functions convert in-memory NLRI structures to the TLV-based wire format used in MP_REACH_NLRI and MP_UNREACH_NLRI path attributes. - bgp_ls_encode_node_descriptor() - Encode Node Descriptors - bgp_ls_encode_link_descriptor() - Encode Link Descriptors - bgp_ls_encode_prefix_descriptor() - Encode Prefix Descriptors - bgp_ls_encode_node_nlri() - Encode Node NLRI - bgp_ls_encode_link_nlri() - Encode Link NLRI - bgp_ls_encode_prefix_nlri() - Encode IPv4/IPv6 Prefix NLRIs - bgp_ls_encode_nlri() - Top-level encoder for any BGP-LS NLRI - bgp_ls_encode_attr() - Encode BGP-LS Attributes (Type 29) Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add functions to parse BGP-LS NLRIs from wire format per RFC 9552. The decode functions parse NLRIs received in MP_REACH_NLRI and MP_UNREACH_NLRI path attributes into in-memory structures. - bgp_ls_decode_node_descriptor() - Parse Node Descriptor - bgp_ls_decode_link_descriptor() - Parse Link Descriptor - bgp_ls_decode_prefix_descriptor() - Parse Prefix Descriptor - bgp_ls_decode_node_nlri() - Parse Node NLRI - bgp_ls_decode_link_nlri() - Parse Link NLRI - bgp_ls_decode_prefix_nlri() - Parse IPv4/IPv6 Prefix NLRI - bgp_ls_decode_nlri() - Top-level decoder for BGP-LS NLRI - bgp_ls_parse_attr() - Main attribute parser dispatcher Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add Traffic Engineering Database (TED) instance to BGP-LS structure to store link-state topology. In FRR's Link State architecture, IGP protocols (IS-IS, OSPF) act as producers that build link-state databases from protocol exchanges and send updates via ZAPI Opaque messages. BGP-LS acts as a consumer that synchronizes with IGPs and listens for updates, maintaining a TED with the topology information. The TED models network topology as a graph G(V, E) with: - Vertices (V): Network nodes from BGP-LS Node NLRIs - Edges (E): Unidirectional links from BGP-LS Link NLRIs - Subnets (P): Prefixes from BGP-LS Prefix NLRIs Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add helper functions to register and unregister BGP-LS for Link State database notifications from IGP producers. In FRR's Link State architecture, consumers must register with zebra to receive ZAPI Opaque Link State Update messages from producers (IS-IS, OSPF). These functions wrap the Link State API registration mechanism: - bgp_ls_register() - Register to receive LS updates from IGPs - bgp_ls_unregister() - Unregister from LS updates Registration enables BGP-LS to receive Node, Link, and Prefix updates when IGPs detect topology changes. This is required for BGP-LS to maintain an up-to-date TED and advertise topology to peers per RFC 9552. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Extend the core BGP attribute structure to support BGP-LS Attributes (RFC 9552 Section 5.3) by adding ls_attr field and updating all related attribute processing functions. Changes: - Add ls_attr field to struct attr to store BGP-LS Attribute TLVs - Update attrhash_key_make() to include ls_attr in attribute hash key - Update attrhash_cmp() to compare ls_attr when present - Extend bgp_attr_intern() to intern BGP-LS attributes - Extend bgp_attr_unintern() to properly deintern/free BGP-LS attributes This enables the core BGP attribute handling infrastructure to properly manage BGP-LS attributes through the standard attribute interning mechanism, ensuring reference counting and deduplication of BGP-LS attribute data across the RIB. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Implement BGP-LS route installation and withdrawal to enable processing of BGP-LS NLRIs received in BGP UPDATE messages. In BGP-LS, UPDATE messages contain BGP-LS NLRIs (not traditional prefixes). When a BGP UPDATE with BGP-LS NLRI is received, a bgp_dest is allocated to represent that NLRI location in the RIB and stored in the BGP RIB tree. The ls_nlri field in bgp_dest stores the BGP-LS NLRI at that destination. Changes: - Add bgp_ls_update() - Install or update BGP-LS NLRI in the BGP RIB Called when a BGP UPDATE message contains a BGP-LS NLRI to add/modify a BGP-LS route in the RIB - Add bgp_ls_withdraw() - Withdraw BGP-LS NLRI from the BGP RIB Called when a BGP UPDATE message contains a withdrawn BGP-LS NLRI to remove the BGP-LS route from the RIB - Add ls_nlri field to bgp_dest structure Stores the BGP-LS NLRI at the destination in the RIB (used as the destination key for BGP-LS routes) - Extend bgp_dest_unlock_node() cleanup logic Properly free ls_nlri when destination is being freed from the RIB Behavior: - When a BGP UPDATE is received with BGP-LS NLRI, bgp_ls_update() creates/updates a bgp_dest with that NLRI and installs it in the RIB - When a BGP UPDATE is received with withdrawn BGP-LS NLRI, bgp_ls_withdraw() removes the bgp_dest containing that NLRI from the RIB - Proper resource cleanup ensures ls_nlri is freed when destinations are removed from the RIB (bgp_dest_unlock_node) Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add callback functions to parse and process Link State updates received from IGP producers via ZAPI Opaque messages. When IGPs (IS-IS, OSPF) detect topology changes, they send Link State Update messages through zebra to registered consumers. These functions handle the received messages: - bgp_ls_parse_update() - Parse ZAPI Opaque Link State messages - bgp_ls_process_node() - Process Node updates (ADD/UPDATE/DELETE) - bgp_ls_process_link() - Process Link updates (ADD/UPDATE/DELETE) - bgp_ls_process_prefix() - Process Prefix updates (ADD/UPDATE/DELETE) The functions use the Link State API to extract Node, Link, or Prefix information and update the TED accordingly. Updates trigger BGP-LS NLRI generation for advertisement to peers. This enables BGP-LS to maintain a synchronized TED reflecting current IGP topology and propagate changes to peers per RFC 9552. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add callback handler to process ZAPI Opaque messages from zebra containing Link State updates from IGP producers. Register bgp_zebra_opaque_msg_handler() as the callback for ZEBRA_OPAQUE_MESSAGE type in the zebra client handler table. The handler: - Decodes ZAPI Opaque message header using zclient_opaque_decode() - Routes Link State messages (LINK_STATE_SYNC, LINK_STATE_UPDATE) to bgp_ls_process_linkstate_message() for TED processing - Logs warnings for unknown opaque message types This completes the communication path between IGP producers (IS-IS, OSPF) and BGP-LS consumer, enabling BGP-LS to receive topology updates and database synchronization messages via zebra's ZAPI Opaque mechanism. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add BGP_LS_NODE to enum node_type in command.h to enable BGP Link-State
address family configuration mode.
This allows creating a dedicated configuration context for BGP-LS:
router bgp 65000
address-family link-state
<BGP-LS specific commands>
exit-address-family
Follows the same pattern as other BGP address families (BGP_EVPN_NODE,
BGP_SRV6_NODE).
Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Install BGP_LS_NODE in the CLI node hierarchy and add commands to
activate and configure BGP Link-State address family.
New commands:
- address-family link-state [link-state]
Enters BGP-LS configuration mode under router bgp
- neighbor PEER activate
Activates BGP-LS address family for the specified neighbor
Configuration example:
router bgp 65000
neighbor 192.0.2.1 remote-as 65001
address-family link-state
neighbor 192.0.2.1 activate
exit-address-family
Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Extend bgp_config_write() to serialize BGP Link-State address family configuration. This enables BGP-LS configuration to be: - Displayed via show running-config - Saved to startup-config (write memory) - Written to configuration files Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add commands to display BGP Link-State NLRIs from the BGP RIB. New commands: - show bgp link-state link-state [json] Display all BGP-LS routes with node/link/prefix NLRIs - show bgp link-state link-state NLRI [json] Display specific BGP-LS route by NLRI identifier NLRI format: [Type][ID][Protocol][Instance][AS][Area][Descriptors...] Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Integrate BGP_LS_NODE into vtysh to enable link-state address family
configuration.
This allows users to configure BGP-LS through vtysh using:
router bgp 65000
address-family link-state
neighbor <peer> activate
exit-address-family
Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Register for Link State database updates when the first BGP-LS peer is activated, and unregister when the last peer is deactivated. Modify peer_activate() and peer_deactivate() to manage Link State database registration based on active BGP-LS peers: - When first peer is activated for link-state address family, call bgp_ls_register() to subscribe to IGP topology updates from zebra - When last peer is deactivated, call bgp_ls_unregister() to stop receiving updates This optimizes resource usage by only receiving IGP topology updates (from IS-IS, OSPF) when there are active BGP-LS peers that need to receive the information. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add display support for BGP-LS multi-protocol capability in BGP OPEN message output. Update bgp_capability_vty_out() to properly display BGP-LS capabilities: - Display "AFI BGP-LS" for AFI_BGP_LS (16388) - Display "SAFI BGP-LS" for SAFI_BGP_LS (71) - Add JSON output support for BGP-LS capabilities This allows users to verify BGP-LS capability negotiation between peers using "show bgp neighbor" commands, displaying both text and JSON output for link-state address family capability advertisement and reception. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add BGP-LS capability checks to peer activity and address family negotiation functions. Update peer status and capability negotiation functions to include BGP-LS AFI/SAFI: - peer_active() - Check if peer has BGP-LS configured - peer_active_nego() - Check if BGP-LS was negotiated with peer - peer_group_af_configured() - Check if peer group has BGP-LS enabled - bgp_open_option_parse() - Validate BGP-LS in capability negotiation This ensures BGP sessions with link-state address family are properly recognized as active and that capability negotiation correctly validates BGP-LS multi-protocol extensions. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add BGP-LS encoding support to UPDATE message generation for transmitting Link-State topology information to peers. Implement bgp_packet_ls_attribute() to encode BGP-LS Attribute (Type 29) by dispatching to type-specific encoders (node/link/prefix attributes). Extend packet building functions to accept ls_nlri parameter: - bgp_packet_attribute() - encode BGP-LS attribute when present - bgp_packet_mpattr_prefix() - call bgp_ls_encode_nlri() for SAFI_BGP_LS - bgp_packet_mpunreach_prefix() - handle BGP-LS withdrawals Update subgroup_update_packet() and subgroup_withdraw_packet() to extract ls_nlri from path_info->extra and pass to encoding functions. This enables BGP-LS routes to be advertised and withdrawn using the RFC 9552 wire format. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add bgp_attr_ls() function to parse and intern BGP-LS attributes (Type 29) from received BGP update messages. The function validates peer configuration, parses Type 29 TLVs, and interns the resulting attribute for use in route processing. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Call bgp_ls_unregister() in bgp_ls_terminate() to cleanly unregister from the zebra link-state database when BGP instance terminates. This ensures proper cleanup and stops receiving IGP topology updates when the BGP-LS functionality is no longer needed. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add inbound BGP-LS message processing to receive Link-State topology information from BGP peers. When BGP receives a BGP UPDATE message from a peer, it calls bgp_nlri_parse() to parse the NLRI. The bgp_nlri_parse() function checks the SAFI (Subsequent Address Family Identifier) contained in the UPDATE message and dispatches to the appropriate SAFI-specific handler. Currently supported SAFIs include: - SAFI_UNICAST, SAFI_MULTICAST, SAFI_LABELED_UNICAST β bgp_nlri_parse_ip() - SAFI_MPLS_VPN β bgp_nlri_parse_vpn() - SAFI_ENCAP β bgp_nlri_parse_encap() - SAFI_EVPN β bgp_nlri_parse_evpn() - SAFI_FLOWSPEC β bgp_nlri_parse_flowspec() This commit extends bgp_nlri_parse() to handle SAFI_BGP_LS and dispatch to a new handler bgp_nlri_parse_ls(). The bgp_nlri_parse_ls() function performs the following operations: - Decodes BGP-LS NLRIs from MP_REACH_NLRI and MP_UNREACH_NLRI attributes using bgp_ls_decode_nlri() - Interns decoded NLRI into hash table via bgp_ls_nlri_get() - Creates synthetic prefix (AF_UNSPEC) with NLRI ID for RIB storage - Calls bgp_update() for route advertisements or bgp_withdraw() for route removals to install/remove BGP-LS routes in the RIB This completes the inbound UPDATE message processing path, enabling BGP to receive and store Link-State topology from peers per RFC 9552. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
BGP-LS routes advertised to peers require a nexthop with the same address family as the peer session (IPv4 peer needs IPv4 nexthop, IPv6 peer needs IPv6 nexthop). The MP_REACH_NLRI and MP_UNREACH_NLRI encoding code in bgp_attr does not have direct knowledge of the peer's address family, making it unable to select the appropriate nexthop address family for BGP-LS advertisements. Add peer flags PEER_FLAG_BGP_LS_IPV4 and PEER_FLAG_BGP_LS_IPV6 that are set during peer activation for BGP-LS address family. The bgp_attr encoding functions check these flags to determine whether to encode IPv4 or IPv6 nexthop addresses in MP_REACH_NLRI attributes. This ensures BGP-LS routes are advertised with nexthops matching the peer session's address family, allowing proper route exchange with both IPv4 and IPv6 BGP-LS peers. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Add pytest topology test for BGP Link-State covering producer and consumer modes with ISIS IGP backend. Tests BGP-LS capability negotiation, NLRI advertisement/reception (Node, Link, Prefix), and dynamic topology change propagation including route additions/removals and link state changes. Verifies BGP-LS updates flow correctly from IGP through BGP-LS producer to BGP-LS consumer. Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
cscarpitta
force-pushed
the
feature/bgp_linkstate
branch
from
March 10, 2026 10:43
aea4183 to
3a97a2f
Compare
Contributor
Author
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.
This PR implements BGP Link-State (BGP-LS) support as defined in RFC 9552.
BGP-LS defines a mechanism by which link-state and traffic engineering information can be collected from networks and shared with external components using the BGP routing protocol. This is achieved using a BGP Network Layer Reachability Information (NLRI) encoding format that describes network topology, including nodes, links, and prefixes, along with their associated attributes.
The BGP-LS NLRI is carried in BGP using an address family (AFI 16388) and subsequent address family identifier (SAFI 71).
Reference: RFC 9552 - "Distribution of Link-State and Traffic Engineering Information Using BGP"
Configuration Example
To enable BGP-LS for a neighbor: