Skip to content

Segment Routing

Thomas Mangin edited this page Nov 13, 2025 · 3 revisions

Segment Routing

Segment Routing (SR) is a source-based routing paradigm that enables traffic engineering and service chaining by encoding paths as sequences of segments. ExaBGP provides comprehensive Segment Routing support via BGP-LS extensions, enabling SDN controllers and orchestration systems to collect SR topology information and distribute SRv6 (Segment Routing over IPv6) policies.

Table of Contents


What is Segment Routing?

Segment Routing (SR) is a source-based routing architecture that simplifies traffic engineering and enables programmable network paths. Instead of hop-by-hop routing decisions, the source encodes the entire path as a sequence of "segments" in the packet header.

Key Concepts

Segment: An instruction to perform a specific action on a packet

  • Node Segment: Forward to a specific router
  • Adjacency Segment: Forward over a specific link
  • Service Segment: Forward to a service function

Segment List: Ordered sequence of segments defining the path

Source Routing: Path determined at ingress router, not hop-by-hop

How Segment Routing Works

Traditional Routing (hop-by-hop):
β”Œβ”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”
β”‚  A  │───▢│  B  │───▢│  C  │───▢│  D  β”‚
β””β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”˜
Each router makes independent forwarding decision

Segment Routing (source-based):
β”Œβ”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”
β”‚  A  │───▢│  B  │───▢│  C  │───▢│  D  β”‚
β””β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”˜
  β”‚
  └─ Encodes path: [B, C, D] in packet header
     Routers execute segment instructions

Benefits:

  • βœ… Traffic Engineering: Explicit path control
  • βœ… Simplicity: No per-flow state in network core
  • βœ… Scalability: State at source only, not intermediate routers
  • βœ… Service Chaining: Route through service functions
  • βœ… Fast Reroute: Pre-computed backup paths

Segment Routing Architectures

1. SR-MPLS (Segment Routing over MPLS)

Data Plane: MPLS label stack Control Plane: IS-IS or OSPF extensions Segment Identifier: MPLS label (20 bits)

Example:

IPv4 Packet with SR-MPLS:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Label: 16003 β”‚ Label: 16002 β”‚ Label: 16001 β”‚ IPv4 Header β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚              β”‚              β”‚
     └─ Segment 3   └─ Segment 2  └─ Segment 1 (Top of Stack)

Forwarding:
- Router 1: Pop 16001, forward to next segment
- Router 2: Pop 16002, forward to next segment
- Router 3: Pop 16003, deliver to destination

Use Cases:

  • MPLS networks
  • Traffic engineering in SP core
  • Fast reroute

2. SRv6 (Segment Routing over IPv6)

Data Plane: IPv6 Segment Routing Header (SRH) Control Plane: BGP, IS-IS, or OSPF extensions Segment Identifier: IPv6 address (128 bits)

Example:

IPv6 Packet with SRv6:
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ IPv6 Header  β”‚ Segment Routing Header (SRH) β”‚ Payload     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
                      └─ Segment List:
                         - fc00:0:1::1 (Segment 1)
                         - fc00:0:2::1 (Segment 2)
                         - fc00:0:3::1 (Segment 3)

IPv6 Destination Address = Current active segment

Use Cases:

  • IPv6 networks
  • Data center fabrics
  • 5G mobile networks (Mobile User Plane)
  • Service Function Chaining (SFC)

ExaBGP Segment Routing Capabilities

ExaBGP provides BGP-LS extensions for Segment Routing:

βœ… SRv6 Support (RFC 9514):

  • SRv6 SID Information TLV
  • SRv6 Capabilities TLV
  • SRv6 End.X SID TLV
  • SRv6 LAN End.X SID TLV
  • SRv6 Locator TLV
  • SRv6 Endpoint Behavior sub-TLVs
  • SRv6 SID Structure sub-TLVs

βœ… SR-MPLS Support (via BGP-LS):

  • SR Capabilities
  • SR Algorithm
  • SR Local Block
  • Adjacency Segment Identifier (Adj-SID)
  • LAN Adjacency Segment Identifier
  • Prefix Segment Identifier (Prefix-SID)

βœ… BGP-LS Integration:

  • Receive SR topology via BGP-LS
  • Distribute SR information to SDN controllers
  • Parse and decode SR TLVs

❌ Not Supported:

  • ❌ SRv6 policy origination (ExaBGP receives SR info but doesn't originate SRv6 policies)
  • ❌ SR-MPLS label programming (ExaBGP does NOT manipulate MPLS FIB)
  • ❌ SRv6 header insertion (ExaBGP is control plane only)

Key Point: ExaBGP's role in Segment Routing is topology collection and distribution via BGP-LS. It does NOT perform SR forwarding or label/SID programming.

Implementation:

  • src/exabgp/bgp/message/update/attribute/bgpls/link/srv6*.py (SRv6)
  • src/exabgp/bgp/message/update/attribute/bgpls/ (SR-MPLS)
  • src/exabgp/protocol/family.py (BGP-LS SAFI)

RFC Compliance:

  • RFC 9514: BGP-LS Extensions for SRv6
  • RFC 7752: North-Bound Distribution of Link-State and TE Information

SR-MPLS Overview

SR-MPLS Segments

Prefix-SID (Prefix Segment Identifier):

  • Globally unique identifier for a router (node segment)
  • Shortest path forwarding to the node
  • Example: Router A has Prefix-SID 16001

Adjacency-SID (Adj-SID):

  • Identifier for a specific link (adjacency segment)
  • Forces traffic over a specific link
  • Example: Link Aβ†’B has Adj-SID 24001

Binding-SID:

  • Identifier for a path or policy
  • Maps to a segment list
  • Example: TE policy has Binding-SID 30001

SR-MPLS via BGP-LS

ExaBGP receives SR-MPLS topology information via BGP-LS:

IGP Speaker (IS-IS/OSPF)      ExaBGP (BGP-LS)           SDN Controller
       β”‚                             β”‚                         β”‚
       β”‚  SR topology:               β”‚                         β”‚
       β”‚  - Prefix-SID 16001         β”‚                         β”‚
       β”‚  - Adj-SID 24001            β”‚                         β”‚
       β”‚                             β”‚                         β”‚
       └─────BGP-LS UPDATE──────────▢│                         β”‚
               (SR TLVs)             β”‚                         β”‚
                                     β”‚                         β”‚
                                     └────BGP-LS UPDATE───────▢│
                                            (SR topology)       β”‚
                                                                β”‚
                                                          Build TE paths
                                                          using SR-MPLS

ExaBGP's Role:

  1. Receive BGP-LS updates with SR-MPLS TLVs from IGP speaker
  2. Parse SR Prefix-SID, Adj-SID, SR Capabilities
  3. Forward BGP-LS information to SDN controller
  4. SDN controller computes SR-MPLS paths

ExaBGP does NOT:

  • Program MPLS labels into forwarding plane
  • Originate SR-MPLS policies
  • Perform SR-MPLS encapsulation

SRv6 Overview (RFC 9514)

SRv6 Architecture

SRv6 Segment: 128-bit IPv6 address with special meaning

Structure:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Locator (variable)     β”‚ Function (var)β”‚ Arg (var)    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  fc00:0:1::/48          β”‚ ::1          β”‚ ::0          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                      β”‚              β”‚
         └─ Network prefix      └─ Behavior    └─ Arguments

Example SRv6 SID: fc00:0:1::1
- Locator: fc00:0:1::/48 (identifies node/locator)
- Function: ::1 (behavior to execute)
- Arguments: ::0 (optional parameters)

Components:

  • Locator: IPv6 prefix identifying the node
  • Function: Identifies the SRv6 endpoint behavior
  • Arguments: Optional parameters for the function

SRv6 Endpoint Behaviors

ExaBGP supports these SRv6 behaviors via BGP-LS:

End (0x01): Endpoint function

  • Regular SRv6 endpoint
  • Pop top SID, process next segment

End.X (0x05): Endpoint with cross-connect

  • Layer 3 cross-connect to specific neighbor
  • Used for SR policy steering

End.DT4 (0x13): Decapsulation and IPv4 table lookup

  • Remove SRv6 header
  • Lookup IPv4 destination in specific table

End.DT6 (0x14): Decapsulation and IPv6 table lookup

  • Remove SRv6 header
  • Lookup IPv6 destination in specific table

End.DT46 (0x15): Decapsulation and IP table lookup

  • Remove SRv6 header
  • Lookup IPv4 or IPv6 destination

See SRv6 Endpoint Behaviors section for complete list.

SRv6 via BGP-LS

IGP Speaker (IS-IS/OSPF)      ExaBGP (BGP-LS)           SDN Controller
       β”‚                             β”‚                         β”‚
       β”‚  SRv6 topology:             β”‚                         β”‚
       β”‚  - Locator fc00:1::/48      β”‚                         β”‚
       β”‚  - End.X SID fc00:1::100    β”‚                         β”‚
       β”‚  - Behavior: End.X          β”‚                         β”‚
       β”‚                             β”‚                         β”‚
       └─────BGP-LS UPDATE──────────▢│                         β”‚
               (SRv6 TLVs)           β”‚                         β”‚
                                     β”‚                         β”‚
                                     └────BGP-LS UPDATE───────▢│
                                            (SRv6 topology)     β”‚
                                                                β”‚
                                                          Compute SRv6
                                                          segment lists

ExaBGP's Role:

  1. Receive BGP-LS updates with SRv6 TLVs from IGP speaker
  2. Parse SRv6 SID, Locator, Endpoint Behaviors
  3. Forward BGP-LS information to SDN controller
  4. SDN controller programs SRv6 policies

ExaBGP does NOT:

  • Insert SRv6 headers into packets
  • Program SRv6 SIDs into kernel
  • Originate SRv6 policies

BGP-LS SR Extensions

SRv6 TLVs Supported by ExaBGP

RFC 9514 defines these TLVs (all supported by ExaBGP):

Link Attribute TLVs

TLV Name Purpose
1106 SRv6 End.X SID Layer 3 adjacency SID
1107 SRv6 LAN End.X SID LAN adjacency SID

Prefix Attribute TLVs

TLV Name Purpose
1158 SRv6 Locator SRv6 locator advertisement

Node Attribute TLVs

TLV Name Purpose
1038 SRv6 Capabilities Node SRv6 capabilities

Sub-TLVs

Sub-TLV Name Purpose
1 SRv6 Endpoint Behavior Behavior code and flags
2 SRv6 SID Structure Locator/Function/Arg lengths

Implementation: src/exabgp/bgp/message/update/attribute/bgpls/link/srv6*.py

SR-MPLS TLVs

TLV Name Purpose
1034 SR Capabilities SR-MPLS capabilities
1035 SR Algorithm Supported SR algorithms
1036 SR Local Block SRLB range
1099 Adj-SID Adjacency segment ID
1100 LAN Adj-SID LAN adjacency segment ID
1158 Prefix-SID Prefix segment ID

Configuration Examples

BGP-LS Configuration for SR Topology

# ExaBGP receives BGP-LS with SR extensions
neighbor 192.168.1.1 {
    router-id 192.168.1.2;
    local-address 192.168.1.2;
    local-as 65001;
    peer-as 65001;  # iBGP with IGP speaker

    family {
        bgpls;  # BGP-LS for topology collection
    }

    api {
        processes [ sr-topology-collector ];
    }
}

process sr-topology-collector {
    run python3 /etc/exabgp/api/sr_topology.py;
    encoder json;
}

API Process for SR Topology Collection

#!/usr/bin/env python3
"""Collect SRv6 and SR-MPLS topology via BGP-LS"""
import sys
import json

def process_bgpls_sr():
    """Process BGP-LS updates with SR extensions"""

    srv6_sids = {}
    sr_mpls_sids = {}

    while True:
        line = sys.stdin.readline().strip()
        if not line:
            break

        try:
            msg = json.loads(line)

            if msg.get('type') == 'update' and 'announce' in msg:
                # Process BGP-LS announcements
                bgpls = msg['announce'].get('bgpls bgpls', {})

                for nexthop, nlri_list in bgpls.items():
                    for nlri in nlri_list:
                        # Extract SRv6 information
                        if 'srv6-sid' in nlri:
                            srv6_sid = nlri['srv6-sid']
                            print(f"SRv6 SID: {srv6_sid}", file=sys.stderr)
                            srv6_sids[srv6_sid] = nlri

                        # Extract SR-MPLS information
                        if 'prefix-sid' in nlri:
                            prefix_sid = nlri['prefix-sid']
                            print(f"SR-MPLS Prefix-SID: {prefix_sid}", file=sys.stderr)
                            sr_mpls_sids[prefix_sid] = nlri

                        # Extract SRv6 Locator
                        if 'srv6-locator' in nlri:
                            locator = nlri['srv6-locator']
                            print(f"SRv6 Locator: {locator}", file=sys.stderr)

                        # Extract SRv6 Endpoint Behavior
                        if 'srv6-endpoint-behavior' in nlri:
                            behavior = nlri['srv6-endpoint-behavior']
                            print(f"SRv6 Behavior: {behavior}", file=sys.stderr)

        except json.JSONDecodeError:
            pass

process_bgpls_sr()

Use Cases

1. SDN Controller Topology Collection

Scenario: SDN controller collects SR topology via ExaBGP for path computation.

Architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           SDN Controller / PCE                β”‚
β”‚     (Path Computation Element)                β”‚
β”‚  - Computes SR-MPLS/SRv6 paths               β”‚
β”‚  - Programs SR policies                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β”‚ BGP-LS (SR topology)
                    β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚  ExaBGP  β”‚
              β”‚ BGP-LS   β”‚
              β”‚ Receiver β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                    β–²
                    β”‚ BGP-LS (SR TLVs)
                    β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚           β”‚           β”‚
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚Router Aβ”‚  β”‚Router Bβ”‚  β”‚Router Cβ”‚
   β”‚ IS-IS  β”‚  β”‚ IS-IS  β”‚  β”‚ IS-IS  β”‚
   β”‚ SRv6   β”‚  β”‚ SRv6   β”‚  β”‚ SRv6   β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜

ExaBGP Configuration:

neighbor 192.168.1.254 {  # IGP speaker
    router-id 192.168.1.2;
    local-address 192.168.1.2;
    local-as 65001;
    peer-as 65001;

    family {
        bgpls;
    }

    api {
        processes [ topology-to-controller ];
    }
}

process topology-to-controller {
    run python3 /etc/exabgp/api/forward_to_controller.py;
    encoder json;
}

API Process:

#!/usr/bin/env python3
"""Forward SR topology to SDN controller"""
import sys
import json
import requests

CONTROLLER_URL = "http://10.0.0.1:8080/topology"

def forward_to_controller():
    """Forward BGP-LS SR updates to SDN controller"""

    while True:
        line = sys.stdin.readline().strip()
        if not line:
            break

        try:
            msg = json.loads(line)

            if msg.get('type') == 'update':
                # Forward to controller
                response = requests.post(
                    CONTROLLER_URL,
                    json=msg,
                    headers={'Content-Type': 'application/json'}
                )

                print(f"Forwarded to controller: {response.status_code}", file=sys.stderr)

        except Exception as e:
            print(f"Error: {e}", file=sys.stderr)

forward_to_controller()

2. SRv6 Network Monitoring

Scenario: Monitor SRv6 SID allocations and endpoint behaviors.

Example:

#!/usr/bin/env python3
"""Monitor SRv6 SID allocations"""
import sys
import json

class SRv6Monitor:
    def __init__(self):
        self.locators = {}
        self.sids = {}
        self.behaviors = {}

    def process_update(self, msg):
        """Process BGP-LS update with SRv6 information"""

        if msg.get('type') != 'update' or 'announce' not in msg:
            return

        bgpls = msg['announce'].get('bgpls bgpls', {})

        for nexthop, nlri_list in bgpls.items():
            for nlri in nlri_list:
                # Track locators
                if 'srv6-locator' in nlri:
                    locator = nlri['srv6-locator']['prefix']
                    node = nlri.get('node-id', 'unknown')
                    self.locators[locator] = node
                    print(f"Locator: {locator} on {node}", file=sys.stderr)

                # Track SIDs
                if 'srv6-sid' in nlri:
                    sid = nlri['srv6-sid']['address']
                    behavior = nlri.get('srv6-endpoint-behavior', {}).get('behavior', 'unknown')
                    self.sids[sid] = behavior
                    print(f"SID: {sid} Behavior: {behavior}", file=sys.stderr)

    def report(self):
        """Generate monitoring report"""
        print("\n=== SRv6 Topology Report ===", file=sys.stderr)
        print(f"Locators: {len(self.locators)}", file=sys.stderr)
        print(f"SIDs: {len(self.sids)}", file=sys.stderr)

        # Behavior distribution
        behavior_count = {}
        for sid, behavior in self.sids.items():
            behavior_count[behavior] = behavior_count.get(behavior, 0) + 1

        print("\nSID Behaviors:", file=sys.stderr)
        for behavior, count in behavior_count.items():
            print(f"  {behavior}: {count}", file=sys.stderr)

# Run monitor
monitor = SRv6Monitor()

while True:
    line = sys.stdin.readline().strip()
    if not line:
        break

    try:
        msg = json.loads(line)
        monitor.process_update(msg)
    except json.JSONDecodeError:
        pass

3. Traffic Engineering Path Computation

Scenario: Compute SR-MPLS paths using topology from ExaBGP.

Example:

#!/usr/bin/env python3
"""Compute SR-MPLS paths from BGP-LS topology"""
import sys
import json
import networkx as nx

class SRPathComputer:
    def __init__(self):
        self.topology = nx.DiGraph()
        self.prefix_sids = {}
        self.adj_sids = {}

    def process_bgpls(self, msg):
        """Build topology from BGP-LS updates"""

        if msg.get('type') != 'update' or 'announce' not in msg:
            return

        bgpls = msg['announce'].get('bgpls bgpls', {})

        for nexthop, nlri_list in bgpls.items():
            for nlri in nlri_list:
                nlri_type = nlri.get('nlri-type')

                # Node NLRI
                if nlri_type == 'node':
                    node_id = nlri['node-id']
                    self.topology.add_node(node_id)

                    # Extract Prefix-SID
                    if 'prefix-sid' in nlri:
                        prefix_sid = nlri['prefix-sid']
                        self.prefix_sids[node_id] = prefix_sid
                        print(f"Node {node_id} Prefix-SID: {prefix_sid}", file=sys.stderr)

                # Link NLRI
                elif nlri_type == 'link':
                    local_node = nlri['local-node-id']
                    remote_node = nlri['remote-node-id']
                    metric = nlri.get('metric', 1)

                    self.topology.add_edge(local_node, remote_node, weight=metric)

                    # Extract Adj-SID
                    if 'adj-sid' in nlri:
                        adj_sid = nlri['adj-sid']
                        self.adj_sids[(local_node, remote_node)] = adj_sid
                        print(f"Link {local_node}->{remote_node} Adj-SID: {adj_sid}", file=sys.stderr)

    def compute_sr_path(self, source, destination):
        """Compute SR-MPLS path from source to destination"""

        try:
            path = nx.shortest_path(self.topology, source, destination, weight='weight')
            print(f"\nPath from {source} to {destination}: {path}", file=sys.stderr)

            # Build segment list
            segment_list = []

            for i in range(len(path)):
                node = path[i]

                # Add node segment (Prefix-SID)
                if node in self.prefix_sids:
                    segment_list.append(self.prefix_sids[node])

                # Optionally add adjacency segment (Adj-SID)
                if i < len(path) - 1:
                    next_node = path[i + 1]
                    if (node, next_node) in self.adj_sids:
                        adj_sid = self.adj_sids[(node, next_node)]
                        # segment_list.append(adj_sid)  # Uncomment for strict path

            print(f"Segment List: {segment_list}", file=sys.stderr)
            return segment_list

        except nx.NetworkXNoPath:
            print(f"No path from {source} to {destination}", file=sys.stderr)
            return None

# Run path computer
computer = SRPathComputer()

while True:
    line = sys.stdin.readline().strip()
    if not line:
        break

    try:
        msg = json.loads(line)
        computer.process_bgpls(msg)
    except json.JSONDecodeError:
        pass

# Example: Compute path
# computer.compute_sr_path("192.0.2.1", "192.0.2.10")

SRv6 Endpoint Behaviors

RFC 8986 defines SRv6 endpoint behaviors. ExaBGP supports these via BGP-LS:

Endpoint Behaviors

Code Name Description
0x01 End Endpoint function
0x02 End with PSP End with Penultimate Segment Pop
0x03 End with USP End with Ultimate Segment Pop
0x04 End with PSP & USP End with both PSP and USP
0x05 End.X Endpoint with L3 cross-connect
0x06 End.X with PSP End.X with PSP
0x07 End.X with USP End.X with USP
0x08 End.X with PSP & USP End.X with both
0x09 End.T Endpoint with specific IPv6 table lookup
0x0A End.T with PSP End.T with PSP
0x0B End.T with USP End.T with USP
0x0C End.T with PSP & USP End.T with both
0x0D End.B6.Encaps Endpoint bound to SRv6 encapsulation
0x0E End.B6.Encaps.Red End.B6.Encaps with reduced SRH
0x0F End.BM Endpoint bound to SRv6 policy
0x10 End.DX6 Decapsulation and IPv6 cross-connect
0x11 End.DX4 Decapsulation and IPv4 cross-connect
0x12 End.DX2 Decapsulation and L2 cross-connect
0x13 End.DT4 Decapsulation and IPv4 table lookup
0x14 End.DT6 Decapsulation and IPv6 table lookup
0x15 End.DT46 Decapsulation and IP table lookup (IPv4/IPv6)
0x16 End.DT2U Decapsulation and unicast L2 table lookup
0x17 End.DT2M Decapsulation and multicast L2 table lookup

Most Common Behaviors:

  • End: Basic SRv6 endpoint
  • End.X: Layer 3 adjacency (like SR-MPLS Adj-SID)
  • End.DT4/DT6: VPN decapsulation and lookup
  • End.DX4/DX6: VPN decapsulation and cross-connect

Monitoring and Verification

Via API (JSON)

#!/usr/bin/env python3
"""Monitor SR topology updates"""
import sys
import json

def monitor_sr_updates():
    """Monitor and log SR topology changes"""

    while True:
        line = sys.stdin.readline().strip()
        if not line:
            break

        try:
            msg = json.loads(line)

            if msg.get('type') == 'update':
                # Check for SR information
                if 'announce' in msg:
                    bgpls = msg['announce'].get('bgpls bgpls', {})

                    for nexthop, nlri_list in bgpls.items():
                        for nlri in nlri_list:
                            # Log SRv6 updates
                            if 'srv6-sid' in nlri:
                                print(f"SRv6 SID Update: {json.dumps(nlri, indent=2)}", file=sys.stderr)

                            # Log SR-MPLS updates
                            if 'prefix-sid' in nlri:
                                print(f"SR-MPLS Prefix-SID Update: {json.dumps(nlri, indent=2)}", file=sys.stderr)

                # Check for withdrawals
                if 'withdraw' in msg:
                    bgpls = msg['withdraw'].get('bgpls bgpls', {})
                    print(f"SR Topology Withdrawal: {json.dumps(bgpls, indent=2)}", file=sys.stderr)

        except json.JSONDecodeError:
            pass

monitor_sr_updates()

Via Logging

[exabgp.log]
level = INFO
packets = true
message = true

Log output:

INFO     Peer 192.168.1.1: Received BGP-LS UPDATE with SRv6 TLVs
INFO     SRv6 Locator: fc00:0:1::/48
INFO     SRv6 End.X SID: fc00:0:1::100
INFO     SRv6 Endpoint Behavior: End.X (0x05)

Limitations and Considerations

ExaBGP Limitations

  1. Receive-Only SR Topology

    • ExaBGP receives SR information via BGP-LS
    • ExaBGP does NOT originate SRv6 policies
    • ExaBGP does NOT program SR-MPLS labels
  2. No Forwarding Plane Integration

    • ExaBGP does NOT insert SRv6 headers
    • ExaBGP does NOT manipulate MPLS forwarding
    • ExaBGP is control plane only (topology collection)
  3. BGP-LS Dependency

    • SR topology must come from IGP speaker via BGP-LS
    • Requires BGP-LS capable IGP speaker (IS-IS/OSPF with BGP-LS export)

General SR Considerations

  1. SR-MPLS vs SRv6 Choice

    • SR-MPLS: MPLS networks, mature, label-based
    • SRv6: IPv6 networks, newer, SID-based
    • Not interoperable (choose one or run both)
  2. SRv6 Overhead

    • SRv6 header adds packet overhead (variable size)
    • Long segment lists = larger packets
    • Consider MTU implications
  3. Operational Complexity

    • Requires IGP extensions (IS-IS or OSPF with SR)
    • Requires SID planning and allocation
    • Requires SDN controller for path computation (typically)

Best Practices

βœ… Do:

  • Use ExaBGP for SR topology collection
  • Forward BGP-LS to SDN controller for path computation
  • Monitor SR SID allocations
  • Document SID allocation scheme

❌ Don't:

  • Expect ExaBGP to program SR forwarding
  • Use ExaBGP as SR policy originator
  • Mix SR-MPLS and SRv6 without careful planning

See Also


References

RFCs

Internet Drafts

  • draft-ietf-spring-sr-yang: YANG Data Model for Segment Routing
  • draft-ietf-spring-segment-routing-policy: Segment Routing Policy Architecture

ExaBGP Documentation

Implementation

  • Source Code:
    • src/exabgp/bgp/message/update/attribute/bgpls/link/srv6*.py (SRv6)
    • src/exabgp/bgp/message/update/attribute/bgpls/ (SR-MPLS)
    • src/exabgp/protocol/family.py (BGP-LS)
  • ExaBGP Version: 4.x, 5.x/main

External Resources


πŸ‘» Ghost written by Claude (Anthropic AI)

Clone this wiki locally