SR-MPLS – Anycast
1. Intro
An IGP anycast segment is an IGP prefix segment that identifies a set of routers. An anycast segment enforces forwarding based on the equal-cost multipath-aware shortest-path toward the closest node of the anycast set. Within an anycast group, all the routers advertise the same prefix with the same SID value, which facilitates load balancing.
We will use the same test topology from the previous posts:

The initial config is simple:
### Initial config:
set interfaces ge-0/0/1 unit 0 family mpls maximum-labels 8
set interfaces ge-0/0/2 unit 0 family mpls maximum-labels 8
set protocols isis interface ge-0/0/1.0 point-to-point
set protocols isis interface ge-0/0/2.0 point-to-point
set protocols isis interface lo0.0 passive
set protocols isis source-packet-routing srgb start-label 800000
set protocols isis source-packet-routing srgb index-range 10000
set protocols isis source-packet-routing node-segment ipv4-index 1001
set protocols isis level 2 wide-metrics-only
set protocols isis level 1 disable
set protocols mpls interface lo0.0
set protocols mpls interface ge-0/0/2.0
set protocols mpls interface ge-0/0/1.0
2. Configuring Anycast
We will configure the 1.2.3.4/32 prefix on R7 and R8, then we will advertise it in ISIS:
### On both R7 and R8 configure the following:
set interfaces lo0.0 family inet address 1.2.3.4/32
set policy-options policy-statement SR-ANYCAST term 10 from protocol direct
set policy-options policy-statement SR-ANYCAST term 10 from route-filter 1.2.3.4/32 exact
set policy-options policy-statement SR-ANYCAST term 10 then prefix-segment index 1234
set policy-options policy-statement SR-ANYCAST term 10 then prefix-segment node-segment
set policy-options policy-statement SR-ANYCAST term 10 then accept
set protocols isis export SR-ANYCAST
### We can see that the prefix is received by the R1 router:
root@R1# run show route 1.2.3.4
inet.0: 43 destinations, 43 routes (43 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
1.2.3.4/32 *[IS-IS/18] 00:01:29, metric 30
> to 17.8.1.2 via ge-0/0/2.0
inet.3: 8 destinations, 9 routes (8 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
1.2.3.4/32 *[L-ISIS/14] 00:01:29, metric 30
> to 17.8.1.2 via ge-0/0/2.0, Push 801234
### What matters more to us is the inet.3 table:
root@R1# run show route table inet.3 1.2.3.4 extensive
inet.3: 8 destinations, 9 routes (8 active, 0 holddown, 0 hidden)
1.2.3.4/32 (1 entry, 1 announced)
*L-ISIS Preference: 14
Level: 2
Next hop type: Router, Next hop index: 0
Address: 0x7bbe734
Next-hop reference count: 1, key opaque handle: 0x0, non-key opaque handle: 0x0
Kernel Table Id: 0
Next hop: 17.8.1.2 via ge-0/0/2.0, selected
Label operation: Push 801234
Label TTL action: prop-ttl
Load balance label: Label 801234: None;
Label element ptr: 0xa3f3908
Label parent element ptr: 0x0
Label element references: 1
Label element child references: 0
Label element lsp id: 0
Session Id: 0
State: <Active Int>
Local AS: 64512
Age: 4:43 Metric: 30
Validation State: unverified
ORR Generation-ID: 0
Task: IS-IS
Announcement bits (1): 2-Resolve tree 1
AS path: I
Ext Data: Prefix-Sid: Index: 1234 Algo: 0 Flags:R:0,N:1,P:0,E:0
Thread: junos-main
Now, let’s test the Anycast 1.2.3.4/32 prefix with some pings:
### For testing purposes we will configure the following on both R1 and R2.
set protocols mpls traffic-engineering mpls-forwarding
### Now, in inet.0 we have the MPLS path:
root@R1# run show route 1.2.3.4
inet.0: 43 destinations, 51 routes (43 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
1.2.3.4/32 *[L-ISIS/14] 00:23:18, metric 30
> to 17.8.1.2 via ge-0/0/2.0, Push 801234
[IS-IS/18] 00:23:18, metric 30
> to 17.8.1.2 via ge-0/0/2.0
inet.3: 8 destinations, 8 routes (8 active, 0 holddown, 0 hidden)
+ = Active Route, - = Last Active, * = Both
1.2.3.4/32 *[L-ISIS/14] 00:22:45, metric 30
> to 17.8.1.2 via ge-0/0/2.0, Push 801234
### Ping from R1 to the Anycast 1.2.3.4 is OK:
root@R1# run ping 1.2.3.4 source 17.0.0.1
PING 1.2.3.4 (1.2.3.4): 56 data bytes
64 bytes from 1.2.3.4: icmp_seq=0 ttl=62 time=4.047 ms
64 bytes from 1.2.3.4: icmp_seq=1 ttl=62 time=4.727 ms
^C
--- 1.2.3.4 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 4.047/4.387/4.727/0.340 ms
### With tcpdump we can capture the packet on the top link R3-R6:
15:37:56.605406 MPLS (label 801234, exp 0, [S], ttl 63) IP 17.0.0.1 > 1.2.3.4: ICMP echo request, id 31522, seq 25, length 64
### Ping from R2 to the Anycast 1.2.3.4 is OK:
root@R2# run ping 1.2.3.4 source 17.0.0.2
PING 1.2.3.4 (1.2.3.4): 56 data bytes
64 bytes from 1.2.3.4: icmp_seq=0 ttl=62 time=4.233 ms
64 bytes from 1.2.3.4: icmp_seq=1 ttl=62 time=4.423 ms
^C
--- 1.2.3.4 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max/stddev = 4.233/4.328/4.423/0.095 ms
### With tcpdump we can capture the packet on the bottom link R4-R5:
15:44:57.854831 MPLS (label 801234, exp 0, [S], ttl 63) IP 17.0.0.2 > 1.2.3.4: ICMP echo request, id 30496, seq 3, length 64
This demonstrates that when pinging from R1, the request goes to R7. But when pinging from R2, the requests goes to R8 instead.
External Resources: