MPLS Segment Routing, Part 1: The Theory (Beginner’s Guide)

Do you ever stop to think about how an MPLS label is really an instruction? An instruction to the receiving router, to perform some kind of forwarding action with the packet it has received? Do you ever think about that?

Well, I don’t. I NEVER think about it. Do I look like a nerd? No. No I do NOT look like a nerd. I’m a jock. I’m a sports jock that never thinks about things like how MPLS labels are like an instruction. Have you really come to my blog, my sacred website, just to accuse me of being the kind of person who spends his time thinking about how MPLS labels are like an instruction? This is an outrage. I’m going to sue to you, there’s no doubt about it. I’ve spent literal decades building up my jock persona, only for you to ruin it within ten seconds. You’re going to pay, and pay very heavily indeed.

But hey, forget I said any of that: this post is a beginner’s guide to MPLS segment routing. Nice!

You can use segment routing for similar reasons that you would use LDP and RSVP – to create label-switched paths. However, the way that segment routing goes about making those paths is very different! And over these next two posts, I’m going to teach you the high points of it all.

In this introductory post I’ll to show you some of the basic theory, where you’re going to learn all about how an MPLS label is really like a kind of instruction. This is a concept that I think about a lot. And I mean a LOT.

Then in Part 2 (which you can read here when you’re ready) I’ll show you how you can easily use segment routing as a replacement for LDP, for shortest-path routing. You’ll see both the config and the verification steps, and I get a feeling that you’re going to like what you see! By the end of it all, I’m pretty sure you’ll be itching to turn off LDP, and turn on segment routing.

You’ll need some baseline MPLS knowledge to understand these two posts, but I’ll do my best to bring you along for the journey no matter what your current level of understanding. Time to dive deep into some very cool tech!



Sorry for using swear words in that sub-title there.

Segment routing can be used to create MPLS label-switched paths (LSPs) between two routers. You know: the kind of LSPs that let you do things like a BGP-free core, and MPLS VPNs.

Segment routing is also sometimes called SPRING, which stands for Source Packet Routing In Networking. The “source routing” refers to the fact that the source router (which really means the ingress router to an LSP) decides the end-to-end path.

Just like RSVP, you can make specific traffic-engineered LSPs. Just like LDP, you can make shortest-path LSPs. And just like both, you can create backup “local repair” paths that can be used immediately in times of link or node failure.

One thing segment routing can’t do is bandwidth reservations. However, if you use an external controller to build your LSPs, then this controller can do the bandwidth reservations in its own memory, and make sure that LSPs are rerouted when needed.

Okay, fine. But how is using segment routing different to using LDP or RSVP?



There’s a few answers to that, and perhaps the best place to start is to say that segment routing isn’t a protocol in the same way that RSVP or LDP are protocols. There is no “segment routing protocol” that two routers talk to each other to exchange MPLS labels.

Instead, the labels are advertised directly inside IS-IS or OSPF!

To be more precise, sometimes it’s a label, and sometimes it’s a number that is used as the basis of calculating a label. More on that later.

In any case, IS-IS/OSPF take care of advertising all of this info, so that every router either knows or can calculate exactly what label every other router expects to receive, in order to forward traffic in a certain direction, or toward some end destination. When you read Part 2 you’ll peak inside the IS-IS database (because it’s so much easier to read than the OSPF database) and you’ll see exactly what this looks like.

Already this is excellent, because it means you have one less protocol to run. As soon as OSPF or IS-IS are up, your label-switched paths are also up.



Another big difference is how segment routing creates its LSPs in the first place. The way that traffic engineering works is different to RSVP, and the way that shortest path routing works is different to LDP!

Let’s start with shortest path routing. Just like LDP, there is one transport label which is “swapped” hop by hop, and popped by the penultimate router.

The difference in segment routing is that it’s possible to configure things in such a way that the exact same transport label is used at every hop! You will soon see how this works—but for now it’s enough to say that a) you reserve a block of labels on each router specifically for this purpose, and b) that most people reserve the same block on each router.

(Don’t worry—choosing the block to reserve is much easier than it sounds, and I’ll talk you through it in Part 2.)

As for traffic-engineered paths, even this works differently, because LSPs are not signaled like they are in RSVP. After all, there is no segment routing protocol. All of this information is advertised in IS-IS (the correct choice) or OSPF (the coward’s protocol).

If there is no signaling like in RSVP, then how are traffic-engineered paths made?

Segment routing is able to use the topology information in IS-IS/OSPF, inspect the label information associated with each piece of the topology, and use this to push an entire stack of labels onto a packet, such that the ingress router knows exactly which label each hop along the way expects to receive, if traffic is to be forwarded in a certain direction!

Each hop will receive a packet with a stack of labels, inspect the top label, work out what to do with the packet, pop that label, and forward the packet to the next router, for the process to happen all over again.

If you can’t visualise that, then “hold” your “horses”, because in a moment I’ll show you exactly what it looks like. Wow, I’m so good and nice to you! Wow.



See those “pieces” of the topology that have labels associated with them? Those are the “segments” in segment routing.

Now, you’re probably familiar with the concept of “segments” thanks to your history of eating oranges. However, this post has nothing to do with oranges. It’s actually a distraction that you brought up oranges in the first place, and I think you owe me an apology for wasting my time there.

Each segment in the network is given a “Segment ID” or SID for short.

As it happens, almost anything can be given a Segment ID, including:

  • An entire router (or “node”)
  • A link (specifically, any link with an IS-IS/OSPF adjacency on it)
  • A individual link in a LAG bundle
  • A prefix on a router
  • A prefix that exists on two or more routers, where you’re happy for the traffic to go to whichever router is closest (cool people call this “anycast”)
  • Your parents (not true)
  • And more! (true)

All of these segments can have MPLS labels associated with them. It’s the combination of all of these SIDs, these segment IDs, that allows a router to specify a precise path for an LSP.

The stack can even include a mix of these SID types.

For example, a stack of labels may include some Node SID labels, which will just route the packet along the metrically-best path to that node, and they may also include some Adjacency SIDs (the SIDs that represent links with an adjacency on them) that will tell a hop precisely which link to forward the traffic out of.

This is a bit like how an RSVP LSP can include loose and strict hops. The strict hops have to be directly connected, but the loose hops can get there however is best.

I’m going to introduce you to the proper names of a few of the segment types you just learned about. As I introduce you to them, I’m going to reference some routers in my Famous Ten-Router Lab. What makes it famous? Oh I don’t know, how about the fact that it was voted “Most Handsome Network 2022” by none other than Good Housekeeping magazine?

You can click this pic to open it in a new tab, if you want it open for easy reference:



Segment routing refers to a router as a “node”. When you assign a Segment ID to a node, it’s called a Node SID.

A Node SID is nothing more than a number, a unique identifier. These Node SID numbers are then advertised throughout the network, so that each router knows the number, the Node SID, associated with each router.

By the way, in segment routing, one segment ID is assigned for IPv4, and another separate segment ID is assigned for IPv6. For example, a particular router might have two Node SIDs, and a particular link might also have two Adjacency SIDs too – one for IPv4, and one for IPv6.

This isn’t often made clear, and a lot of documentation often uses the phrase “Node SID” or “Adjacency SID” to really mean the IPv4 version. Be alert when you’re reading around this topic!



You use Node SIDs when you want to perform shortest path routing.

Whenever a router receives an MPLS label associated with a particular Node SID, this label is an instruction for the router to forward the traffic towards that Node SID, following the metrically-best path.

However, these Node SID numbers are not MPLS labels in themselves. Instead are the the basis for generating a label.

The idea in segment routing is that on each router in the network, you manually define a block of labels for shortest-path forwarding. Don’t worry, it’s WAY easier than it sounds, and in Part 2 I’ll show you how to choose a block of labels for production.

To define a block of labels, you state your starting label, and then the label block size. So for example, you might choose starting label 800000, and use a label block size of 9000. That gives you labels 800000 to 808999 to use for shortest path routing.

Each router is going to advertise this block of labels, and indicate to the rest of the network, “This is the block of labels that I am using for shortest path forwarding. If you want to send traffic to a particular Node SID, add the Node SID number to my starting label block, and then use that as the label number when you send the packet to me”.

Actually, I told you a little lie there: you don’t have to define a block of labels yourself. I can only talk for Junos, but you’ll see in Part 2 that if you don’t define a block of labels yourself, then Junos does it for you. But there’s a very good reason to do it manually. Let me show you why.



Imagine this, if you’re brave enough:

  • R1 has an IPv4 Node SID of 401
  • R2 has an IPv4 Node SID of 402
  • R5 has an IPv4 Node SID of 405
  • And so on. Can you guess the IPv4 Node SIDs for the rest of the routers in the topology? I’m sure you can. I’m confident in you.

Thanks to IS-IS/OSPF, every router is aware of every Node SID number in the network. Great!

But how are these Node SID numbers turned into MPLS labels?

On each router you’re going to allocate a block of MPLS labels that can be used to generate labels from these Node SIDs. For now, let’s just imagine that we’ve chosen labels 800000 to 809999. Ten thousand labels should be more than enough!

Don’t worry too much for now about how I decided that I wanted to use that specific block. Once you understand the basics, we’ll come back to it in Part 2.

Let’s pick on R2 as a random example. R2 advertises that it is using this label block in particular, via IS-IS/OSPF. Every router in the network now knows that R2 expects to receive labels in this range when traffic is to be forwarded to a particular node.

Now let’s think about R1, who wants to forward traffic to R5 down a label-switched path. R1 wants this traffic to take the shortest path, which is R1-R2-R3-R4-R5.

R1 is adjacent to R2. R1 is aware of two things:

  • R2’s label block starts at 800000
  • R5’s Node SID is 405
  • R1 uses these two pieces of information to work out that if it wants R2 to send traffic to R5 via the shortest path, it should use label 800405.

Wow! That was pretty easy right? If you can add two numbers together, then you too can become a segment routing expert.



There’s a name for this label block: it’s called the Segment Routing Global Block, or SRGB for short.

The word “global” is massively misleading. It doesn’t mean that the labels have global significance. Instead, it means that these local labels are “advertised globally”, such that every router in the network is “globally aware” of the label block that R2 is using.

It’s always helpful and fantastic when networking use highly intuitive terminology! Always a great time! Always a great time.

The interesting thing about the SRGB, the Segment Routing Global Block, is that although it is only locally significant, there is nothing stopping you from individually configuring the same label block on each router in the network.

For example, imagine that R3 also uses a label block starting at 800000. This means that when R2 receives a packet labeled with 800405, R2 forwards the packet towards R3 – and uses the same label! That’s pretty cool for troubleshooting, right?

That means that if you choose the same label block on every router, you can expect every single router to expect the same label for a particular Node SID. That’s very different to LDP, where the label is totally random at each hop. Plan your labels and Node SIDs right, and you’ll be able to look at a particular label and know exactly what it’s doing.

Funnily enough, when you look on the CLI, you’ll see that when R2 receives label 800405, it “swaps” it to label 800405 before it sends it to R3. Yep: it swaps it to the same label!



However, using the same label block everywhere isn’t mandatory.

For example, you might have a multi-vendor environment where, for some reason, certain blocks of labels are reserved. In this case, you have the freedom to use different blocks of labels on each router. You’re not restricted. Everything still works, because every router knows what label block every other router is using.

So for example, imagine that R4 is by a different vendor, and for some reason it doesn’t allow you to allocate the same block of labels. No worries: you can just choose a different block.

Let’s imagine that you choose to allocate labels starting from 400000 on R4. Here’s what would happen, from R1 to R5:

  • R1 would push label 800405 and send the packet to R2
  • R2 would swap the label to 800405 and send the packet to R3
  • R3 knows that R4 is using a different label block, so it swaps the label to 400405 before sending to R4. Same math, different starting block!
  • And then R4 does penultimate-hop popping before sending the packet to R5.

Either way, the result is shortest path forwarding. You’ve successfully replaced LDP with segment routing!

To return to the idea of manually allocating labels – you can choose pretty much any starting label you like, because when you configure SR for the first time you’re going to deactivate and reactive MPLS in order to clear out any labels currently in use. This means that you don’t need to worry about using a “reserved block” or anything. If a block is genuinely reserved, you’d get a Junos commit error, so you can just relax my guy!



When you turn on segment routing in general, Junos (and I assume other vendors too, but I’ll leave you to do that research) automatically assigns a SID to each IS-IS/OSPF adjacency. And funnily enough, it’s called an Adjacency SID!

I personally found the term “Adjacency SID” to be a bit odd when I was first learning SR, in that it was a phrase that didn’t immediately tell me what it did. Maybe that’s just my broken brain, lol. But when I realised that an Adjacency SID was basically a SID that represents an interface, then it made sense.

Once again there’s an Adjacency SID for IPv4, and another for IPv6.

To be clear, if you had five physical interfaces on a router, but only four of them were running IS-IS/OSPF, you’d end up with four Adjacency SIDs for each address family. The fifth link wouldn’t have a Segment ID by default, though you can manually configure one.

When you learned about Node SIDs, you saw that the Node SID number is used to calculate the MPLS label.

Adjacency SIDs are a bit different, because the SID itself is also the label! Your router generates a label/SID for each adjacency, and then these labels are advertised through the network via IS-IS or OSPF.

So for example, in this diagram on the left, R8 has generated IPv4 Adjacency SIDs for its three links, and these SIDs are also MPLS labels. If R8 receives a packet with a label of 24, R8 will pop that label, and then send the packet out of its interface towards R9. If it receives a packet with label 26, the label is popped and sent up to R3.

Every router does this, for each of its adjacencies – and once again, these numbers are advertised in IS-IS or OSPF. Thanks to your IGP of choice, every router in the network will know the precise label that each router expects to receive, if traffic is to be forwarded out of a particular interface. It’s thanks to this information that an ingress router is able to build that stack of labels that we mentioned earlier.

Speaking of which, you now know enough to see what the stack might look like.



Imagine that R1 wanted a packet to get to R10 via the path R1-R2-R3-R8-R9-R10.

In RSVP, R1 would have to signal this path, get every router to agree, bring the path up, and then maintain that path through some kind of refresh message, as well as each router in the path using up memory to remember that the LSP exists.

But in segment routing, R1 already knows the labels that each router expects to receive, when traffic needs to be forwarded down a specific link. R1 can just look in its IS-IS/OSPF database and find the Adjacency SID from R2 to R3, from R3 to R8, and so on, and push each of those labels onto the packet to indicate the precise path that the packet should take.

Below you can see what the final packet looks like. By the way, these MPLS labels/SID numbers come from my actual lab of ten Junos routers. In Part 2 you’ll find out how to see these numbers for yourself. For now, you’re just gonna have to #trust me that they’re real.

Goddamn that’s a nice subtle green gradient. Real nice.

Anyway, R1 would push that label stack onto the packet, then send this packet to R2, who would see label 25, pop it, and forward the packet to R3 with just a three-label stack.

R3 will receive this packet, look at the new top label of 16, pop it, and forward it to R8. R8 does the same on label 24, popping it and sending the packet to R9.

By the time it reaches R9 the packet has just one single label of 24. There is penultimate-hop popping here, because R9 will pop the final label of 24 before forwarding to R10.

You surely noticed that R8 and R9 are using the same label, but that’s fine – remember these labels are generated by the local router, and only have meaning to that router.

So then, if R1 wanted to create that precise LSP, it no longer has to “request” that the LSP be brought up, like it would in RSVP. Instead, R1 already knows everything it needs to send the traffic a specific way, thanks to the information received in IS-IS or OSPF.



You may look at that stack of labels and wonder to yourself: how exactly is this stack built? What do you, as an engineer, have to do in order to “create” that stack?

There’s three main answers to that.

If you like tedious work, you could configure manual segment routing LSPs where you explicitly define each label in the stack, by digging through the IS-IS database and working out which label to use. Great for learning the data plane; dreadful in production, for the same reasons that you wouldn’t build an entire network out of static routes. If a link goes down, then your LSP breaks. There’s also no guarantee that the labels will stay the same over reboots or IGP flaps.

More likely is that you would introduce an external controller into the mix, where you could request LSPs from Router A to Router B, and perhaps add some constraints into the mix. The controller could then program the LSPs directly into the data plane of your routers, building the stack of labels required. In this situation, you couldn’t care less what the specific labels are. You just define your intent, and then the controller works out the best path. If the network changes, this best path is dynamically changed, along with the label stack to achieve it.

The third option – much less common, much less documented, but still possible – is to make manual LSPs that don’t refer to labels directly, but just refer to the egress router, and potentially contain some traffic engineering constraints, just like you would in RSVP.

In Part 2 you’re going to learn how to easily use SR as a placement for LDP, and you’ll see that there’s no controller needed at all for this use-case. No controller, no label stack – just four lines of config, and a single label end-to-end.



One final thing!

All of this post so far has focused on using MPLS labels to create your segment-routed paths. However, there are other options available.

One such example is SRv6, which uses a stack of IPv6 addresses to route the traffic! In other words, rather than using one single IPv6 address to identify the end destination, you can instead use multiple IPv6 addresses, to define not only the specific path you want to take, but even the action that should be taken with the traffic when it reaches its destination.

This stack of addresses is contained in a special header called the SRH – the Segment Routing Header.

In this system, SRv6 is not necessarily carrying IPv6 traffic. The payload can be anything. Instead, the stack of IPv6 headers performs the same task as the stack of MPLS labels. A router receives a packet with a stack of IPv6 headers, inspects the top header, pops the top header, and forwards the traffic accordingly.

I’m going to stop talking there, because otherwise this post will be double the size. For now, just be aware that SRv6 exists.

Personally, I recommend studying SR-MPLS first, because there’s so many new features and services to know about in segment routing. As you study it, you’ll learn new terms like flex algo, BGP classful transport, the BGP color community, TI-LFA, and more. Don’t worry if you don’t know what any of those terms mean yet – you will in time. The point is that there’s a lot to learn, and you’ll give yourself an advantage by learning them using the MPLS data plane you’re familiar with.

Then, once you’ve learned those concepts, it won’t be too hard to learn them with stacks of IPv6 addresses instead of stacks of MPLS labels.



That’s a lot to take in, so don’t be shy to read this post a second time if you need to.

When you’re happy that you know the theory, click here to read Part 2 where I show you how to configure and verify segment routing in Junos as a replacement for LDP. Sweet!

If you want to be among the first to find out when I publish new posts, follow me on Twitter. I’ll always share my new stuff there, plus very regular networking nonsense.

If you fancy some more learning, take a look through my other posts. I’ve got plenty of cool new networking knowledge for you on this website, especially covering Juniper tech and service provider goodness.

It’s all free for you, although I’ll never say no to a donation. This website is 100% a non-profit endeavour, in fact it costs me money to run. I don’t mind that one bit, but it would be cool if I could break even on the web hosting, and the licenses I buy to bring you this sweet sweet content.

And hey: if you enjoyed this post, I’d love you to share it on your favourite social media platform of choice, or maybe email it directly to pals and colleagues who might enjoy it. And if you didn’t enjoy this post, then be sure to write to your local politician, and demand that I be punished by being given £5,000,000 and unlimited holidays.

There’s certainly much more to tell you about segment routing. There’s tons you can do with it, and we’ve only scratched the surface. But for now, I hope you’ve enjoyed this introduction. See you next week!

7 thoughts on “MPLS Segment Routing, Part 1: The Theory (Beginner’s Guide)

  • February 17, 2022 at 8:32 pm

    Loved your Segment Routing article – thank you so much for making nice light reading and not falling to sleep.

  • June 8, 2022 at 9:09 am

    Thanks for the segment Routing article. You made it simple and easy to understand. Excellent!

  • June 22, 2022 at 3:19 pm

    Appreciate your contribution.I’ve read some pages about SPRING in IETF documents but It’s so hard to understand.Thank you so much !

  • January 21, 2023 at 2:56 am

    no one on internet came close to your explanation of Segment routing!
    you made it super easy. will follow you on twitter
    Thank you for posting these nuggets!

    • January 21, 2023 at 4:25 pm

      Nice one 🙂 Thank you very much!

  • August 16, 2023 at 1:51 am

    I had so much fun learning SR with this article. I’m more of a security guy (and a routing&switching wanna be engineer), and honestly, I couldn’t understand SR before this post. Thanks again!


Leave a Reply

Your email address will not be published. Required fields are marked *