1.12.a.1 Segment Routing Introduction

Segment Routing (SR) comes in two flavors or implementations:

  • SRv6, which operates entirely in the IPv6 address space
  • SRMPLS, which uses MPLS tags

This series on Segment Routing is going to consider SRv6.

The Problem Space

What problems are we trying to solve with SRv6?

  • Traffic steering
  • Service chaining

Each of these two represents an entire class of problems.

Traffic steering is largely a network side solution that can:

  • Pull traffic along a specific path, selected for higher bandwidth, lower delay, or just about anything else.
  • Used to select how traffic exits a network—or any part of a network.

Service chaining is largely an application side solution that allows traffic to be forwarded from one service to another, allowing services to be:

  • Dynamically inserted or removed from a flow’s processing based on any sort of policy, such as the source, destination, or contents of each packet
  • Dynamically reordering processing

Service chaining assumes each packet processing service lives on a separate device—whether real or virtual—and the network is going to be used to transport packets within a flow between these devices.

Plain IPv6

One interesting thing about IPv6 is the sheer amount of address space—so much that we can be much more creative in our use of the address space than we are when using IPv4. Consider the situation shown below.

In this illustration:

  • ADD1 is assigned to SVC1
  • ADD2 is assigned to SVC2
  • E advertises ADD1 to router C
  • router C advertises ADD1 to router B
  • E advertises ADD2 to router D
  • router D advertises ADD2 to router B

Traffic then flows along the paths shown below.

  • router A forwards traffic to ADD1 towards router C based on its local routing table
  • router A forwards traffic to ADD2 towards router D based on its local routing table
  • router C forwards traffic towards E
  • router D forwards traffic towards E
  • host E internally forwards traffic to the correct service

Using just IP addresses and our control over where routes are advertised, we’ve steered traffic so it always enters on a specific interface at server E.

We can give some things names to make it easier to talk about:

  • The path traffic takes through the network to reach SV1 or SV2 is called a segment
  • Each service running on host D is given a different IPv6 address used just to reach this service. This is called a Segment Identifier or SID

Some interesting observations:

  • We are adding state to the control plane to steer traffic along specific paths. Assuming we are steering traffic to optimize something—network utilization, latency, jitter, bandwidth, etc.—this makes sense. The SOS triad tells us we must increase state to increase optimization, so this is what we should expect.
  • There is no “tunnel” here. Instead, the destination advertises multiple possible destinations, each associated with a service, class of service, etc., and the sender chooses which of the available destinations to use based on some local policy. While we can call the source the head end and the destination the tail end, there is no tunnel configuration, setup, etc.
  • Because there is no tunnel state, we can effectively set up a full mesh of “tunnels” with a minimum possible amount of additional state.
  • Because the source is choosing which SID to use, this is a form of source routing. This is why this work is being done in the source routing working group (SPRING) in the IETF.

Adding a Header

Segment routing goes beyond controlling the flow of traffic using multiple addresses by adding a header, called the Segment Routing Header, or SRH, to create a pseudo-tunnel and steer traffic through the network.

This use case is illustrated below.

In this figure:

  • Router F assigns SID1 to the [F,C] link
  • Router F assigns SID2 to the [F,D] link
  • Router F advertises SID1 and SID2 to routers C and D
  • Router C and D advertise SID1 and SID2 to router B
  • Router B has an explicit policy to route traffic destined to SID1 towards C
  • Router B has an explicit policy to route traffic destined to SID2 towards D

Suppose host A would like to send a packet to E via C:

  • The sending process on Host A creates a packet destined to E’s IP address
  • The network stack on Host A, based on a local policy, encapsulates the packet using an SRH with a destination address of SID1
  • The packet is forwarded to B
  • Router B forwards the packet to C based on a local policy
  • Router C forwards the packet to F based on the local routing table
  • Router F strips the SRH and forwards the packet based on the original IP packet’s destination address—in this case, towards E

Some observations:

  • Host A chooses the path through the network by encapsulating the packet in an SRH with SID1 as a destination address
  • SID1 and SID2 are “just IPv6 addresses” to C and D; they do not look like anything other than a standard IPv6 route in the local routing table
  • Host A must somehow know about the SIDs and their meaning
  • Routers C and D do not need to know about E’s interface address; hence traffic is tunneled from A to F

Expanding the SID

In the examples above, we’ve used the SID to represent either a path or a service. This ability to represent either is what gives segment routing its real power. Let’s look at an example where the SID’s meaning is expanded to include both.

In this figure:

  • There are two instances of a single service, SVC1, hosted on E and G
  • Router F assigns SID1 to the [F,E] link, so whatever traffic F receives with an SRH containing SID1 as its destination address, F will transmit along the [F,E] link regardless of the actual destination address
  • Router F assigns SID2 to the [F,G] link, so whatever traffic F receives with an SRH containing SID2 as its destination address, F will transmit along the [F,G] link regardless of the actual destination address
  • Router F advertises SID1 and SID2 towards C and D
  • Routers C and D advertise SID1 and SID2 towards B
  • Router B has a local policy to forward traffic destined to SID1 towards C
  • Router B has a local policy to forward traffic destined to SID2 towards D

Assume A wants to send traffic to SVC1, and chooses (based on some local configuration or policy) to send the traffic to SID1. In this case:

  • Some process on A sends a packet towards the IP address of SVC1
  • The network stack on A, based on some policy, encapsulates this packet in an SRH with a destination address of SID1
  • Host A forwards the packet to B
  • Router B receives the packet and forwards it to C based on local policy
  • Router C forwards the packet towards F based on the local routing table
  • Router F determines it needs to send the packet along the [F.E] link based on the SRH destination address
  • Router F strips the SRH and forwards the packet to E

Some observations:

  • Host A must somehow know about the relationship between SVC1, SID1, and SID2
  • Once again, C and D do not need to know about either E or G’s IP addresses; these two routers only know about the two SIDs
  • At router C and D, the SIDs appear to be plain IPv6 destinations in their routing tables

As an exercise, imagine A is not a host but a load balancer that can measure the performance of each host running SVC1. The load balancer could select the correct instance of SVC1 regardless of the destination host’s IP address.

Service Chaining

Finally, let’s separate the path from the service using service chaining.

In this case:

  • Hosts E and G run two instances of SVC1
  • Router F assigns SID1 to the [F,E] link and advertises it to C and D
  • Router F assigns SID2 to the [F,G] link and advertises it to C and D
  • Router C assigns SID3 to itself (C) and advertises to to B
  • Router D assigns SID4 to itself (D) and advertises it to F

Assume A wants to send traffic to the SVC1 instance running on E via router D. In this case:

  • Some process creates a packet destined to SVC1’s address
  • Host A’s network stack has a policy to send this packet via SRv6 towards one of the hosts running SVC1
  • Host A’s network stack
    • determines the packet should go to E via D
    • imposes an SRH with a stack of two SIDS, [SID1,SID4]
    • forwards the packet to B
  • Router B
    • examines the SRH destination, which is SID4 (the lower, or outer, SID in the stack)
    • Because SID4 is D’s address, router B forwards the packet to D
  • Router D
    • strips the outer SID from the stack because it is local to D itself
    • forwards the packet to F based on the remaining SID (SID1)
  • Router F
    • determines it should forward the packet along the [F,E] link based on the remaining SID (SID1)
    • strips the SRH and forwards the packet along [F,E]

Some observations:

  • Routers C and D assign themselves SIDs; these are called Node SIDs
  • Routers C and D (still) do not know anything about the final destination addresses (E and G), or even the service’s address (SVC1); they are forwarding based on local policy and information in the local routing table

Again, as an exercise, imagine host A is a load balancer receiving traffic from some other host, or even load balancing traffic originating from local processes.

Summary

  • SRv6 treats IPv6 addresses as destinations and identifiers
    • Identifiers can identify a service, a link, or a node
  • SRv6 uses a Segment Routing Header (SRH) to encapsulate packets so the original destination is not visible, and to steer traffic along specific paths (segments) or a set of services (service chain)
    • The SRH can contain a stack of SIDs
    • Each SID is process according to local rules by devices that recognize the SID (or have local policy to process the address in the SRH)
    • Devices that do not understand a SID (or SRv6, more broadly), treat the lowest IPv6 address in the stack as a destination, forwarding the packet to towards that destination based on local routing information

The most difficult point in understanding SRv6 is treating and IPv6 address as something other than an interface address—treating it as a service as well as a destination. This is also, however, where SRv6 derives its real power to solve a lot of different use cases.