Multicast

The RPF Check: How Multicast Prevents Loops

Multicast RPF check - feature image showing a broken RPF and the static mroute fix on IOS XE
In: Multicast, Labs

Unicast routing looks forward: where is this packet going? Multicast routing looks backward: did this packet arrive from the right direction? That reversal is the reverse path forwarding check, and it is both the reason multicast never loops and the single most common reason a multicast stream silently dies. This article explains the rule, then deliberately breaks it in the lab and fixes it with a static mroute, with real output at every step. Part of the IP multicast guide.

The Rule in One Sentence

A router accepts a multicast packet only if it arrives on the interface the router would itself use to send unicast traffic back to the packet's source; otherwise the packet is dropped, no error generated, no ICMP sent.

Why so strict? A multicast packet is addressed to a group, not a destination, so a router cannot forward it "toward" anything; it copies the packet out multiple interfaces. If two routers both copy the same packet toward each other, it loops forever, and multicast loops amplify because each pass replicates. RPF kills every such loop at the first hop: a looped packet necessarily arrives on a wrong-direction interface and fails the check. TTL would eventually stop a unicast loop; multicast cannot afford "eventually".

The check runs against the unicast routing table (this is the "protocol independent" in PIM). It also determines topology: the RPF interface toward the source (or the RP, for shared trees) becomes the incoming interface of the mroute entry, and PIM joins are sent out of it. RPF is not just a filter; it is how PIM sparse mode decides where trees grow.

Reading a Healthy RPF

The lab: a Debian VM receiver behind R1, a source at 10.0.30.10 three hops away, OSPF area 0 underlay. One command shows the whole story:

R1# show ip rpf 10.0.30.10
RPF information for ? (10.0.30.10)
  RPF interface: Ethernet0/1
  RPF neighbor: ? (10.0.12.2)
  RPF route/mask: 10.0.30.0/24
  RPF type: unicast (ospf 1)
  Doing distance-preferred lookups across tables

Ethernet0/1 is where OSPF routes 10.0.30.0/24; multicast from that source must arrive there. The corresponding mroute entry is healthy, forwarding on the source tree:

R1# show ip mroute 239.1.1.10
(10.0.30.10, 239.1.1.10), 00:00:05/00:02:54, flags: JT
  Incoming interface: Ethernet0/1, RPF nbr 10.0.12.2
  Outgoing interface list:
    Ethernet0/0, Forward/Sparse, 00:00:05/00:02:54

Breaking It on Purpose

RPF failures happen when the unicast table disagrees with where multicast actually arrives: asymmetric routing, a static route someone added for a maintenance window, tunnel interfaces, or a multicast-free path in an otherwise fine network. To reproduce the classic case, the lab gets a deliberately wrong static route on R1, pointing the source subnet out the receiver-facing interface:

R1(config)# ip route 10.0.30.0 255.255.255.0 192.168.99.100

The static route (admin distance 1) beats OSPF (110), so the RPF lookup now resolves to the wrong interface:

R1# show ip rpf 10.0.30.10
RPF information for ? (10.0.30.10)
  RPF interface: Ethernet0/0
  RPF neighbor: ? (192.168.99.100)
  RPF route/mask: 10.0.30.0/24
  RPF type: unicast (static)

Multicast still arrives on Ethernet0/1, where it has always arrived. But the router now insists it should arrive on Ethernet0/0. Every packet fails the check, and the mroute entry collapses:

R1# show ip mroute 239.1.1.10
(*, 239.1.1.10), 00:04:12/stopped, RP 2.2.2.2, flags: SJC
  Incoming interface: Ethernet0/1, RPF nbr 10.0.12.2

(10.0.30.10, 239.1.1.10), 00:00:43/00:02:15, flags: PJX
  Incoming interface: Ethernet0/0, RPF nbr 192.168.99.100
  Outgoing interface list: Null

Compare with the healthy entry: the incoming interface flipped to Ethernet0/0, the P flag (pruned) appeared, and the outgoing list went Null. The stream is dead, and nothing logged anything. This exact signature, wrong incoming interface plus Null OIL, is what you hunt for in multicast troubleshooting. On platforms with show ip mroute count, the RPF failed drop counter climbing confirms it numerically.

The Fix: Static Mroute

Two fixes exist. The right long-term fix is repairing the unicast topology so it matches where multicast flows. But when the asymmetry is intentional (multicast engineered onto a different path than unicast, or a unicast-only firewall in the nominal path), IOS XE lets you override the RPF lookup specifically for multicast, without touching unicast routing:

R1(config)# ip mroute 10.0.30.0 255.255.255.0 10.0.12.2

A static mroute is not a route: it never forwards anything. It is an RPF instruction: "for sources in 10.0.30.0/24, expect multicast via next hop 10.0.12.2". The RPF source flips immediately:

R1# show ip rpf 10.0.30.10
RPF information for ? (10.0.30.10)
  RPF interface: Ethernet0/1
  RPF neighbor: ? (10.0.12.2)
  RPF type: multicast (static)
  RPF topology: ipv4 multicast base

Note the type change: multicast (static), and the topology line no longer says "originated from ipv4 unicast base". The mroute entry heals on the next join cycle, with the incoming interface tagged as mroute-derived:

R1# show ip mroute 239.1.1.10
(10.0.30.10, 239.1.1.10), 00:01:18/00:01:41, flags: JT
  Incoming interface: Ethernet0/1, RPF nbr 10.0.12.2, Mroute
  Outgoing interface list:
    Ethernet0/0, Forward/Sparse, 00:00:16/00:02:43

JT flags restored, traffic flowing, unicast table still wrong and unicast routing entirely unaffected. That separation is the point: static mroutes decouple the multicast RPF topology from unicast routing where they must differ. (The broken static route was removed after this capture; the demo only needed it to exist long enough to fail.)

Where RPF Bites in Real Networks

  • Asymmetric paths. Traffic engineering, unequal-cost designs, or policy routing put the return path somewhere multicast does not flow. The RPF interface is legal but multicast-dead.
  • Tunnels and overlays. Multicast rides a GRE tunnel (see the GRE guide) but unicast prefers the underlay: instant RPF failure without a static mroute or IGP adjustment over the tunnel.
  • ECMP. With equal-cost paths, the RPF tiebreak picks the neighbor with the highest IP address. Predictable, but only if you know the rule; "why does all multicast prefer that link" tickets come from here.
  • Shared trees too. RPF applies to the RP for (*,G) state as well. If the unicast route to the RP is wrong, receivers never even build a working shared tree.

Two Lookups, Not One: (*,G) vs (S,G)

A subtlety that matters in troubleshooting: a PIM-SM router runs RPF against different targets depending on which tree the state belongs to. For (*,G) shared-tree entries, the check targets the RP address, because the RP is the root of that tree; for (S,G) entries, it targets the source. That means one group can be healthy on its shared tree and RPF-dead on its source tree simultaneously, which is exactly what the broken state above shows: the (*,G) kept its correct incoming interface toward the RP while the (S,G) collapsed, because only the route to the source was poisoned.

The practical consequence: when you check RPF, check it against the right address. A receiver stuck before the SPT switchover needs show ip rpf <RP>; a stream dying after switchover needs show ip rpf <source>. And when an RP itself cannot pull traffic from a registering source, the RP's own RPF toward the source is the lookup to inspect. The order of preference IOS XE applies to each lookup is also worth knowing: static mroutes win first, then MBGP multicast address-family routes if you run them, then the plain unicast table; "distance-preferred lookups across tables" in the command output is that policy talking.

Verification Workflow

When a stream is missing, the RPF portion of the investigation is three commands on each router along the expected path, upstream from the receiver: show ip rpf <source> (does the RPF interface match where the stream physically arrives?), show ip mroute <group> (is the incoming interface right, is the OIL non-Null, are the flags sane?), and show ip route <source> (what unicast entry is feeding the lookup?). The router where the RPF interface and the actual arrival interface disagree is your culprit. Fix the routing or add the static mroute, and confirm the P flag clears.

Key Takeaways

  • RPF accepts multicast only on the interface that unicast routing would use toward the source. Everything else is dropped silently.
  • The check is multicast's loop prevention and its topology engine: the RPF interface becomes the mroute incoming interface and the direction PIM joins travel.
  • The failure signature is unmistakable: wrong incoming interface, P flag, Null OIL, and zero log messages.
  • ip mroute creates a static RPF override, not a forwarding route. It fixes multicast asymmetry without touching unicast routing, and shows up as "RPF type: multicast (static)" plus an Mroute tag in the entry.
  • Suspect RPF first with tunnels, asymmetric designs, and ECMP (highest neighbor IP wins the tiebreak).

Related: PIM sparse mode for the trees this check protects, and the complete multicast guide for the full cluster.

Written by
More from Ping Labz
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Ping Labz.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.