IPv6 Segment Routing

Ronald van der Pol
Mon, Jan 13, 2020 - 1762 Words - 9 minutes
Categories: networking

Segment routing is a form of source routing in which a node that originates a packet (the headend node), adds an ordered list of segments (or instructions) to that packet. Such an ordered list is called a segment routing (SR) policy. These segments tell the routers along the path how that packet should be forwarded. Only the headend node to a segment routing domain maintains per flow state. There is no per flow state inside the network.

Segments have an identifier, the Segment Identifier (SID). Segments can be topological or service based. Examples of topological segments are:

Examples of service segments are:

The segment routing architecture is described in RFC 8402. It describes two data planes for segment routing: MPLS based (SR-MPLS) and IPv6 based (SRv6). In SR-MPLS (RFC 8660) the segment list corresponds to an MPLS stack and each segment is encoded as an MPLS label. SR-MPLS is being rolled out in the SURFnet8 network. In SRv6 the segment list is encoded in an extension header, the Segment Routing Header. Each segment is encoded as a 128-bit IPv6 address. An IPv6 address needs to be explicitly configured to be used as a SID. The remainder of this chapter describes IPv6 Segment Routing in more detail.

In SRv6, a node that acts as the headend of a segment routing domain encapsulates the original packet with an outer IPv6 header that contains a Segment Routing Header (SRH). The node adds segments to the SRH and by doing so determines how the packet is routed through the network and which services will act on the packet. The IPv6 Segment Routing Header is being defined in the IETF 6MAN working group as draft-ietf-6man-segment-routing-header and is shown below:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Next Header   |  Hdr Ext Len  | Routing Type  | Segments Left |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Last Entry   |     Flags     |              Tag              |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|            Segment List[0] (128 bits IPv6 address)            |
|                                                               |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|                                                               |
                              ...
|                                                               |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
|            Segment List[n] (128 bits IPv6 address)            |
|                                                               |
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
//                                                             //
//         Optional Type Length Value objects (variable)       //
//                                                             //
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The “Segment List” is encoded in this header as an ordered list of IPv6 addresses. The currently active segment is always copied to the IPv6 destination address of the outer header of the packet. A “Segments Left” field in the SRH points to the next segment.

SRv6 Packet Processing

The headend node of a segment routing domain adds the encapsulating IPv6 header and the SRH to the packet, copies the active segment to the destination address, and sends the packet to that address according to its FIB. A node along a segment routing path examines the destination address. If the node does not have a segment that corresponds to that address, the packet is forwarded as a normal IPv6 packet. If the address corresponds to a segment of that node, an appropriate action is taken, the segment (address) pointed to by the “Segments Left” field is copied to the destination address field, and the “Segments Left” field is decremented. If a segment routing enabled node receives a packet in which the “Segments Left” field is zero, the packet is just forwarded as a normal IPv6 packet.

This shows the pseudo code that describes the forwarding process of a node:

S01. When an SRH is processed {
S02.   If Segments Left is equal to zero {
S03.     Proceed to process the next header in the packet,
         whose type is identified by the Next Header field in
         the Routing header.
S04.   }
S05.   Else {
S06.     If local configuration requires TLV processing {
S07.       Perform TLV processing (see TLV Processing)
S08.     }
S09.     max_last_entry  =  ( Hdr Ext Len /  2 ) - 1
S10.     If  ((Last Entry > max_last_entry) or
S11.          (Segments Left is greater than (Last Entry+1)) {
S12.       Send an ICMP Parameter Problem, Code 0, message to
           the Source Address, pointing to the Segments Left
           field, and discard the packet.
S13.     }
S14.     Else {
S15.       Decrement Segments Left by 1.
S16.       Copy Segment List[Segments Left] from the SRH to the
           destination address of the IPv6 header.
S17.       If the IPv6 Hop Limit is less than or equal to 1 {
S18.         Send an ICMP Time Exceeded -- Hop Limit Exceeded in
             Transit message to the Source Address and discard
             the packet.
S19.       }
S20.       Else {
S21.         Decrement the Hop Limit by 1
S22.         Resubmit the packet to the IPv6 module for transmission
             to the new destination.
S23.       }
S24.     }
S25.   }
S26. }

SRv6 Network Programming

More elaborate forwarding behaviour is being defined in the SPRING working group draft: draft-ietf-spring-srv6-network-programming. Examples are the decapsulation of the outer IPv6 and SRH headers and:

There is also the concept of a “Binding SID” for inter domain stitching. The Binding SID can be used for traffic-engineering policies across multiple domains. In such a case, an SRv6 headend node can include one or more binding SIDs in its segment list. Binding SIDs are used to forward a packet to a next domain and tell that next domain which SR policy it needs to apply to the packet. The headend node chooses one of the binding SIDs that correspond to one of the SR policies that the next domain supports. If domains further along the path also support SRv6 and binding SIDs, the headend node can choose to include their binding SIDs in the segment list too.

A domain that supports binding SIDs and receives a SRv6 packet from another domain does the following. Each binding SID is associated with an SR policy B and an IPv6 source address A. The node that applies the policy encapsulates the packet with an IPv6 header and an SRH. It fills the segment list in its SRH with segments corresponding to the SR policy. The IPv6 sources address of the outer IPv6 header is set to A.

This shows the pseudo code for this handling of binding SIDs:

S01. When an SRH is processed {
S02.   If (Segments Left == 0) {
S03.      Send an ICMP Parameter Problem message to the Source Address
             Code 4 (SR Upper-layer Header Error),
             Pointer set to the offset of the upper-layer header.
             Interrupt packet processing and discard the packet.
S04.   }
S05.   If (IPv6 Hop Limit <= 1) {
S06.       Send an ICMP Time Exceeded message to the Source Address,
             Code 0 (Hop limit exceeded in transit),
             Interrupt packet processing and discard the packet.
S07.   }
S08.   max_LE = (Hdr Ext Len / 2) - 1
S09.   If ((Last Entry > max_LE) or (Segments Left > (Last Entry+1)) {
S10.      Send an ICMP Parameter Problem to the Source Address,
             Code 0 (Erroneous header field encountered),
             Pointer set to the Segments Left field.
             Interrupt packet processing and discard the packet.
S11.   }
S12.   Decrement Hop Limit by 1
S13.   Decrement Segments Left by 1
S14.   Push a new IPv6 header with its own SRH containing B
S15.   Set the outer IPv6 SA to A
S16.   Set the outer IPv6 DA to the first SID of B
S17.   Set the outer PayloadLength, Traffic Class, FlowLabel and
          Next-Header fields
S18.   Submit the packet to the egress IPv6 FIB lookup and
          transmission to the new destination
S19. }

Segment Routing Mapped to IPv6

Segments in SRv6 are 128-bit IPv6 addresses. When there is a large segment list the overhead of the SRH with respect to the payload can become big. Some, including Juniper, have a problem with that and have come up with an alternative architecture: segment routing mapped to IPv6 (SRm6). Proponents of SRm6 stress that it is optimised for ASIC-based forwarding at high data rates. In January 2020 there is still a heated debate between proponents of SRv6 and those of SRm6. SRm6 is defined in the (currently personal) draft: draft-bonica-spring-sr-mapped-six. Ron Bonica is a Juniper employee.

SRm6 uses a different routing header than is used for SRv6, the Compressed Routing Header (CRH). There are actually two flavours, CRH-16 with 16-bit length segments and CRH-32 with 32-bit length segments. These headers are defined in draft-bonica-6man-comp-rtg-hdr and are shown below:

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Next Header  |  Hdr Ext Len  | Routing Type  | Segments Left |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |             SID[0]            |          SID[1]               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
   |                          .........
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-


   0                   1                   2                   3
   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  |  Next Header  |  Hdr Ext Len  | Routing Type  | Segments Left |
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  +                             SID[0]                            +
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  +                             SID[1]                            +
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  //                                                              //
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
  +                             SID[n]                            +
  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Compared to the SRH, there are no Last Entry, Flags, or Tag fields. The Last Entry is not needed in SRm6 because there is no variable option data. So, the Header Extension Length and the Routing Type determine how many SIDs are present. SRm6 defines three segment types (adjacency, node, and binding) and two service instruction types (per-segment and per-path). SRm6 nodes have an additional level of indirection compared to SRv6 nodes. A SID is not just an IPv6 address, but it is a lookup key in a table with additional information, such as segment type, and the IPv6 address to be used as destination address in the outer IPv6 header. For an adjacency segment type there is also an interface identifier. For a binding segment type there is a SID list length and a SID list.