Safeguard
Supply Chain Security•

Segment Routing Explained: SR-MPLS, SRv6 and Securing Source Routing

Segment routing puts the path inside the packet as a list of SIDs. How SR-MPLS and SRv6 work, and why the SR domain edge must filter SIDs and SRH.

Safeguard Security Team
53 min read

Segment routing is source routing for operator networks: the ingress router writes the path into the packet as an ordered list of instructions called segments, and the core simply follows them without keeping per-path state. It runs on MPLS (SR-MPLS, where each segment is a label) or on IPv6 (SRv6, where each segment is an IPv6 address carried in a Segment Routing Header). It is safe only inside a trusted domain whose edges drop any outside packet aimed at its segment identifiers.

This post goes one level deeper than our explainers on MPLS, OSPF, BGP and SD-WAN versus MPLS. Those covered labels, link state flooding and path selection. This one covers what happens when the path itself moves into the packet header: the segment types, the two data planes, SR policies and Flex-Algo, why IPv6 already tried and abandoned an earlier source routing header, and the specific filters and keys that stop outsiders from steering your traffic. Every RFC number, date and field below was checked against the RFC Editor's published text on 24 October 2026.

Key takeaways

  • Segment routing (SR) was standardised by the IETF SPRING working group, chartered in October 2013. The architecture is RFC 8402, published July 2018.
  • A segment is an instruction ("go to node X by the shortest path", "leave through this link", "decapsulate into this VPN table"). A Segment Identifier (SID) names it. Prefix, node, anycast, adjacency, BGP and binding SIDs are the main types.
  • IS-IS (RFC 8667), OSPFv2 (RFC 8665) and BGP (RFC 8669, RFC 9252 and RFC 9830) carry SIDs. There is no separate label signalling protocol like LDP or RSVP-TE.
  • SR-MPLS (RFC 8660) encodes the path as a stack of 4 byte MPLS labels. A global SID is an index added to the base of the SR Global Block, so index 1 with an SRGB starting at 16000 becomes label 16001.
  • SRv6 (RFC 8754) carries 128 bit SIDs in Routing Header type 4. SRv6 network programming (RFC 8986) gives SIDs behaviours such as End, End.X, End.DT4, End.DT6 and End.DT46.
  • SR policies (RFC 9256) are identified by headend, color and endpoint and pick among candidate paths by preference. Flex-Algo (RFC 9350, algorithms 128 to 255) lets the IGP compute constrained paths itself.
  • IPv6 Type 0 routing headers were deprecated by RFC 5095 in December 2007 because they enabled remote traffic amplification (88 fold was demonstrated). SRv6 avoids repeating that only if the SR domain filters at its edge.
  • The core controls are: drop outside packets addressed to your SID block or carrying an SRH at every external interface, drop SID traffic from non infrastructure sources on every node, authenticate the IGP, BGP and controller sessions, and use the SRH HMAC TLV where hosts or less trusted nodes add headers.
  • RFC 9602 (October 2024) reserved 5f00::/16 for SRv6 SIDs, marked not globally reachable, specifically so edges can fail closed with one filter.

What is segment routing, and who standardised it?

The IETF's Source Packet Routing in Networking (SPRING) working group is the home of segment routing. Its datatracker history shows the group created in September 2013 and its charter approved on 25 October 2013. The charter describes SPRING as the home of SR over MPLS and IPv6, and asks the group to avoid changes to existing data planes that would break deployments and to reuse existing control and management protocols wherever possible.

That second instruction shaped the whole design. SR-MPLS needed no change at all to MPLS forwarding: a label is still a 20 bit value in a 4 byte label stack entry as defined in RFC 3032. SRv6 needed one new IPv6 routing header type, which the 6man working group published as RFC 8754. Everything else reuses IS-IS, OSPF, BGP and the Path Computation Element Communication Protocol (PCEP).

RFC 8402, "Segment Routing Architecture", came out in July 2018. Its first paragraph is the cleanest definition available: a node steers a packet through an SR Policy instantiated as an ordered list of instructions called segments, and SR keeps per-flow state only at the ingress nodes to the SR domain.

What problem did it solve compared with RSVP-TE and LDP?

Before SR, an MPLS network typically ran two label distribution protocols:

  • LDP (current specification RFC 5036, October 2007) hands out labels hop by hop that follow the IGP shortest path. It is simple, but it adds a second protocol that must stay synchronised with the IGP, and it cannot express "take this other path".
  • RSVP-TE (RFC 3209, December 2001) signals an explicit path, reserves bandwidth along it and installs a label at every hop. It can express any path, but every midpoint router holds state for every tunnel crossing it, and that state is kept alive by periodic refresh messages. A large mesh of tunnels means a large amount of soft state in the core.

Segment routing removes both burdens. Labels (or SIDs) are advertised once by the IGP alongside the topology, so there is no separate label protocol to synchronise. A path is just a list of SIDs the headend pushes, so midpoints hold no per-tunnel state. RFC 8402 is careful to say this is not a security change in kind: RSVP-TE already let a headend express an explicit path with a single label, and SR does the same with a binding SID. What changes is scale and where the state lives.

The trade is that the path is now in the packet. Anyone who can put a packet into the network with the right header can, in principle, choose its path. That is why every SR RFC repeats the same sentence in one form or another: SR operates within a trusted domain, and traffic must be filtered at the domain boundaries.

A dated timeline of segment routing and its ancestors

DateEventSource
January 2001MPLS label stack encoding, 20 bit labels in 4 byte entriesRFC 3032
December 2001RSVP-TE explicit path tunnelsRFC 3209
October 2007LDP specification revisedRFC 5036
December 2007IPv6 Type 0 routing header deprecated after amplification attacksRFC 5095
October 2013SPRING working group charter approvedIETF datatracker
February 2017Linux 4.10 adds IPv6 segment routing (released 19 February 2017)kernelnewbies
July 2017IPv6 specification republished as an Internet StandardRFC 8200
July 2018Segment Routing ArchitectureRFC 8402
December 2019SR-MPLS data plane, IS-IS and OSPF extensions, BGP Prefix-SID, SR-MPLS over IP, PCEP for SRRFC 8660, 8667, 8665, 8669, 8663, 8664
March 2020IPv6 Segment Routing Header (SRH)RFC 8754
February 2021SRv6 Network ProgrammingRFC 8986
August 2021BGP-LS extensions for SR; BGP egress peer engineeringRFC 9085, RFC 9087
July 2022SR Policy Architecture; BGP overlay services over SRv6RFC 9256, RFC 9252
February 2023IGP Flexible AlgorithmRFC 9350
December 2023BGP-LS extensions for SRv6RFC 9514
February 2024SR replication segment for multipoint deliveryRFC 9524
April 2024IANA allocates 5f00::/16 for SRv6 SIDsRFC 9602 (published October 2024)
July 2024PCEP extensions for SRv6RFC 9603
June 2025Compressed SRv6 segment list encodingRFC 9800
September 2025Advertising SR policies in BGP; extra segment types for BGP SR policyRFC 9830, RFC 9831

What are segments and SIDs?

A segment is an instruction. A Segment Identifier is the name that instruction has on the wire. RFC 8402 says a segment can be topological ("forward via this path") or a service ("process this packet in this VM or VRF"), and that it can have a meaning local to one node or global across the whole SR domain.

The segment types you will meet

SID typeScopeWhat it tells the networkAdvertised by
Prefix-SIDGlobalReach this prefix by the shortest path (or by a given algorithm)IS-IS, OSPF, BGP
Node-SIDGlobalA Prefix-SID for a node's loopback, so "go to router X"IS-IS, OSPF
Anycast-SIDGlobalReach the nearest of several nodes sharing the prefixIS-IS, OSPF
Adjacency SID (Adj-SID)Usually localLeave this node through this specific link, whatever the shortest path saysIS-IS, OSPF
BGP Prefix-SIDGlobalReach a BGP-learned prefixBGP (RFC 8669)
BGP peering SIDsLocalExit through this BGP peer or link (egress peer engineering)BGP-LS (RFC 9087)
Binding SID (BSID)Local to headendSteer into this SR policy, which expands into a full SID listHeadend, controller

The combination is what makes SR expressive. A list such as "Node-SID of R5, Adj-SID R5 to R7, Node-SID of R9" means: shortest path to R5, then force the R5 to R7 link, then shortest path to R9. Three entries describe a path that would have needed a full RSVP-TE explicit route object and state at every hop.

The binding SID deserves special attention from a security view. RFC 8402 notes that a complete source-routed path can be represented by a single segment. A BSID hides a whole policy behind one value, which keeps label stacks short but also means a single leaked or spoofed BSID can steer traffic into an entire engineered path.

How are SIDs distributed by IS-IS, OSPF and BGP?

SR leans on the routing protocols you already run.

IS-IS (RFC 8667, December 2019) adds a Prefix-SID sub-TLV attached to prefix reachability TLVs, Adj-SID and LAN-Adj-SID sub-TLVs attached to neighbour TLVs, and router capability sub-TLVs: SR-Capabilities (which announces the node's SRGB), SR-Algorithm (which algorithms the node supports) and the SR Local Block. Every IS-IS router floods these in its link state PDUs, so every router learns every global SID along with the topology.

OSPFv2 (RFC 8665, December 2019) does the same with opaque LSAs: a SID/Label Range TLV in the Router Information LSA for the SRGB, a Prefix SID sub-TLV in the extended prefix LSA, and Adj-SID and LAN Adj-SID sub-TLVs in the extended link LSA.

BGP carries SR information in several ways:

  • RFC 8669 defines the BGP Prefix-SID attribute, an optional transitive attribute used for SR in BGP-only fabrics such as large data centres.
  • RFC 9252 (July 2022) carries SRv6 service SIDs for L3VPN, EVPN and Internet services, which is how an SRv6 network replaces the VPN label of classic BGP/MPLS VPNs.
  • RFC 9085 (August 2021) and RFC 9514 (December 2023) export SR topology and SIDs to controllers through BGP Link State.
  • RFC 9830 (September 2025) defines how a controller advertises SR policies themselves to headends in BGP, and RFC 9831 adds segment types to that encoding.

The practical result is that the routing protocol is now also the label and SID distribution protocol. If someone can inject a false IS-IS LSP or a false BGP update, they can now inject false SIDs as well as false routes. RFC 8402 says it plainly: SR does not define any additional security mechanism in existing control plane protocols. It relies on theirs.

How does SR-MPLS encode a path as a label stack?

RFC 8660 (December 2019) specifies SR over the MPLS data plane. Nothing in MPLS forwarding changes. Three ideas carry the design.

1. The SR Global Block (SRGB). Each node reserves a range of its label space for global SIDs. A global SID is advertised not as a label but as an index. Each node turns the index into a label by adding it to the start of its own SRGB. RFC 8660 gives the formula for a multi-range SRGB and the simple case is easy: with an SRGB of 16000 to 17000, index 1 becomes label 16001.

2. Three operations. RFC 8660 maps the RFC 8402 operations onto MPLS:

  • PUSH: put one or more labels on top of the packet (the headend does this).
  • CONTINUE: swap the top label for the outgoing label, the normal MPLS swap, used while a prefix segment is still in progress.
  • NEXT: pop the top label because this segment is done, then act on what is underneath (for an Adj-SID, send the packet out of the named link).

3. Local SIDs. Adjacency SIDs and binding SIDs are usually allocated from the SR Local Block or the dynamic label range and only mean something on the node that owns them.

Worked example 1: computing the label stack

Take five routers in one IS-IS area. All use the same SRGB, 16000 to 23999, for this example. A uniform SRGB makes a prefix SID's label identical on every router.

RouterLoopbackPrefix-SID indexLabel (SRGB base 16000 + index)
R1192.0.2.1/32116001
R2192.0.2.2/32216002
R3192.0.2.3/32316003
R4192.0.2.4/32416004
R5192.0.2.5/32516005

R3 has allocated Adj-SID 24035 for its link to R5 from its local range.

The goal is to send traffic from R1 to R5, but through R3 and specifically over the R3 to R5 link, even though IS-IS prefers R1 to R2 to R4 to R5.

The headend R1 pushes the stack, top first:

  1. 16003 (Node-SID of R3)
  2. 24035 (Adj-SID R3 to R5)
  3. 16005 (Node-SID of R5), optional if the Adj-SID already lands on R5, but often kept for clarity.

Walking the packet:

  • R1 forwards on the top label 16003 along its shortest path to R3. Any transit router between them applies CONTINUE, swapping 16003 for 16003 (same SRGB, same label).
  • The router before R3 may pop 16003 under penultimate hop popping, so R3 sees 24035 on top.
  • R3 sees its own Adj-SID 24035, applies NEXT, pops it and sends the packet out of the R3 to R5 link.
  • R5 sees 16005, which is its own prefix SID, pops it and delivers the payload.

Header cost: three labels at 4 bytes each, 12 bytes. A VPN service label underneath would add 4 more. No router in the middle created any state for this path; R3 only needed the Adj-SID it had already advertised.

If R4 had used a different SRGB, say 20000 to 27999, then R1 would push 20003 when R4 was the next hop rather than 16003, because the outgoing label must be the one the receiving node expects. RFC 8660 makes that the rule. It works, but debugging becomes harder, which is why a uniform SRGB is standard practice.

SR-MPLS without MPLS in the core

RFC 8663 (December 2019) allows MPLS segment routing over an IP network by putting the label stack inside UDP or MPLS-over-IP encapsulation. It is useful for incremental deployment, but it also means label stacks can travel inside ordinary IP packets. Edge filtering therefore has to cover those encapsulations too, not just packets that arrive as MPLS frames.

How does SRv6 encode a path in the Segment Routing Header?

SRv6 puts segments into IPv6 itself. RFC 8754 (March 2020) defines the Segment Routing Header as Routing Header type 4. Its fixed part is 8 bytes:

FieldSizeMeaning
Next Header8 bitsHeader that follows the SRH
Hdr Ext Len8 bitsLength of the SRH in 8 octet units, not counting the first 8
Routing Type8 bits4
Segments Left8 bitsIndex of the next segment to visit
Last Entry8 bitsIndex of the last element of the segment list
Flags8 bitsCurrently unused, must be zero on transmission
Tag16 bitsOptional grouping of packets
Segment List[0..n]128 bits eachThe SIDs, encoded in reverse order
TLVsVariableOptional, including padding and HMAC

Two details trip people up.

First, the segment list is stored backwards. Segment List[0] is the last segment of the path, Segment List[1] the one before it, and so on. The active segment is always in the IPv6 destination address.

Second, Segments Left is the only field a normal endpoint changes. At each SR endpoint whose SID matches the destination address, the node decrements Segments Left, copies Segment List[Segments Left] into the destination address and forwards the packet. Transit routers that are not SR endpoints just route on the destination address like any IPv6 packet. RFC 8754 calls these three roles the SR source node, transit node and SR segment endpoint node.

RFC 8754 also defines a reduced SRH: when the source encapsulates, it can omit the first segment from the list because it is already in the destination address. The Linux implementation exposes this as encap.red, and its manual notes that with only one segment and no HMAC, the SRH is left out entirely.

What is SRv6 network programming?

RFC 8986 (February 2021) turned SRv6 from a path encoding into a programming model. It defines an SRv6 SID as three fields:

  • LOC, the locator: the most significant bits, routable, leading to the node that owns the SID. A locator can itself be split into B:N, a SID block allocated by the operator and a node identifier.
  • FUNCT, the function: an opaque value bound to a local behaviour.
  • ARG, the arguments: optional bits used by some behaviours.

The lengths are flexible as long as they fit in 128 bits, and RFC 8986 gives the example of assigning a /48 block to the domain and a /64 per node.

Each function is bound to a behaviour. The ones you will meet most often:

BehaviourWhat the endpoint doesTypical use
EndPlain SRv6 endpoint: decrement Segments Left, copy the next SID into the destination, forwardEquivalent of a Node-SID
End.XEnd, then forward to a specific layer 3 neighbourEquivalent of an Adj-SID
End.TEnd, then look up in a specific IPv6 tableMulti-table cores
End.DX6 / End.DX4Decapsulate and forward the inner IPv6 or IPv4 packet to a given next hopPer-CE VPN cross-connect
End.DT6 / End.DT4 / End.DT46Decapsulate and look the inner packet up in a specific table (VRF)L3VPN egress per VRF
End.DX2, End.DX2V, End.DT2U, End.DT2MLayer 2 cross-connect, VLAN lookup, unicast MAC lookup, floodingEVPN and layer 2 services
End.B6.EncapsBound to an SRv6 policy: push a new SRH from this nodeBinding SID
End.BMBound to an SR-MPLS policySRv6 to SR-MPLS interworking

RFC 8986 also defines headend behaviours (H.Encaps, H.Encaps.Red and their layer 2 variants) and three flavours that change how the SRH is removed: PSP (penultimate segment pop), USP (ultimate segment pop) and USD (ultimate segment decapsulation).

The security consequence is direct. In SR-MPLS, a label is an index into a table only the operator's routers understand. In SRv6, a SID is an IPv6 address, and some SIDs are programs: "decapsulate whatever is inside and drop it into the finance VRF" is a behaviour reachable by any packet whose destination address is that SID. If an outsider can deliver a packet to an End.DT4 SID, the router will decapsulate the inner IPv4 packet and route it inside the VPN. That is why RFC 8986's security section points straight back to RFC 8754's domain filtering and says a clear distinction between SID space and end user address space is "required to maintain the integrity and security of the SRv6 Domain".

Worked example 2: SRv6 header overhead with and without compression

The cost of 128 bit SIDs is the main operational complaint about SRv6. Here are the numbers for an encapsulated packet, using the field sizes from RFC 8200 and RFC 8754.

CaseOuter IPv6SRH fixedSegment listTotal added
3 SIDs, full SRH40 bytes8 bytes3 x 16 = 48 bytes96 bytes
3 SIDs, reduced SRH (first SID only in DA)4082 x 16 = 3280 bytes
1 SID, reduced, no HMAC (SRH omitted)400040 bytes
8 SIDs, full SRH4088 x 16 = 128176 bytes
8 SIDs, compressed (RFC 9800 example, 2 containers, reduced)4081 x 16 = 1664 bytes
Same 3 hop path in SR-MPLS003 x 4 = 1212 bytes

The compressed line comes from RFC 9800 (June 2025), "Compressed SRv6 Segment List Encoding". Its example uses a 48 bit locator block with a 16 bit combined node and function. A 128 bit container holds the block plus five 16 bit compressed SIDs, so eight SIDs fit in two containers: the first goes in the destination address and the second is the only entry in the SRH. RFC 9800 defines NEXT-C-SID and REPLACE-C-SID flavours and updates RFC 8754 so a segment list entry can be a packed container rather than a single address.

Add an HMAC TLV and you pay 8 more bytes of TLV header and key ID plus up to 32 bytes of HMAC. With an underlying 1500 byte link MTU, a 176 byte encapsulation leaves 1324 bytes for the inner packet. RFC 8754 section 5.3 says the ingress edge node must consider the MTU of the SR domain, recommends running a larger MTU inside the domain than at the ingress edges, and notes that SRv6 encapsulation carries the same MTU and fragmentation considerations as any IPv6 tunnel (RFC 2473).

What are SR policies and Flex-Algo?

SR policies (RFC 9256)

RFC 9256 (July 2022), "Segment Routing Policy Architecture", updates RFC 8402 and defines how a headend steers traffic into an engineered path. An SR policy is identified by the tuple headend, color and endpoint:

  • Headend: the node that instantiates the policy and pushes the segments.
  • Color: a 32 bit number representing an intent, such as "low latency" or "avoid the submarine cable".
  • Endpoint: where the policy terminates.

A policy has one or more candidate paths, which can come from local configuration, from PCEP (RFC 8664 for SR-MPLS, RFC 9603 for SRv6), or from BGP (RFC 9830). Each candidate path has a preference, a 32 bit value with a default of 100, and the valid path with the highest preference wins. Each candidate path contains one or more segment lists, optionally weighted for load sharing.

Traffic is steered into a policy in three common ways: a BGP route carrying a color extended community that matches a policy's color and endpoint (often called automated steering), a binding SID that some upstream node pushes, or local policy routing.

Two things follow for security. First, whatever can create or prefer a candidate path controls where traffic goes. A BGP session or PCEP session to the controller is therefore as sensitive as the controller itself. Second, RFC 9256's preference rule means an injected candidate path with a higher preference silently replaces the legitimate one. Monitoring should alert on any change of the active candidate path, not only on policy creation.

Flex-Algo (RFC 9350)

RFC 9350 (February 2023), "IGP Flexible Algorithm", lets the IGP compute paths with different metrics or constraints, so you do not always need a controller or an explicit SID list. Algorithm numbers 128 to 255 are Flex-Algorithms. A Flexible Algorithm Definition (FAD) says which metric to minimise (IGP metric, delay or TE metric) and which link affinities or shared risk groups to include or exclude. Routers that participate advertise a separate Prefix-SID (or, for SRv6, a separate locator) per algorithm.

The effect is that a single Node-SID for "R9 under algorithm 128" can mean "shortest delay path to R9 avoiding links coloured red". A one SID policy replaces a long explicit list.

How are they used for traffic engineering and network slicing?

The building blocks combine like this:

  • Traffic engineering: a controller computes a path that meets a bandwidth or latency constraint, then installs it as an SR policy with a binding SID. Headends steer colored BGP routes into it.
  • Low latency or disjoint planes: two Flex-Algos with different FADs (delay metric, or exclusion of each other's links) give two independent topologies that the IGP maintains on its own.
  • Network slicing: a slice is a combination of a Flex-Algo or SR policy for the path, a VPN SID (End.DT4 or End.DT6 in SRv6) for the tenant, and quality of service on the links. SR provides the forwarding part; the isolation guarantees still come from resource reservation and policing, which SR does not provide on its own.
  • Fast reroute: SR lets a node pre-compute a backup segment list for each protected link and switch to it locally when the link fails.

Why was the IPv6 Type 0 routing header deprecated?

IPv6 shipped with a general routing header, and its Type 0 variant (RH0) let any host list intermediate addresses the packet must visit. RFC 5095 (December 2007) explains why it had to go. One RH0 could list many intermediate addresses, and the same address could appear more than once. A packet could therefore be built to bounce between two routers many times, so a stream of attacker packets became many times more traffic on the path between two remote routers. RFC 5095 records an 88 fold amplification demonstrated at the CanSecWest conference in April 2007, and notes that the attack hits the whole path between the two exploited nodes, not just the nodes themselves.

Problems with RH0 had been raised as early as 2001. RFC 5095's fix was blunt: nodes must not process RH0 and must treat it as an unrecognised routing type, which means dropping the packet with an ICMP Parameter Problem if Segments Left is non zero.

RFC 5095 also warned against overcorrecting. Firewalls must not block all routing headers, because that would make it impossible to deploy future routing header types (Mobile IPv6 already used Type 2). That warning is why SRv6 could exist at all, and why your filters should match routing type 4 deliberately rather than "any routing header".

How does the SR domain trust model avoid repeating RH0?

RH0 was dangerous because it was host-to-anywhere source routing across the open Internet. SRv6 keeps the mechanism but changes who may use it. RFC 8402 and RFC 8754 define an SR domain, a set of nodes under one administration, and state that nodes outside it are not trusted and cannot directly use its SIDs. RFC 8754 section 5.1 makes this concrete with two layers of access control:

  1. Distributed edge protection. Allocate all SIDs from one block S/s. On every external interface of every edge node, apply an inbound infrastructure ACL that drops any packet whose destination is in S/s. RFC 8754 states that failing to do so exposes the domain to the source routing attacks described in RFC 5095.
  2. Per-node protection. Assign all infrastructure interface addresses from a prefix A/a. On each node k, put local SIDs in Sk/sk, and on every internal interface drop packets to Sk/sk whose source is not in A/a.

Add BCP 38 and BCP 84 source address filtering so outsiders cannot forge an infrastructure source address, and the RFC says the RH0 attacks from outside the domain are blocked: bypassing filters, reaching otherwise unreachable systems, topology discovery, bandwidth exhaustion and defeating anycast.

Inter-domain traffic is never source routed by outsiders. RFC 8754 section 5.2 requires that traffic crossing the domain be encapsulated in an outer IPv6 header originated and terminated by SR domain nodes. Customer packets ride inside; only the operator's headend writes the SRH.

RFC 9602 (October 2024) added a structural help. IANA allocated 5f00::/16 in April 2024 as "Segment Routing (SRv6) SIDs" in the special purpose address registry, marked not globally reachable. The RFC says the prefix makes it simpler to filter at the edge and for the SR domain to "fail closed", and that global DNS should not reference these addresses. An operator who allocates SIDs from 5f00::/16 can write one edge rule that cannot accidentally overlap customer space.

What are the security risks in a segment routed network?

The threats fall into three planes. The table summarises them; the subsections explain each.

ThreatPlaneWhat it lets an attacker doPrimary control
SRH injection from outside the domainDataChoose paths, bypass filters, reach internal services, amplify trafficEdge IACL dropping SID block and routing type 4
Label stack injection (SR-MPLS)DataSame, for MPLS-labelled or MPLS-over-IP trafficDrop labelled traffic and MPLS-in-IP on untrusted interfaces
SID spoofing toward service SIDsDataInsert packets into a VPN via End.DT4, End.DT6 or End.DX behavioursEdge and per-node ACLs, dedicated SID block, BCP 38
Rogue or compromised node in the domainData and controlAdd arbitrary SRH, modify segment listsHMAC TLV verification at trusted nodes, node hardening
False SID or topology advertisementsControlRedirect traffic by advertising SIDs it does not ownIGP authentication, BGP session protection, route filtering
Controller or policy tamperingManagementInstall or prefer malicious candidate paths for whole traffic classesAuthenticated PCEP and BGP, controller access control, change monitoring
Topology disclosureDataLearn internal topology from captured SRHsEncryption above SR where needed; keep SRHs inside the domain
ICMP error abuseDataTrigger error floods with malformed SRHsICMPv6 rate limiting per RFC 4443

SRH injection from outside the domain

This is the RH0 problem again. If a border router accepts a packet from the Internet with destination in your SID block, or with a type 4 routing header, the packet will be processed by SR endpoints inside. RFC 8402 lists the consequences when filtering fails or the trust model is broken: malicious looping, evasion of access controls, and hiding the source of denial of service attacks.

The fix is the RFC 8754 edge ACL, applied to every external interface. In practice that means peering ports, transit ports, customer access ports, data centre gateways, management networks and any lab or partner connection. A single forgotten interface is the whole hole.

SID spoofing and service SIDs

Because SRv6 SIDs are routable addresses, an attacker does not need an SRH at all to reach a service SID. A plain IPv6 packet whose destination is an End.DT4 SID, carrying an IPv4 packet inside, is exactly what that behaviour is built to decapsulate. Edge filtering on the destination block, not only on the presence of an SRH, is what stops it. RFC 8754 section 7.2 treats this as service theft and says it is not a concern inside the domain because the IACLs deny outsiders.

For SR-MPLS, the equivalent rule is in RFC 8402 section 8.1: boundary routers must filter any external traffic destined to a label associated with a segment in the trusted domain, including labels in the SRGB, the boundary router's SRLB and labels outside both. Most operators implement this by not enabling MPLS on untrusted interfaces at all and by dropping MPLS-in-IP and MPLS-in-UDP encapsulations at the edge unless they come from known tunnel endpoints.

Compromised nodes and the HMAC TLV

The edge ACL does nothing against a node already inside. RFC 8754 is candid: compromised nodes within the SR domain may mount the same attacks plus the usual ones on IP networks, such as interception and man in the middle.

The HMAC TLV is the tool for narrowing that. It is optional and carries a key ID and a keyed HMAC computed over the IPv6 source address, the SRH Last Entry, Flags, the HMAC TLV's D bit and reserved field, the key ID and every address in the segment list. A verifying node checks that the current segment matches the destination address and that the HMAC matches. If not, it should drop and log the packet and send a rate-limited ICMP error. Implementations that support HMAC must implement SHA-256. Key rollover works by running two key IDs side by side, and revoking a segment list means rolling to a new key ID.

RFC 8754 section 5.2 describes the canonical use. A host may be allowed to add its own SRH, for example to request a specific service level, but the top-of-rack switch verifies the HMAC on any packet from that host toward the SID block. The host can use only segment lists it was given; it cannot write its own.

Key management is explicitly out of scope of the RFC, which suggests static or controller-driven configuration or a group key protocol, and points to BCP 107 for key management guidance. Treat HMAC keys like any shared secret: unique per trust zone, rotated, never stored in device configuration backups in plain text.

Control plane: false SIDs and topology

Every SID is learned from IS-IS, OSPF or BGP. RFC 8402 says SR routers accept and install labels or SIDs only if they were advertised by a trusted source, validated using the existing control plane's security mechanisms. So the controls are the ones covered in our OSPF and BGP posts, now with higher stakes:

  • Authenticate IGP adjacencies and LSPs with keyed cryptographic authentication; never run IS-IS or OSPF on customer-facing interfaces.
  • Filter what BGP sessions may advertise, including BGP Prefix-SID and SRv6 service SID attributes. RFC 8669's attribute is optional transitive, so decide deliberately whether it may cross an AS boundary.
  • Do not leak the SID block or locators outside the domain. RFC 8402 states explicit routing information must not be leaked through the boundaries of the administered domain.
  • Watch for SID conflicts. Two routers claiming the same prefix SID index is an operational mistake most of the time, and a hijack some of the time.

Policy tampering via the controller

In centralised SR, a controller computes paths and pushes them by PCEP, BGP or NETCONF. That controller can redirect every flow of a given color in the network. Protect it like a production identity provider:

  • Authenticate and encrypt PCEP and BGP sessions to the controller, and restrict which headends accept policies from which controllers.
  • Separate controller administrative access from general IT access; require multi-person approval for policy changes that affect many headends.
  • Log and alert on new policies, changed preferences, and changes of the active candidate path.
  • Patch and inventory the controller software and its dependencies like any other critical application. It is usually an ordinary Linux application stack with open source libraries.

Topology disclosure and ICMP

RFC 8754 section 7.3 notes the SRH is unencrypted and reveals intermediate SIDs, and section 7.4 points to ICMPv6 rate limiting (RFC 4443) to stop error message floods triggered by malformed headers. Neither is severe inside a well filtered domain. Both are good reasons never to let SRH packets out of the domain unencapsulated, and to encrypt sensitive tenant traffic above the SR layer, because SR provides path control, not confidentiality.

Step by step: build a lab SRv6 path with Linux and add edge filters

This walkthrough builds a small SRv6 domain in network namespaces on one Linux machine using iproute2's seg6 and seg6local route encapsulations. Linux gained IPv6 segment routing in kernel 4.10, and the ip-route(8) manual says the seg6local actions require Linux 4.14 or later; use a current distribution kernel with CONFIG_IPV6_SEG6_LWTUNNEL and, for step 6, CONFIG_IPV6_SEG6_HMAC. Run it in a disposable VM. The commands create and delete namespaces only, but they need root.

Topology:

 hosta ---- r1 ========= r3 ---- hostb
             \           /
              \         /
               +-- r2 --+

 hosta  2001:db8:a::1/64        hostb  2001:db8:b::1/64
 r1-r2  fd00:12::1 / fd00:12::2
 r2-r3  fd00:23::2 / fd00:23::3
 r1-r3  fd00:13::1 / fd00:13::3   (the direct, shortest path)

 SID locators (from 5f00::/16, RFC 9602)
 r1  5f00:0:0:1::/64
 r2  5f00:0:0:2::/64   End SID     5f00:0:0:2::e
 r3  5f00:0:0:3::/64   End.DT6 SID 5f00:0:0:3::d6

Without SR, traffic from hosta to hostb takes r1 to r3 directly. The SR policy forces it through r2.

Step 1: create namespaces and links

set -e
for n in hosta r1 r2 r3 hostb; do ip netns add $n; done

link() {  # link <nsA> <ifA> <nsB> <ifB>
  ip link add "$2" type veth peer name "$4"
  ip link set "$2" netns "$1"; ip link set "$4" netns "$3"
  ip -n "$1" link set "$2" up; ip -n "$3" link set "$4" up
}
link hosta a-r1  r1 r1-a
link r1   r1-r2 r2 r2-r1
link r2   r2-r3 r3 r3-r2
link r1   r1-r3 r3 r3-r1
link r3   r3-b  hostb b-r3

for n in hosta r1 r2 r3 hostb; do ip -n $n link set lo up; done

Step 2: addresses and forwarding

ip -n hosta addr add 2001:db8:a::1/64 dev a-r1 nodad
ip -n r1    addr add 2001:db8:a::254/64 dev r1-a nodad
ip -n hostb addr add 2001:db8:b::1/64 dev b-r3 nodad
ip -n r3    addr add 2001:db8:b::254/64 dev r3-b nodad

ip -n r1 addr add fd00:12::1/64 dev r1-r2 nodad
ip -n r2 addr add fd00:12::2/64 dev r2-r1 nodad
ip -n r2 addr add fd00:23::2/64 dev r2-r3 nodad
ip -n r3 addr add fd00:23::3/64 dev r3-r2 nodad
ip -n r1 addr add fd00:13::1/64 dev r1-r3 nodad
ip -n r3 addr add fd00:13::3/64 dev r3-r1 nodad

for n in r1 r2 r3; do
  ip netns exec $n sysctl -qw net.ipv6.conf.all.forwarding=1
  ip netns exec $n sysctl -qw net.ipv6.conf.all.seg6_enabled=1
  for i in $(ip -n $n -o link show | awk -F': ' '{print $2}' | cut -d@ -f1 | grep -v '^lo$'); do
    ip netns exec $n sysctl -qw net.ipv6.conf.$i.seg6_enabled=1
  done
done

ip -n hosta route add default via 2001:db8:a::254
ip -n hostb route add default via 2001:db8:b::254

The kernel's seg6 sysctl documentation says seg6_enabled decides whether an interface accepts or drops SR-enabled IPv6 packets whose destination is local, and that it is disabled by default. That default is a sensible edge posture: leave it off on any interface that faces outside the domain.

Step 3: route the locators

Each router needs a route to the other routers' locators, the job an IGP would do in production.

# r1: reach r2's locator via r2, r3's locator via the direct link
ip -n r1 -6 route add 5f00:0:0:2::/64 via fd00:12::2
ip -n r1 -6 route add 5f00:0:0:3::/64 via fd00:13::3
# r2: reach r3's locator
ip -n r2 -6 route add 5f00:0:0:3::/64 via fd00:23::3
# return traffic from hostb to hosta uses plain IPv6 on the direct link
ip -n r3 -6 route add 2001:db8:a::/64 via fd00:13::1

Step 4: instantiate the SIDs

# r2: an End SID, a plain SRv6 endpoint
ip -n r2 -6 route add 5f00:0:0:2::e/128 encap seg6local action End dev r2-r1

# r3: an End.DT6 SID that decapsulates and looks up the inner packet in the main table
ip -n r3 -6 route add 5f00:0:0:3::d6/128 encap seg6local action End.DT6 table main dev r3-r2

End only accepts packets with a non zero Segments Left; End.DT6 only accepts packets with Segments Left zero or no SRH, and an inner IPv6 packet. Anything else is dropped, according to the manual. In a VPN design you would use End.DT6 vrftable or End.DT4 vrftable with a VRF device, which the manual says requires net.vrf.strict_mode=1.

Step 5: the headend policy

# r1: traffic for hostb is encapsulated with a two segment list: via r2, then decapsulate at r3
ip -n r1 -6 route add 2001:db8:b::/64 \
  encap seg6 mode encap segs 5f00:0:0:2::e,5f00:0:0:3::d6 dev r1-r2

ip netns exec hosta ping -c 3 2001:db8:b::1

Inspect the packets on each hop. In one terminal:

ip netns exec r2 tcpdump -ni r2-r1 -vv ip6

and in another:

ip netns exec r3 tcpdump -ni r3-r2 -vv ip6

On r2's inbound link you should see an outer IPv6 header from r1 to 5f00:0:0:2::e, a routing header of type 4 with Segments Left 1, and the original ICMPv6 echo inside. On r3's link from r2, the outer destination has become 5f00:0:0:3::d6 and Segments Left is 0. On the direct r1 to r3 link you should see only the plain echo replies coming back. Adding count to a seg6local route and running ip -n r2 -s -6 route show exposes the per-action counters the manual describes: packets processed, bytes processed and processing errors.

Try mode encap.red on r1 and compare the capture: the first SID now sits only in the outer destination address and the SRH carries one entry instead of two.

Step 6: require an HMAC at r2

# Generate one 32 byte key for the lab; enter the same value on r1 and r2 when prompted
head -c 32 /dev/urandom | base64 -w 0; echo

ip netns exec r1 ip sr hmac set 42 sha256
ip netns exec r2 ip sr hmac set 42 sha256

# r2 now drops SR packets on this interface that carry no HMAC
ip netns exec r2 sysctl -qw net.ipv6.conf.r2-r1.seg6_require_hmac=1

# Re-create the headend route with the HMAC key ID
ip -n r1 -6 route replace 2001:db8:b::/64 \
  encap seg6 mode encap segs 5f00:0:0:2::e,5f00:0:0:3::d6 hmac 42 dev r1-r2
ip netns exec hosta ping -c 3 2001:db8:b::1

The ip-sr(8) manual makes two points worth copying into your runbook. The passphrase is not stretched and is used directly as the key, so generate it from a random source as above. The supported algorithms are sha1 and sha256; use sha256, which RFC 8754 makes mandatory to implement. The kernel sysctl accepts -1 (ignore HMAC), 0 (accept packets without HMAC, validate those that carry one, the default) and 1 (drop packets without HMAC, validate the rest).

To confirm enforcement, remove hmac 42 from r1's route and ping again. The pings should now fail at r2.

Step 7: add edge filters on r1

r1's link to hosta is the domain edge. Nothing arriving there should be addressed to the SID block or carry a type 4 (or type 0) routing header. The nftables manual documents the rt expression with type and seg-left fields and an srh expression with flags, tag, sid and seg-left.

ip netns exec r1 nft -f - <<'EOF'
table inet sr_edge {
  chain ingress_filter {
    type filter hook prerouting priority -300; policy accept;

    # 1. Outsiders may never address the SID block (RFC 8754 section 5.1, RFC 9602)
    iifname "r1-a" ip6 daddr 5f00::/16 counter drop

    # 2. Outsiders may never send segment routing headers, or the deprecated RH0
    iifname "r1-a" rt type 4 counter drop
    iifname "r1-a" rt type 0 counter drop

    # 3. Outsiders may never claim an infrastructure source (BCP 38)
    iifname "r1-a" ip6 saddr { fd00::/8, 5f00::/16 } counter drop
  }
}
EOF

ip netns exec r1 sysctl -qw net.ipv6.conf.r1-a.seg6_enabled=0

Then the per-node rule from RFC 8754 on r2 and r3: only infrastructure sources may address local SIDs. In this lab the infrastructure prefix A/a is fd00::/8 plus the SID block itself.

for n in r2 r3; do
ip netns exec $n nft -f - <<'EOF'
table inet sr_node {
  chain ingress_filter {
    type filter hook prerouting priority -300; policy accept;
    ip6 daddr 5f00::/16 ip6 saddr != { fd00::/8, 5f00::/16 } counter drop
  }
}
EOF
done

Because r1 encapsulates with an outer source taken from its egress interface (or from ip sr tunsrc set, which the manual recommends setting explicitly for performance), legitimate SR traffic carries an fd00 source and passes. Set ip netns exec r1 ip sr tunsrc set fd00:12::1 to make that deterministic.

Test the edge from hosta. You do not need to craft an SRH to verify rule 1: a plain ping to a SID address from outside should be dropped and the counter should increase.

ip -n hosta -6 route add 5f00::/16 via 2001:db8:a::254
ip netns exec hosta ping -c 2 -W 1 5f00:0:0:2::e     # expected: no reply
ip netns exec r1 nft list table inet sr_edge          # rule 1 counter > 0
ip netns exec hosta ping -c 2 2001:db8:b::1          # expected: replies, policy still works

Step 8: clean up

for n in hosta r1 r2 r3 hostb; do ip netns del $n; done

What carries over to production: allocate all SIDs from one block (5f00::/16 or a dedicated slice of your own space), put the edge rules on every external interface through configuration management rather than by hand, test them with a probe from outside on every change, keep seg6_enabled off where SR is not needed, and decide explicitly where HMAC verification is required.

RSVP-TE, SR-MPLS and SRv6 compared

RSVP-TESR-MPLSSRv6
Key RFCsRFC 3209RFC 8402, RFC 8660RFC 8402, RFC 8754, RFC 8986
State in the corePer tunnel at every midpoint, refreshed periodicallyNone per path; only IGP-advertised SIDsNone per path; only IGP-advertised locators and local SIDs
Label or SID distributionRSVP signalling plus LDP or IGP for base reachabilityIS-IS, OSPF, BGPIS-IS, OSPF, BGP
Header overhead for a 3 segment pathOne 4 byte label per hop3 x 4 = 12 bytes40 byte outer IPv6 + 8 byte SRH + 16 bytes per SID (80 to 96 bytes); less with RFC 9800 compression
Data planeMPLSMPLS, or MPLS over IP/UDP (RFC 8663)Native IPv6
ServicesLabels for VPNs via BGP/MPLS VPNSame VPN labelsSIDs with behaviours (End.DT4, End.DT6, End.DX2) carried in BGP (RFC 9252)
Bandwidth reservationBuilt inNot built in; controller or policingNot built in; controller or policing
Operational modelDistributed signalling, per-tunnel configurationIGP-driven, optional controllerIGP-driven, optional controller, host participation possible
Security boundaryMPLS not enabled outside the domain; RSVP authenticationDrop labelled traffic and MPLS-in-IP at the edge; IGP and BGP authenticationDrop SID block and routing type 4 at the edge; per-node ACLs; optional HMAC; IGP, BGP and PCEP authentication
What breaks if the edge leaksLimited; outside packets rarely arrive as MPLSLabel injection steers trafficAny IPv6 packet can reach service SIDs; RH0 style source routing

The last row is the honest summary. SRv6's biggest strength, that SIDs are ordinary routable IPv6 addresses, is also its biggest exposure. An MPLS label arriving from the Internet is unusual and easy to drop. An IPv6 packet to an address is the most normal thing in the world.

Common mistakes

  • Allocating SIDs from address space that customers or the Internet can reach. If your locators sit inside a prefix you announce to the Internet, every edge filter has to be perfect. Use a dedicated block, ideally 5f00::/16, and never announce it externally.
  • Filtering the SRH but not the SID block. Service SIDs such as End.DT4 do not need an SRH to be reached. Filter on destination address as well as routing type.
  • Blocking every IPv6 routing header everywhere. RFC 5095 warns this breaks future extensions. Inside the domain you need type 4; at the edge, drop type 0 and type 4 from outside explicitly.
  • Forgetting the less obvious edges. Management networks, out-of-band links, lab interconnects, data centre gateways and partner circuits are all external interfaces for this purpose.
  • Treating HMAC as a substitute for edge ACLs. HMAC verification is optional, configured per node, and only checks SRH packets. It does not stop a plain packet to a service SID.
  • Weak or shared HMAC keys. The Linux implementation uses the passphrase directly as the key. A memorable password is a weak key. Generate keys from a random source and rotate them with overlapping key IDs.
  • Running the IGP without authentication. In SR the IGP distributes labels and SIDs as well as routes. An unauthenticated adjacency is a SID injection point.
  • Letting the controller become a soft target. A path computation or policy controller can redirect every colored flow. It needs the same access control, patching and logging as any tier 0 system.
  • Ignoring MTU. A 176 byte encapsulation on a 1500 byte link silently breaks large packets. Raise core MTU or use reduced and compressed encodings, and test with full-size packets.
  • Mixed SRGBs without a reason. Different SRGBs on different routers are allowed by RFC 8660 but make troubleshooting and filter review harder. Pick one.

FAQ

What is the difference between SR-MPLS and SRv6?

Both implement the same RFC 8402 architecture. SR-MPLS encodes each segment as a 4 byte MPLS label in a label stack and needs no change to MPLS forwarding. SRv6 encodes each segment as a 128 bit IPv6 address, carries the list in a Segment Routing Header (Routing Header type 4) and adds programmable behaviours such as End.DT4. SR-MPLS is smaller on the wire; SRv6 runs natively over IPv6 and removes MPLS from the network.

Is segment routing the same as source routing?

It is a form of source routing, and RFC 8402 says so in its first sentence. The difference from old style source routing (IPv4 source route options, IPv6 RH0) is the trust model: only nodes inside an administered SR domain may add segments, and the domain's edges must drop outside packets that try.

Does segment routing replace LDP and RSVP-TE?

It can. Prefix SIDs advertised by the IGP replace LDP's shortest path labels, and SR policies replace many RSVP-TE tunnels without per-tunnel state in the core. RSVP-TE still offers built-in bandwidth reservation, which SR leaves to a controller or to policing, so some networks run both during migration.

Why was the IPv6 Type 0 routing header deprecated?

Because any host could use it to bounce packets between two remote routers many times, amplifying traffic along the path. RFC 5095 cites an 88 fold amplification demonstrated in 2007 and requires nodes to stop processing RH0.

Is SRv6 safe to expose to the Internet?

No. RFC 8754 and RFC 8402 assume a trusted SR domain and require filtering at the boundary. SRv6 SIDs and SRHs should never be accepted from outside the domain. Inter-domain traffic crosses an SR domain inside an outer IPv6 header added by the domain's own headend.

What is the SRv6 HMAC TLV?

An optional TLV in the Segment Routing Header that carries a key ID and a keyed HMAC over the source address, parts of the SRH and the full segment list. A verifying node drops packets whose HMAC is missing or wrong. It lets a domain accept SRHs from hosts or less trusted nodes while ensuring only authorised segment lists are used. SHA-256 support is mandatory for implementations that support it.

What is 5f00::/16?

An IPv6 block IANA allocated in April 2024 for SRv6 SIDs, documented in RFC 9602 (October 2024). It is marked not globally reachable, so operators can number SIDs from it and filter the whole block at the domain edge with one rule.

What is Flex-Algo in segment routing?

IGP Flexible Algorithm, RFC 9350. Algorithms 128 to 255 let the IGP compute paths with a different metric (such as delay) or constraints (such as excluding certain links) and give each node an extra Prefix-SID or SRv6 locator for each algorithm. One SID then means "the low delay path to that node".

What is a binding SID?

A SID that represents a whole SR policy at its headend. A packet arriving with the binding SID as its active segment is steered into the policy and gets the full segment list pushed. It keeps label stacks short and hides internal paths, but it also means one SID controls an entire engineered path.

Can I try SRv6 on Linux?

Yes. Linux has supported IPv6 segment routing since kernel 4.10 (February 2017). iproute2's seg6 encapsulation builds headends, seg6local actions implement End, End.X, End.DT4, End.DT6 and other behaviours, and ip sr hmac configures HMAC keys. The lab above runs in network namespaces on one machine.

Where Safeguard fits

Safeguard does not configure routers, filter packets, audit routing policy or analyse network firmware, and nothing in this post depends on it. The fit is with the software around a segment routed network. Path computation controllers, automation that pushes edge ACLs, network telemetry collectors and the open source routing stacks used in labs and white box deployments are built from open source packages and shipped as container images. Safeguard scans repositories, container images and SBOM files (safeguard scan --dir ., --image <name>, --sbom <file>), shows which projects carry a given component and version, matches them against vulnerability data and applies policies and gates. That tells you which controller or automation builds still carry a vulnerable library when a fix ships. Remediation pull requests are available and switched off by default. The router operating systems themselves come from their vendors, and their fixes still come from those vendors.

Fix it without waiting for upstream

A segment routing domain is only as trustworthy as the software that programs it: the controller that computes policies, the automation that renders edge filters, and the collectors that watch for changed candidate paths are all ordinary applications built from open source dependencies. When one of those dependencies has a vulnerability, the fix path is the same as for any other software you build, so the habits below apply to your network automation as much as to your product code.

Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.

1. Autonomous remediation: pull requests, not tickets

When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation covers eight categories, including dependencies, licenses, security posture and findings. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.

2. Gold Open Source: the safe version in seconds, free

gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds. The safeguard-sh/gold-scan-action GitHub Action can fail a build on a known exploited vulnerability, on any known vulnerability, or never, so a version you have just removed cannot quietly come back in next week's merge.

3. Gold Registry: start from components that are already fixed

registry.safeguard.sh provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs, zero malware and a completed license check, with SLSA L3 or higher provenance, a Sigstore signature and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.

When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. This fork and patch flow is in early access today, so ask which packages it covers before you plan around it.

Your situationWhat to use
A fixed version existsAutonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version
You need to know today whether you are affectedGold Open Source lookup and "Am I affected?" checker, free and without login
You want vulnerable versions to stop shippingThe Gold scan GitHub Action in CI, plus Safeguard policies and gates
Upstream has no fix yet, or will not ship oneA custom Gold request; fork and patch (early access)
You want to start clean on new projectsPull hardened components and images from Gold Registry

One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.

See how Safeguard would help

The first demo is a real session with the Safeguard CLI. The assistant reads a finding and its advisory, asks before each command, upgrades a dependency and runs the tests, and pushes nothing. The same flow applies when a library inside your path computation controller or ACL automation needs an upgrade.

Click through it at your own pace, or open it full screen.

The second demo sets up the Safeguard runner on your own machine, approves it with a device code and then scans from the terminal. Network automation repositories often live on internal hosts, and the runner lets you scan them from a machine you control.

Click through it at your own pace, or open it full screen.

The third demo connects Claude to the Safeguard MCP server with OAuth and lets you choose which tools Claude can use. Choosing a narrow tool set is the same least privilege habit this post recommends for controllers and HMAC keys: give each party only the paths it needs.

Click through it at your own pace, or open it full screen.

Download the apps at safeguard.sh/download and read the CLI docs at docs.safeguard.sh/docs/cli.

Quick check

Your edge routers drop every inbound packet with a type 4 routing header. Is an End.DT4 SID inside the domain now unreachable from the Internet?

No. A plain IPv6 packet with the End.DT4 SID as its destination needs no SRH; the endpoint will decapsulate the inner IPv4 packet and route it in the VRF. You must also drop inbound packets whose destination is in your SID block, which is the first rule in RFC 8754 section 5.1.

All routers use an SRGB of 16000 to 23999. Router R7 advertises prefix SID index 7. What label does the headend push to reach R7, and what does a transit router swap it to?

16007, the SRGB base plus the index. With a uniform SRGB, every transit router applies CONTINUE and swaps 16007 for 16007, so the label stays the same along the shortest path until it is popped at or before R7.

Sources

Last reviewed: 24 October 2026. Segment routing standards continue to evolve in the IETF SPRING working group; check the RFC Editor and your router vendor's documentation before relying on a specific behaviour, flavour or encoding.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.