Segment Routing IPv6 (SRv6) with VyOS
In this post we take a look at configuring Segment Routing IPv6 (SRv6) using VyOS. For those unfamiliar, VyOS is an open-source routing platform built on top of Debian Linux and features a commit-based configuration system similar to Juniper’s JUNOS. It originated as a fork of Vyatta Core in late 2013 after Brocade stopped development. If you are new to VyOS, it is recommended to read the quick start guide before continuing.
Beginning with pull request #2606, the VyOS team has made several strides to include configuration options for FRR’s BGP SRv6 capabilities. FRR is the routing control plane used in VyOS.
This post looks specifically at configuring SRv6 L3VPNs.
Topology
Above is a very basic service provider topology. On the left is our first customer (CE1). It connects to the network using a standard dual-stack IPv4/IPv6 ethernet connection to the provider network at (PE2). Similarly, the right side of the diagram is the other end of the customer VPN (CE5). It has an identical configuration as CE1, updated with its own addressing, and connects to PE4.
The service provider network consists of two provider-edge (PE) routers and one provider (P) router. The P router (P3) is completely unnecessary and could be removed at any point. It only serves to demonstrate that there is no special connectivity needed between PE routers other than basic IPv6 connectivity.
The underlay within the provider network uses IS-IS between unnumbered ethernet interfaces, relying on IPv6 link-local. There are no addresses configured at all on P3 to demonstrate this simplicity. Each PE router advertises its assigned /48 IPv6 summary into IS-IS as a means for all routers (including P3) to understand how to route traffic within these prefixes to each PE. There are no IPv4 elements within the service provider underlay network (AS65000) at all.
Between provider-edge routers, iBGP is configured with both IPv4 and IPv6 VPN address-families. This provides for the exchange of L3VPN routes for each customer using a mechanism similar to more traditional methods such as MPLS L3VPN.
Configuration
Everything discussed and demonstrated here has complete configurations as well
as the pre-configured lab for EVE-NG available on
GitHub.
The VyOS version used is a nightly build
from the end of January 2024 (VyOS 1.5-rolling-202401310023
).
Provider Routers
PE2
Configure the host name:
|
|
Interfaces
The provider network interface configuration (eth0
) is trivial. There is
nothing special needed here other than to ensure the interface is not disabled
and has a IPv6 link-local address (both defaults). The description is set
here as a standard best practice.
Additionally, a routable IPv6 loopback addresses is configured for use as a destination address for BGP sessions between PE routers.
|
|
Routing
A static IPv6 null route is configured to create a summary which encompasses all future assignments related to this router. In our case, this will cover Segment Identifiers (SIDs) represented as IPv6 addresses.
|
|
IS-IS
IS-IS is configured to provide the underlay routing for all provider routers.
This requires enabling the protocol on interfaces eth0
and lo
, setting the
device to act as a Level-2 router and configuring a Network Entity Title (NET).
|
|
Additionally, we redistribute the IPv6 summary we created above. This informs the intermediary P router, and other PEs, how to route traffic destined for addresses within this PE’s assigned summary (including soon to be created SRv6 SIDs).
|
|
Segment Routing
Now it is time to configure the basic system properties for Segment Routing
IPv6. Here we enable the interfaces that will receive SRv6 traffic (our provider
network interfaces). We also must define at least one prefix that can be used to
allocate Segment IDs (SIDs). This is known as the SRv6 Locator and is being
named L3VPN
. Optionally, we can also configure the
micro-sid
allocation behavior.
|
|
BGP
At this point we can now configure BGP. First, configure the autonomous system
number 65000
. Next, since there are no IPv4 addresses configured we must
supply a router ID. Note that while required to be in IPv4 format, this address
does not have to exist on any interface.
|
|
Now as a matter of practice, configure a peer-group that can be used to templatize configuration of multiple PEs. In this lab we have only one other PE neighbor, however it is being done here to more clearly show the necessary attributes for PE neighbors.
The PE
peer group configures both IPv4 VPN and IPv6 VPN address families which
provides the mechanism to exchange IPv4 and IPv6 customer (VRF) routes between
PE routers. In this scenario we are using iBGP between PE routers and configure
the peers to match the “internal” ASN (65000
) we configured above.
|
|
Next we need to configure the IPv6 nexthop capability. RFC 8950 describes this mechanism as a way to encode an IPv6 address as a next-hop for IPv4 destinations. This is required in order for the L3VPN to function in Linux for customer IPv4 prefixes. As we will see later, customer IPv4 routes will be destined to the exit PE’s IPv6 address along with an assigned IPv6 SID.
|
|
We can now configure the PE4
router as a member of the PE
peer-group.
|
|
The last step for now is to configure the SRv6 locator that BGP should use to
generate SIDs. Here we configure the locator named L3VPN
we created
previously.
|
|
Customer Configuration
VRF
First define a VRF to contain the customer’s routes (CE1). This lab uses the
name VRF1
. Linux also requires a table ID to identify the routing table:
|
|
Interfaces
Next configure the interface connected to CE1 and place it into the VRF:
|
|
BGP
In this lab, the CE routers have the ability to advertise any additional private customer routes that need to be shared between locations. To accomplish this, eBGP is configured with in the VRF.
First set a router-id
and system-as
for the VRF’s BGP instance:
|
|
Next, configure both IPv4 and IPv6 address families. For the purposes of this lab, configure redistribution of connected routes.
|
|
Now configure a peer-group (CE
) to define the BGP peering configuration for
our CE routers. Here we enable both IPv4 and IPv6 unicast addresses families and
instruct the group to be an eBGP session. In this example, any AS that does not
match our system-as
will be accepted, using the external
keyword.
|
|
Once the peer-group is defined, we can now add CE1
as a neighbor.
|
|
BGP VPN
There are additional parameters we need to configure to identify, export and import customer routes between VRF1 and the global BGP IPv4/IPv6 VPN table.
First is the route distinguisher.
It uniquely identifies a route within the global IPv4 and IPv6 VPN tables and
allows for address overlapping within multiple VRFs. In this case we are
using <ROUTER_ID>:<TABLE_ID>
as a scheme. It needs to be configured on both
IPv4 and IPv6 address families inside VRF1
.
|
|
Next we need to define route targets. These extended communities are used to identify which routes to import from the global IPv4/IPv6 VPN tables and how to mark routes being sent to the global IPv4/IPv6 VPN tables respectively.
|
|
A shortcut option both
does exist. Instead of the above the same can be
accomplished using:
|
|
We can now instruct FRR to perform importing and exporting routes to the global IPv4/IPv6 VPN tables:
|
|
Finally, SRv6 is configured for the VRF. Set the SID creation option to
per-vrf
, creating a unique SID per VRF. The export '101'
statement assigns
a specific allocation index within the locator prefix for this VRF.
|
|
When using a specific index we can predict a resulting SID. In this case 101
is represented as 65
in hexadecimal and produces the SID:
2001:db8:2:aaa:65::/128
Automatic allocation indexing is also an option. Use the following instead of a specific index number:
|
|
Prior to VyOS 1.5-rolling-202402080022
a reboot is required. This was
necessary to ensure that the net.vrf.strict_mode
parameter gets set to 1
.
See the caveat details below.
PE Caveat
UPDATE: This has been resolved as of VyOS 1.5-rolling-202402080022
via
VyOS#2952. The workaround mentioned
here is no longer necessary on newer versions.
VyOS PRs #2663 and
#2877 attempt to set the kernel
parameter net.vrf.strict_mode=1
automatically for you. This parameter is
required for SRv6 to function and must be set on both PE routers. After initial
configuration a reboot is required in order for this to take effect.
However, after restarting, it does not appear to get correctly set:
|
|
This means FRR is unable to install SRv6 SIDs into the Linux kernel routing table:
|
|
Notice the above prefix shows a r
(rejected) status. The following log entries
confirm the issue installing into kernel:
|
|
WORKAROUND: I have observed that manually setting this parameter in the configuration (committing and saving) and rebooting again resolves this issue:
|
|
Be sure the other changes are committed before attempting to apply this
parameter. Otherwise you may experience a Invalid value
error.
After one last reboot, the SID appears to have been programmed correctly:
|
|
P3
The P router (P3
) requires very minimal configuration. The only requirement
is to enable IS-IS on both ethernet interfaces and optionally set a few
descriptions.
|
|
Interfaces
|
|
IS-IS
|
|
PE4
PE4
is configured identically to PE2. A complete configuration can be
found on
GitHub
and specific differences are highlighted below below:
|
|
Interfaces
|
|
Routing
|
|
IS-IS
|
|
Segment Routing
|
|
BGP
|
|
Customer Configuration
Interfaces
|
|
BGP
|
|
BGP VPN
|
|
Customer Routers
CE routers only require basic configuration. Substitute addresses and values for each router according to the topology diagram:
|
|
Interfaces
|
|
BGP
|
|
Verification
The following can be used to validate the control plane in each PE router.
SRv6 SIDs
Verify a SRv6 End.DT46
SID has been created for VRF1 (table 101
):
|
|
More information about SR Endpoint behaviors can be found in RFC 8986
BGP
IPv4: VPN
Validate routes are in the global IPv4 VPN table:
|
|
IPv6: VPN
Validate routes are in the global IPv6 VPN table:
|
|
IPv4: VRF1
Validate IPv4 routes are received from the CE and are imported into the VRF from other PEs:
|
|
IPv6: VRF1
Validate IPv6 routes are received from the CE and are imported into the VRF from other PEs:
|
|
Routing Tables
Verify routes are installed into the Linux kernel for the VRF routing table:
IPv4
|
|
IPv6
|
|
End-to-End connectivity
Caveat
Before any L3VPN traffic will route properly, traffic must be sent sourced from either PE to the other PE, within the VRF at least once. This must be performed specifically between VRF-member interfaces on PEs.
For example, a ping between PE2’s eth1
interface and PE4’s eth1
interface:
|
|
This only needs to be performed once (unless rebooted) and can be completed on either address family. It does not require this action on both families in order for both IPv4 and IPv6 VRF traffic to work. Once completed, all further traffic works as expected.
This is a particularly odd behavior that appears to have something to do with routing within the Linux kernel. Using dropwatch on the inbound PE and collecting dropped packets from CE1 to CE5 (on PE2) I observed the following:
|
|
The input port (ifindex: 7
) matches the VRF1
interface. The drop reason
listed, IP_INNOROUTES,
corresponds to a network unreachable error.
These drops are no longer observed after a successful ping between PE2 and PE4’s
eth1
interfaces as shown above.
IPv4
Ping from CE1 to CE5
|
|
The packet capture below shows the traffic above collected on PE2’s eth0
interface. This is the interface from PE2 into the provider network facing P3
.
Notice the IPv4 traffic is encapsulated into IPv6 with a destination address
of the End.DT46
SID allocated for VRF1
(table 101
) on PE4.
IPv6
Ping from CE1 to CE5
|
|
This packet capture again shows the traffic above collected on PE2, eth0
.
Similarly to IPv4 test above, notice the traffic is encapsulated with the same
destination address representing the End.DT46
SID allocated for
VRF1
(table 101
) on PE4.
Conclusion
IPv6 as a transport mechanism for Segment Routing allows for more traditional provider topologies to be simplified significantly as long as there is basic IPv6 connectivity between customer facing routers.
In this lab we created a basic working SRv6 L3VPN network in VyOS. We walked briefly through all of the necessary components and took a peak at how to validate end-to-end connectivity. I hope this was beneficial in providing some background on Segment Routing with IPv6 and how this technology can be used to support Layer 3 VPNs.