Tip
This is the documentation for the 25.06 version. Looking for the documentation of the latest version? Have a look here.
Routing IPv4 Traffic Through Unnumbered Interfaces¶
Unnumbered interfaces can process IPv4 packets without having an IPv4 address present on the interface. Unnumbered interfaces “borrow” the IPv4 address from another interface for routing purposes. Depending on the configuration style, the borrowed address may or may not be used directly as a routing destination.
Warning
The best practice for maximum stability is to borrow an IP address from a loopback interface. Loopback interfaces will always be up and able to process traffic, where other interfaces may be down and unable to process if they lose link, for example.
Unnumbered interfaces are useful on large and complex deployments where having to allocate, assign, and otherwise manage unique transit networks for every point-to-point interface can be a significant burden.
This technique is primarily used with point-to-point tunnel interfaces, such as GRE or IPIP. While this technique can work with Ethernet interfaces, doing so involves additional complications.
Note
Though this recipe covers GRE, IPIP, and Ethernet interfaces, the GRE example will contain additional explanations and context. Read the GRE example first before looking at the other examples.
See also
Required Information¶
These tables contain general information about the two nodes involved in this unnumbered routing example.
Item |
Value |
---|---|
R1 WAN IP Address |
203.0.113.2/24 |
R1 LAN Subnet |
10.2.0.0/24 |
R1 LAN IP Address |
10.2.0.1 |
R1 Loopback Instance |
0 (loop0) |
R1 Loopback Address |
10.2.10.1/32 |
Item |
Value |
---|---|
R2 WAN IP Address |
203.0.113.30/24 |
R2 LAN Subnet |
10.30.0.0/24 |
R2 LAN IP Address |
10.30.0.1 |
R2 Loopback Instance |
0 (loop0) |
R2 Loopback Address |
10.30.10.1/32 |
GRE Example¶
This example demonstrates using a GRE tunnel between two hosts, R1 and R2, with the GRE interface being unnumbered.
Configure R1¶
First configure a loopback instance. This creates the loop0
interface where
the local routing address will reside.
r1 tnsr(config)# interface loopback routing
r1 tnsr(config-loopback)# instance 0
r1 tnsr(config-loopback)# exit
See also
Next, enable the loop0
and assign an IP address:
r1 tnsr(config)# interface loop0
r1 tnsr(config-interface)# ip address 10.2.10.1/32
r1 tnsr(config-interface)# enable
r1 tnsr(config-interface)# exit
Note
Even when repeating this example with multiple unnumbered tunnel interfaces, only this single loopback is necessary. Every unnumbered tunnel can borrow its address from this one loopback.
Create a GRE tunnel interface instance between R1 and R2:
r1 tnsr(config)# gre toremote
r1 tnsr(config-gre)# instance 0
r1 tnsr(config-gre)# source 203.0.113.2
r1 tnsr(config-gre)# destination 203.0.113.30
r1 tnsr(config-gre)# exit
See also
Enable the GRE interface and configure it as unnumbered, borrowing from the
loop0
interface:
r1 tnsr(config)# interface gre0
r1 tnsr(config-interface)# ip unnumbered loop0
r1 tnsr(config-interface)# enable
r1 tnsr(config-interface)# exit
This is an optional route to the remote loopback address. This can be used for diagnostic purposes, but is generally unnecessary.
r1 tnsr(config)# route table default
r1 tnsr(config-route-table)# route 10.30.10.1/32
r1 tnsr(config-rttbl4-next-hop)# next-hop 0 via 0.0.0.0 gre0
r1 tnsr(config-rttbl4-next-hop)# exit
r1 tnsr(config-route-table)# exit
Note
The via 0.0.0.0
indicates that the interface itself is the destination,
in this case gre0
. This tells the dataplane to send traffic for this
destination through this interface without a specific destination address.
See also
Finally, add a route to the remote LAN subnet at R2 using the same interface route method:
r1 tnsr(config)# route table default
r1 tnsr(config-route-table)# route 10.30.0.0/24
r1 tnsr(config-rttbl4-next-hop)# next-hop 0 via 0.0.0.0 gre0
r1 tnsr(config-rttbl4-next-hop)# exit
r1 tnsr(config-route-table)# exit
Configure R2¶
On the other router the procedure is the same, but substituting the relevant parameters along the way.
Create the R2 loopback instance:
r2 tnsr(config)# interface loopback routing
r2 tnsr(config-loopback)# instance 0
r2 tnsr(config-loopback)# exit
Enable and configure the R2 loopback interface:
r2 tnsr(config)# interface loop0
r2 tnsr(config-interface)# ip address 10.30.10.1/32
r2 tnsr(config-interface)# enable
r2 tnsr(config-interface)# exit
Create the GRE interface from R2 to R1:
r2 tnsr(config)# gre tohq
r2 tnsr(config-gre)# instance 0
r2 tnsr(config-gre)# source 203.0.113.30
r2 tnsr(config-gre)# destination 203.0.113.2
r2 tnsr(config-gre)# exit
Enable and configure the R2 GRE interface as unnumbered, borrowing from
loop0
:
r2 tnsr(config)# interface gre0
r2 tnsr(config-interface)# ip unnumbered loop0
r2 tnsr(config-interface)# enable
r2 tnsr(config-interface)# exit
Optionally add a route to the R1 loopback through gre0
:
r2 tnsr(config)# route table default
r2 tnsr(config-route-table)# route 10.2.10.1/32
r2 tnsr(config-rttbl4-next-hop)# next-hop 0 via 0.0.0.0 gre0
r2 tnsr(config-rttbl4-next-hop)# exit
r2 tnsr(config-route-table)# exit
Add a route to the R1 LAN subnet through gre0
:
r2 tnsr(config)# route table default
r2 tnsr(config-route-table)# route 10.2.0.0/24
r2 tnsr(config-rttbl4-next-hop)# next-hop 0 via 0.0.0.0 gre0
r2 tnsr(config-rttbl4-next-hop)# exit
r2 tnsr(config-route-table)# exit
Testing¶
With a GRE tunnel interface, testing can be performed from the TNSR CLI, a dataplane shell or VPP. The TNSR CLI is the easiest method.
First, from R1, try a ping from the R1 LAN IP address to the R2 LAN IP address:
r1 tnsr(config)# dataplane ping 10.30.0.1 source 10.2.0.1 count 3
PING 10.30.0.1 (10.30.0.1) from 10.2.0.1 : 56(84) bytes of data.
64 bytes from 10.30.0.1: icmp_seq=1 ttl=64 time=0.175 ms
64 bytes from 10.30.0.1: icmp_seq=2 ttl=64 time=0.125 ms
64 bytes from 10.30.0.1: icmp_seq=3 ttl=64 time=0.125 ms
--- 10.30.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2077ms
rtt min/avg/max/mdev = 0.125/0.141/0.175/0.023 ms
Then, from R2, try a ping from the R2 LAN IP address to the R1 LAN IP address:
r2 tnsr(config)# dataplane ping 10.2.0.1 source 10.30.0.1 count 3
PING 10.2.0.1 (10.2.0.1) from 10.30.0.1 : 56(84) bytes of data.
64 bytes from 10.2.0.1: icmp_seq=1 ttl=64 time=0.208 ms
64 bytes from 10.2.0.1: icmp_seq=2 ttl=64 time=0.120 ms
64 bytes from 10.2.0.1: icmp_seq=3 ttl=64 time=0.117 ms
--- 10.2.0.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2073ms
rtt min/avg/max/mdev = 0.117/0.148/0.208/0.042 ms
If both pings were successful, there is now two-way routing connectivity between the R1 LAN and R2 LAN. Add more routes as needed.
To add more routers, R1 only needs additional GRE tunnels and routes.
IPIP Example¶
Configuring the same style of setup with IPIP is nearly identical to the GRE example. Refer to that recipe for more detail on each step.
Configure R1¶
Create the R1 loopback instance:
r1 tnsr(config)# interface loopback routing
r1 tnsr(config-loopback)# instance 0
r1 tnsr(config-loopback)# exit
Enable and configure the R1 loopback interface IP address:
r1 tnsr(config)# interface loop0
r1 tnsr(config-interface)# ip address 10.2.10.1/32
r1 tnsr(config-interface)# enable
r1 tnsr(config-interface)# exit
Create a new IPIP tunnel interface between R1 and R2. This example creates
ipip10
:
r1 tnsr(config)# tunnel ipip 10
r1 tnsr(config-ipip)# source ipv4 address 203.0.113.2
r1 tnsr(config-ipip)# destination ipv4 address 203.0.113.30
r1 tnsr(config-ipip)# exit
Next enable the R1 ipip10
interface and configure it as unnumbered,
borrowing its IP address from loop0
:
r1 tnsr(config)# interface ipip10
r1 tnsr(config-interface)# ip unnumbered loop0
r1 tnsr(config-interface)# enable
r1 tnsr(config-interface)# exit
Create a route to the R2 LAN subnet using the ipip10
interface as the
destination:
r1 tnsr(config)# route table default
r1 tnsr(config-route-table)# route 10.30.0.0/24
r1 tnsr(config-rttbl4-next-hop)# next-hop 0 via 0.0.0.0 ipip10
r1 tnsr(config-rttbl4-next-hop)# exit
r1 tnsr(config-route-table)# exit
Configure R2¶
Create the R2 loopback instance:
r2 tnsr(config)# interface loopback routing
r2 tnsr(config-loopback)# instance 0
r2 tnsr(config-loopback)# exit
Enable and configure the R2 loopback interface IP address:
r2 tnsr(config)# interface loop0
r2 tnsr(config-interface)# ip address 10.30.10.1/32
r2 tnsr(config-interface)# enable
r2 tnsr(config-interface)# exit
Create a new IPIP tunnel interface between R2 and R1. This example creates
ipip10
:
r2 tnsr(config)# tunnel ipip 10
r2 tnsr(config-ipip)# source ipv4 address 203.0.113.30
r2 tnsr(config-ipip)# destination ipv4 address 203.0.113.2
r2 tnsr(config-ipip)# exit
Next enable the R2 ipip10
interface and configure it as unnumbered,
borrowing its IP address from loop0
:
r2 tnsr(config)# interface ipip10
r2 tnsr(config-interface)# ip unnumbered loop0
r2 tnsr(config-interface)# enable
r2 tnsr(config-interface)# exit
Create a route to the R1 LAN subnet using the ipip10
interface as the
destination:
r2 tnsr(config)# route table default
r2 tnsr(config-route-table)# route 10.2.0.0/24
r2 tnsr(config-rttbl4-next-hop)# next-hop 0 via 0.0.0.0 ipip10
r2 tnsr(config-rttbl4-next-hop)# exit
r2 tnsr(config-route-table)# exit
Testing¶
Testing the IPIP configuration works identically to testing in the GRE example. Try a ping from each router using the TNSR CLI. Refer to the GRE example testing section for more details.
Ethernet Example¶
Typically Ethernet interfaces are not point-to-point connections so there is ambiguity when determining how TNSR delivers packets to the peer. If the interface is cross-connected or only has one possible destination, it is still viable.
Using unnumbered Ethernet interfaces requires using routes with the
dataplane-only
property, which makes it harder to test. The ping
command
in TNSR relies on routes in the operating system which are not present with
dataplane-only
routes.
See also
While some aspects of this example are much different, refer to the GRE example for more details on the setup in general.
Configure R1¶
Create the R1 loopback instance:
r1 tnsr(config)# interface loopback routing
r1 tnsr(config-loopback)# instance 0
r1 tnsr(config-loopback)# exit
Enable and configure the R1 loopback interface IP address:
r1 tnsr(config)# interface loop0
r1 tnsr(config-interface)# ip address 10.2.10.1/32
r1 tnsr(config-interface)# enable
r1 tnsr(config-interface)# exit
Enable the directly connected link interface and configure it as unnumbered,
borrowing its address from loop0
:
r1 tnsr(config)# interface CCLINK
r1 tnsr(config-interface)# ip unnumbered loop0
r1 tnsr(config-interface)# enable
r1 tnsr(config-interface)# exit
Create a route to the R2 LAN subnet using the dataplane-only
property and
using both the R2 loopback IP address and the directly connected link interface
as the destination:
r1 tnsr(config)# route table default
r1 tnsr(config-route-table)# route 10.30.0.0/24
r1 tnsr(config-rttbl4-next-hop)# dataplane-only
r1 tnsr(config-rttbl4-next-hop)# next-hop 0 via 10.30.10.1 CCLINK
r1 tnsr(config-rttbl4-next-hop)# exit
r1 tnsr(config-route-table)# exit
See also
Configure R2¶
Create the R2 loopback instance:
r2 tnsr(config)# interface loopback routing
r2 tnsr(config-loopback)# instance 0
r2 tnsr(config-loopback)# exit
Enable and configure the R2 loopback interface IP address:
r2 tnsr(config)# interface loop0
r2 tnsr(config-interface)# ip address 10.30.10.1/32
r2 tnsr(config-interface)# enable
r2 tnsr(config-interface)# exit
Enable the directly connected link interface and configure it as unnumbered,
borrowing its address from loop0
:
r2 tnsr(config)# interface CCLINK
r2 tnsr(config-interface)# ip unnumbered loop0
r2 tnsr(config-interface)# enable
r2 tnsr(config-interface)# exit
Create a route to the R1 LAN subnet using the dataplane-only
property and
using both the R1 loopback IP address and the directly connected link interface
as the destination:
r2 tnsr(config)# route table default
r2 tnsr(config-route-table)# route 10.2.0.0/24
r2 tnsr(config-rttbl4-next-hop)# next-hop 0 via 10.2.10.1 CCLINK
r2 tnsr(config-rttbl4-next-hop)# dataplane-only
r2 tnsr(config-rttbl4-next-hop)# exit
r2 tnsr(config-route-table)# exit
Testing¶
This type of routing will not work from the TNSR OS even using the dataplane
namespace. As such, it cannot work with ping
from the shell or even the TNSR
CLI.
To test this type of routing, use the dataplane itself (VPP) to send a ping
(sudo vppctl ping x.x.x.x source LAN
) or ping from host to host within the
target networks.
Test from R1 using the dataplane:
r1 tnsr(config)# dataplane shell sudo vppctl ping 10.30.0.1 source LAN
116 bytes from 10.30.0.1: icmp_seq=1 ttl=64 time=.1013 ms
116 bytes from 10.30.0.1: icmp_seq=2 ttl=64 time=.0776 ms
116 bytes from 10.30.0.1: icmp_seq=3 ttl=64 time=.0782 ms
116 bytes from 10.30.0.1: icmp_seq=4 ttl=64 time=.0772 ms
116 bytes from 10.30.0.1: icmp_seq=5 ttl=64 time=.0779 ms
Test from R2 using the dataplane:
r2 tnsr(config)# dataplane shell sudo vppctl ping 10.2.0.1 source LAN
116 bytes from 10.2.0.1: icmp_seq=1 ttl=64 time=.0964 ms
116 bytes from 10.2.0.1: icmp_seq=2 ttl=64 time=.0782 ms
116 bytes from 10.2.0.1: icmp_seq=3 ttl=64 time=.0779 ms
116 bytes from 10.2.0.1: icmp_seq=4 ttl=64 time=.0782 ms
116 bytes from 10.2.0.1: icmp_seq=5 ttl=64 time=.0782 ms
Statistics: 5 sent, 5 received, 0% packet loss