Multicast VPN Extranet

This post talks about how you can do inter-VRF multicast using BGP VPNv4 multicast (SAFI 129).

You might have seen this guide on Cisco.com
Configuring Multicast VPN Extranet Support

They suggest leaking unicast routes between VRFs which isn’t required for this to work.

I’m using this topology to go through the configuration:

Our source is R9 in VRF a which is configured as rosen draft on R10 and R12. The configuration hereof is plain:

! R10
vrf definition a
rd 10.10.10.10:10
route-target export 65000:10
route-target import 65000:10
!
address-family ipv4
mdt default 232.0.0.10
mdt data 232.0.1.0 0.0.0.255 threshold 1
mdt data threshold 1
exit-address-family
!
router bgp 65000
bgp router-id 10.10.10.10
bgp log-neighbor-changes
no bgp default ipv4-unicast
neighbor 11.11.11.11 remote-as 65000
neighbor 11.11.11.11 update-source Loopback0
!
address-family vpnv4
neighbor 11.11.11.11 activate
neighbor 11.11.11.11 send-community extended
exit-address-family
!
address-family vpnv4 multicast
neighbor 11.11.11.11 activate
neighbor 11.11.11.11 send-community extended
exit-address-family
!
address-family ipv4 mdt
neighbor 11.11.11.11 activate
neighbor 11.11.11.11 send-community extended
exit-address-family
!
address-family ipv4 vrf a
neighbor 10.0.109.9 remote-as 65009
neighbor 10.0.109.9 activate
exit-address-family
!
address-family ipv4 multicast vrf a
network 10.0.109.0 mask 255.255.255.0
exit-address-family

What might not seem so plain with this configuration, is the BGP part. With L3 MPLS VPNs we’re used to configuring `address-family vpnv4` which implies unicast. Since we’re not interested in using unicast for RPF, we need some way of distributing multicast routes for RPF checks. This we can do using a multicast address-family. In this case I’m using VPNv4 multicast which gives us the capability of using importing the because of route-targets. Specifically we’re exporting the prefix 10.0.109.0/24 into VPNv4 multicast.

Let’s look at the other side, R12.

! R12
vrf definition a
rd 12.12.12.12:10
route-target export 65000:10
route-target import 65000:10
!
address-family ipv4
mdt default 232.0.0.10
mdt data 232.0.1.0 0.0.0.255 threshold 1
mdt data threshold 1
exit-address-family
!
vrf definition b
ipv4 multicast multitopology
rd 12.12.12.12:11
route-target export 65000:11
route-target import 65000:11
!
address-family ipv4
exit-address-family
!
address-family ipv4 multicast
topology base
route-replicate from vrf a multicast all

!
exit-address-family
!
router bgp 65000
bgp router-id 12.12.12.12
bgp log-neighbor-changes
no bgp default ipv4-unicast
neighbor 11.11.11.11 remote-as 65000
neighbor 11.11.11.11 update-source Loopback0
!
address-family ipv4
neighbor 11.11.11.11 activate
exit-address-family
!
address-family vpnv4
neighbor 11.11.11.11 activate
neighbor 11.11.11.11 send-community extended
exit-address-family
!
address-family vpnv4 multicast
neighbor 11.11.11.11 activate
neighbor 11.11.11.11 send-community extended
exit-address-family
!
address-family ipv4 mdt
neighbor 11.11.11.11 activate
neighbor 11.11.11.11 send-community extended
exit-address-family
!
address-family ipv4 vrf b
neighbor 10.12.14.14 remote-as 65014
neighbor 10.12.14.14 activate
exit-address-family

Now the fun begins. Instead of leaking unicast routes using RTs, we configure the address-family ipv4 multicast under the receiver vrf, VRF b. Note, this requires you to configure multicast multitopology first. Now we can replicate the multicast routes from VRF a into VRF b. In this case I import all multicast routes, but one could specify a route-map making the import focus on specific multicast routes.

R12# sh bgp vpnv4 multicast vrf a 10.0.109.0/24
BGP routing table entry for 12.12.12.12:10:10.0.109.0/24, version 13
Paths: (1 available, best #1, table a:multicast)
Not advertised to any peer
Refresh Epoch 7
Local, imported path from 10.10.10.10:10:10.0.109.0/24 (global)
10.10.10.10 (metric 3) (via default) from 11.11.11.11 (11.11.11.11)
Origin IGP, metric 0, localpref 100, valid, internal, best
Extended Community: RT:65000:10
Originator: 10.10.10.10, Cluster list: 11.11.11.11
Connector Attribute: count=1
type 1 len 12 value 10.10.10.10:10:10.10.10.10
rx pathid: 0, tx pathid: 0x0
R12#
R12#sh ip route multicast vrf b bgp | be +
+ - replicated route, % - next hop override
Gateway of last resort is not set

10.0.0.0/8 is variably subnetted, 5 subnets, 2 masks
B + 10.0.109.0/24 [200/0] via 10.10.10.10, 00:08:32
R12#
R12#sh ip rpf vrf b 10.0.109.10
RPF information for ? (10.0.109.10)
RPF interface: Tunnel1
RPF neighbor: ? (10.10.10.10)
RPF route/mask: 10.0.109.0/24
RPF type: multicast (bgp 65000)
Doing distance-preferred lookups across tables
Using Extranet RPF Rule: BGP Imported Route, RPF VRF: b
RPF topology: ipv4 multicast base, originated from ipv4 unicast base
R12#

So now we’re able to perform RPF check in the receiver vrf, VRF b, on the 10.0.109.0/24 prefix which is where the RP in VRF a is located, on R10. Let’s look at the RP configuration:

! R10
ip pim vrf a bsr-candidate GigabitEthernet1.109 0
ip pim vrf a rp-candidate GigabitEthernet1.109

! R12
ip pim vrf b rp-address 10.0.109.10

! Verification:
R12#sh ip pim vrf a rp mapping
PIM Group-to-RP Mappings
Group(s) 224.0.0.0/4
RP 10.0.109.10 (?), v2
Info source: 10.0.109.10 (?), via bootstrap, priority 0, holdtime 150
Uptime: 00:15:54, expires: 00:01:45
R12#
R12#sh ip pim vrf b rp mapping
PIM Group-to-RP Mappings
Group(s): 224.0.0.0/4, Static
RP: 10.0.109.10 (?)
R12#

Now if we join a multicast group on R14, our receiver, we should be state all the way to the RP on R10. Let’s try:

! R14
interface GigabitEthernet1.1214
encapsulation dot1Q 1214
ip address 10.12.14.14 255.255.255.0
ip pim dr-priority 0
ip pim sparse-mode
ip igmp join-group 224.10.11.14

! R12
R12#sh ip mroute vrf b 224.10.11.14 | be (
(*, 224.10.11.14), 00:00:15/stopped, RP 10.0.109.10, flags: SJC
Incoming interface: Tunnel1, RPF nbr 10.10.10.10, using vrf a, Mbgp
Outgoing interface list:
GigabitEthernet1.1214, Forward/Sparse, 00:00:15/00:02:56
R12#
R12#sh ip mroute vrf a 224.10.11.14 | be (
(*, 224.10.11.14), 00:01:15/00:01:44, RP 10.0.109.10, flags: SJCE
Incoming interface: Tunnel1, RPF nbr 10.10.10.10, Mbgp
Outgoing interface list: Null
Extranet receivers in vrf b:
(*, 224.10.11.14), 00:01:15/stopped, RP 10.0.109.10, OIF count: 1, flags: SJC
R12#

! R10
R10#sh ip mroute vrf a 224.10.11.14 | be (
(*, 224.10.11.14), 00:01:44/00:02:45, RP 10.0.109.10, flags: S
Incoming interface: Null, RPF nbr 0.0.0.0
Outgoing interface list:
Tunnel2, Forward/Sparse, 00:01:44/00:02:45
R10#

Great! We have multicast state for 224.10.11.14 all the way through VRF b to VRF a on R12 and to VRF a on R10. Notice the IIL (Incoming Interface List) on R10 is Null, because we haven’t generated any traffic for this group yet. But the main thing is that we have state, and we can actually see the connection between the VRFs on R12 in VRF a.

Last thing to do is check reachability by pinging the group on R9, our source.

! R9
R9#ping 224.10.11.14 rep 10
Type escape sequence to abort.
Sending 10, 100-byte ICMP Echos to 224.10.11.14, timeout is 2 seconds:
………
R9#

! R10
R10#show ip mfib vrf a 224.10.11.14 count
Forwarding Counts: Pkt Count/Pkts per second/Avg Pkt Size/Kilobits per second
Source: 10.0.109.9,
SW Forwarding: 0/0/0/0, Other: 0/0/0
HW Forwarding: 10/0/117/0, Other: 0/0/0
R10#
R10#sh ip mroute vrf a 224.10.11.14 | be \(10.0.109.
(10.0.109.9, 224.10.11.14), 00:02:34/00:00:25, flags: T
Incoming interface: GigabitEthernet1.109, RPF nbr 10.0.109.9
Outgoing interface list:
Tunnel2, Forward/Sparse, 00:02:34/00:03:06
R10#

! R12
R12#sh ip mroute vrf a 224.10.11.14 | be \(10.0.109.
(10.0.109.9, 224.10.11.14), 00:02:21/00:00:38, flags: JTE
Incoming interface: Tunnel1, RPF nbr 10.10.10.10, Mbgp
Outgoing interface list: Null
Extranet receivers in vrf b:
(10.0.109.9, 224.10.11.14), 00:02:21/stopped, OIF count: 1, flags: T
R12#
R12#sh ip mroute vrf b 224.10.11.14 | be \(10.0.109.
(10.0.109.9, 224.10.11.14), 00:00:11/stopped, flags: T
Incoming interface: Tunnel1, RPF nbr 10.10.10.10, using vrf a, Mbgp
Outgoing interface list:
GigabitEthernet1.1214, Forward/Sparse, 00:00:11/00:02:48
R12#
R12#sh ip pim vrf a mdt
implies mdt is the default MDT, # is (,) Wildcard,
is non-(,) Wildcard
MDT Group/Num Interface Source VRF
232.0.0.10 Tunnel1 Loopback0 a
R12#
R12#sh ip pim vrf a mdt bgp
MDT (Route Distinguisher + IPv4) Router ID Next Hop
MDT group 232.0.0.10
12.12.12.12:10:10.10.10.10 11.11.11.11 10.10.10.10
R12#

Note the E flag in the above output: E – Extranet

And the IIL in VRF b is Tunnel1 which is the multicast tunnel interface for our rosen draft implementation using group address 232.0.0.10 for transport in VRF a. And we build the tunnel with R10 which is the VPNv4 next-hop for 232.0.0.10.

Oh, and it did look like the pings didn’t work, but with a debug ip icmp on R14, we can in fact see, that R14 tries to reply, but since it doesn’t have a unicast route back to 10.0.109.9, the reply never reaches R9.

! R14
*Jan 4 16:09:58.357: ICMP: echo reply sent, src 10.12.14.14, dst 10.0.109.9, topology BASE, dscp 0 topoid 0

That’s all for now. I hope you enjoyed seeing one way of using BGP to provide RPF check for an inter-VRF multicast extranet solution. And alternative could be static mroutes or the ip multicast rpf select feature.