Configuring SRv6
This document describes the device data model parameters one should consider when creating an SRv6 device configuration template. For a wider picture, please see the contributing new devices document.
The configuration template (in Jinja2 format) should be stored in the netsim/ansible/templates/srv6/ directory. The template file name is derived from the netlab_device_type or ansible_network_os variable (see Configuring BGP for details on how the platform name is used).
Tip
The <platform> is the value of the netlab_device_type or ansible_network_os variable.
Device Features
Add the following features.srv6 entries to a device YAML file (netsim/devices/<device>.yml) to indicate which SRv6 features the platform supports:
isis – device supports SRv6 with IS-IS
ospf – device supports SRv6 with OSPFv3
bgp – device supports BGP v4/v6 overlay over SRv6 (end.dt4/end.dt6)
vpn – device supports BGP L3VPN v4/v6 over SRv6
Node Attributes
The srv6 node dictionary is always present on nodes that have the srv6 module enabled. It contains the following attributes after transformation:
srv6.locator
An IPv6 prefix in CIDR notation (e.g., 5f00:0:1::/48), specified in lab topology or automatically allocated per-node from the SRv6 locator address pool (default 5F00::/16, based on the IANA-reserved range in RFC 9602).
Templates typically use srv6.locator to configure the SRv6 locator prefix:
locator {{ inventory_hostname }}
prefix {{ srv6.locator }}
srv6.igp
A list of IGP protocol names (e.g., ['isis']) over which SRv6 should be signalled. The default is ['isis']. Valid values are isis and ospf.
Use if 'isis' in srv6.igp (or 'ospf' in srv6.igp) to conditionally enable SRv6 under an IGP:
{% if 'isis' in srv6.igp %}
router isis {{ isis.instance }}
segment-routing srv6
locator {{ inventory_hostname }}
{% endif %}
srv6.bgp
An optional dictionary with keys ipv4 and/or ipv6, each containing a list of BGP neighbor types that should use SRv6 as the transport for the plain IPv4 or IPv6 unicast address family (end.dt4/end.dt6, not VPN).
srv6.bgp is absent when the feature is disabled.
Example:
{% if srv6.bgp is defined %}
{% for af in ['ipv4','ipv6'] if af in srv6.bgp %}
family {{ af }}
locator {{ inventory_hostname }}
{% endfor %}
{% endif %}
srv6.vpn
A dictionary with keys ipv4 and/or ipv6, each containing a list of BGP neighbor types for which BGP L3VPN routes should be carried over SRv6 (end.dt4-vrf/end.dt6-vrf).
The structure and boolean-expansion rules are identical to srv6.bgp. srv6.vpn is absent when L3VPN is disabled.
srv6.transit_only
A boolean flag (True/False). When True, the node acts as a transit-only SRv6 node — it forwards SRv6 traffic but does not need to allocate FPE resources or end.dt SIDs for originating/terminating traffic. Default is False.
{% if not srv6.transit_only|default(False) %}
termination-fpe: [2]
{% endif %}
Loopback IPv6 Address
loopback.ipv6 is always present on SRv6 nodes (enforced by node_post_transform). It may be user-defined, assigned from the loopback topology pool, or automatically assigned as the first host address in srv6.locator (when srv6.allocate_loopback: True).
Templates must use loopback.ipv6 as the SRv6 source address:
source-address {{ loopback.ipv6 | ansible.utils.ipaddr('address') }}
BGP Neighbor Attributes
The srv6 module modifies the bgp.neighbors list during node_post_transform. For each BGP neighbor that…
has an
ipv6transport addresshas no
ipv4transport address,is listed in
srv6.bgp.ipv4orsrv6.vpn.ipv4(i.e., IPv4 AF is carried over an IPv6 session)
…the module adds:
extended_nexthop (
True) — signals that the BGP session requires extended next-hop encoding (RFC 8950) to carry IPv4 prefixes over an IPv6 transport session.
Templates could check for this attribute to conditionally enable extended next-hop negotiation:
{% for n in bgp.neighbors|default([]) if n.ipv6 is defined %}
{% if n.extended_nexthop is defined %}
neighbor {{ n.ipv6 }} capability extended-nexthop
{% endif %}
{% endfor %}
Interface Attributes
The srv6 module does not add any per-interface attributes. Templates that need SRv6 interface-level configuration (e.g., end.x SIDs) typically iterate over interfaces that have IS-IS or OSPF enabled:
{% set srv6_interfaces = interfaces | selectattr('isis','defined') | list %}
Template Architecture
Complex platforms may split SRv6 configuration into a main template and a conditionally-included BGP sub-template. The main template handles locator declaration and IGP integration; the BGP sub-template handles the BGP overlay and VPN configuration.
Example (frr.j2 main template, simplified):
segment-routing
srv6
encapsulation
source-address {{ loopback.ipv6 | ansible.utils.ipaddr('address') }}
locators
locator {{ inventory_hostname }}
prefix {{ srv6.locator }}
{% if 'isis' in srv6.igp|default([]) and isis.instance is defined %}
router isis {{ isis.instance }}
segment-routing srv6
locator {{ inventory_hostname }}
{% endif %}
{% if srv6.vpn is defined and bgp.as is defined %}
{% include "frr.bgp.j2" %}
{% endif %}
Example (frr.bgp.j2 BGP sub-template, simplified):
router bgp {{ bgp.as }}
segment-routing srv6
locator {{ inventory_hostname }}
{% if srv6.vpn is defined %}
{% for n in bgp.neighbors|default([]) if n.ipv6 is defined %}
{% if n.extended_nexthop is defined %}
neighbor {{ n.ipv6 }} capability extended-nexthop
{% endif %}
{% for af in ['ipv4','ipv6'] if n.type in srv6.vpn.get(af,[]) %}
address-family {{ af }} vpn
neighbor {{ n.ipv6 }} activate
{% endfor %}
{% endfor %}
{% endif %}
Example (sros.j2, Nokia SR-OS — gNMI/YANG path style):
{% set srv6_interfaces = interfaces | selectattr('isis','defined') | list %}
updates:
- path: configure/router[router-name=Base]/segment-routing/segment-routing-v6
val:
locator:
- locator-name: JvB
prefix:
ip-prefix: {{ srv6.locator }}
{% if not srv6.transit_only|default(False) %}
termination-fpe: [2]
{% endif %}
{% if 'isis' in srv6.igp %}
- path: configure/router[router-name=Base]/isis[isis-instance=0]
val:
segment-routing-v6:
admin-state: enable
locator:
- locator-name: JvB
{% endif %}
Integration Tests
The integration tests for the SRv6 module are in the tests/integration/srv6/ directory:
02-isis-ipv4-bgp-vpn.yml— PE router running IS-IS + BGP L3VPN (srv6.vpn.ipv4: True) over an IPv6-only SRv6 core, with VRFs attached; validates end-to-end L3VPN reachability.12-isis-ipv6-bgp-vpn.yml— Similar scenario with IPv6 L3VPN overlay.x-01-isis-ipv4-bgp.yml— PE router running IS-IS + BGP (srv6.bgp.ipv4: True) withallocate_loopback: True, carrying IPv4 over an IPv6-only SRv6 core (4PE scenario).x-11-isis-ipv6-bgp.yml— Similar scenario with IPv6 BGP overlay.