As of Linux 4.14, it is possible to define advanced local processing for SR-enabled packets. This processing is based on the active segment (i.e., the IPv6 destination address) and effectively implements the network programming principles defined in this IETF draft.
The built-in SRv6 support in Linux enables to process SR-enabled packets whose destination address is attached to a local
interface. Such packets go through the input path and the IPv6 extension headers processing functions. The SRH processing
function ipv6_srh_rcv()
only handles two cases. If the node is not the last segment, then the packet is forwarded
to the next segment. If the node is the last segment, then the packet continues on the input path (e.g., it is sent to a local
application or the inner packet is forwarded).
The new lightweight tunnel seg6local
enables more flexibility, through fine-grained classification and allows
to steer matching packets through an arbitrary local processing function.
Note that with this framework, segment identifiers cannot be assigned to a local interface. If an IPv6 address is both present as a non-local routing entry and as a locally assigned address, the latter will take precedence and the SRv6 programming will not work.
The latest SRv6 specifications, as well as the network programming draft, define a MyLocalSID table which contains all the segments mapped to a local function. Typically, a whole prefix is assigned to this table. When an SR node receives a packet whose destination address is part of that prefix, it is an active segment that must be processed. If no entry is found in the local SID table, the packet should be dropped. Otherwise, the packet is processed by the corresponding function.
In Linux, such a table is simply defined as an arbitrary routing table. The following commands
define the localsid table as table 100, steer the prefix fc00::/64
through this table and insert a default route
to drop all unknown active segments.
# echo 100 localsid >> /etc/iproute2/rt_tables # ip -6 rule add to fc00::/64 lookup localsid # ip -6 route add blackhole default table localsid
Note: you need to enable CONFIG_IPV6_MULTIPLE_TABLES
and CONFIG_IPV6_SUBTREES
ip -6 route add <segment> encap seg6local action <action> <params> dev <device> table localsid
The arguments are defined as follows:
segment
: active segment to match. It can be a single address or a prefix.
action
: action to perform (function to apply)
params
: parameters of the function
device
: non-loopback device
Currently, the following actions and their parameters are defined:
End
: regular SRH processing
End.X nh6 <nexthop>
: regular SRH processing and forward the resulting packet to the specified nexthop
End.T table <table>
: regular SRH processing and forward to the next-hop looked up in the specified routing table
End.DX2 oif <interface>
: decapsulate an L2 frame and forward it to the specified interface
End.DX6 nh6 <nexthop>
: if the local node is the last segment, or if no SRH is present, then decapsulate the inner IPv6 packet and forward it to the specified nexthop. If the parameter is set to ::
, then the nexthop is selected according to the local route lookup process.
End.DX4 nh4 <nexthop>
: same as above, except that the inner payload is an IPv4 packet, and the nexthop is of the IPv4 family.
End.DT6 table <table>
: decapsulate an IPv6 packet and forward it to the next-hop looked up in the specified routing table.
End.B6 srh segs <segments> [hmac <keyid>]
: insert the specified SRH immediately after the outermost IPv6 header. The original SRH is not modified. The destination address of the packet is set to the first segment of the newly inserted SRH and the packet is forwarded accordingly.
End.B6.Encaps srh segs <segments> [hmac <keyid>]
: advance the packet to the next segment (decrement the segments left value and update the DA accordingly), then encapsulate the resulting packet within an outer IPv6 header containing the specified SRH. The DA of the outer IPv6 header is set to the first segment of the specified SRH. The packet is then forwarded accordingly.