donatas abraitis

Traffic engineering with SR-IPv6

I have always been interested in traffic engineering (TE) since I started my career in ISPs. In my career, I worked in various size of ISPs. The first was Litnet, later I joined Kauno Interneto Sistemos and the last station was Cgates. Most interesting and challenging tasks were how to steer the traffic by various conditions: latency, shortest path, clients’ needs and so on and so forth. Back to TE, I always wondered how to steer the internal traffic with minimal effort (without introducing MPLS-TE), those days were not so good as today.

Segment routing is a modern source-routing architecture that is being developed within the IETF. Traditional IP routing uses destination-based hop-by-hop forwarding. Each intermediate router decides where to forward packets using its local routing table. This table is usually computed according to a shortest-path algorithm. As such, packets traverse networks following the shortest path toward their destination. This behavior is not always optimal, as the shortest path can have undesirable properties, such as congestion.

How SR-IPv6 works?

At first, IPv6 has an additional “feature” named extension header (EH). It differs from the main header, that all the needed options are implemented in extension headers instead (like in souvenir protocol using TLVs). I don’t have any feasible evidence, but I would guess, that EH processing is cutting fast path by iterating through all the headers instead of parsing options as in IPv4. Hence, SR-IPv6 is implemented as an IPv6 extension header (SRH) too, which contains all needed data to forward packets through segments.

There are two types of “routers”: ingress node and egress node. Ingress node is a node which encapsulates the packet in an outer IPv6 header containing the SRH where original packet is left unmodified as the payload. The destination address is set to the first segment from SRH and packet is forwarded as usual (per destination), then the new destination is selected from the SRH as well and so on until no segment is left. The last segment is named egress node, which decapsulates the inner packet and forwards to its original destination.

Looks very simple and promising for traffic engineering, but it’s way hard to predict how fast vendors would implement this. Linux is already offering this implementation since kernel version 4.10.

The main structure for SRH is the following:

/*
 * SRH
 */
struct ipv6_sr_hdr {
        __u8    nexthdr;
        __u8    hdrlen;
        __u8    type;
        __u8    segments_left;
        __u8    first_segment;
        __u8    flags;
        __u16   reserved;

        struct in6_addr segments[0];
};

SRH is handled by ipv6_rthdr_rcv() which takes care about routing headers:

        if (hdr->type == IPV6_SRCRT_TYPE_4)
                return ipv6_srh_rcv(skb);

Here IPV6_SRCRT_TYPE_4 is Segment Routing with IPv6. So, according to evidence above, the first entry gate for SRH is ipv6_srh_rcv(), which does heavy lifting:

  1. WHILE SegmentsLeft > 0 THEN
  2. decrement SL:
    hdr->segments_left--;
    
  3. update the IPv6 DA with SRH[SL]:
    addr = hdr->segments + hdr->segments_left;
    ipv6_hdr(skb)->daddr = *addr;
    
  4. FIB lookup on updated DA
    ip6_route_input(skb);
    
  5. forward accordingly to the matched entry

Final cuts

I don’t work for any ISPs already almost five years, but I always try to do not fall behind this kind of awesomeness. I never gave a try for MPLS, but SR-IPv6 looks way simpler to tackle TE problems, thus it’s in my TOTRY list!