Inspect the Multicast Routing Cache with ip mroute

An empty result from ip mroute show can mean a genuinely empty cache, or a wrong filter. This guide uses ip mroute to inspect the multicast routing cache, apply its selectors, and tell an empty result from a failed query. The installed system uses iproute2 6.1.0, package version 6.1.0-1ubuntu6.4.

Allow about ten minutes. You need a shell and a host where a multicast routing daemon may be running. This guide is entirely read-only, it does not start a daemon, add a route, enable multicast forwarding, or alter an interface. The command can only display these cache objects: the current kernel interface gives no administrative change operation through ip mroute.

1. Confirm the installed command

Check the binary and version before you trust the output, ordinary commands, no elevated privileges needed:

$ command -v ip
/usr/sbin/ip
$ ip -V
ip utility, iproute2-6.1.0, libbpf 1.3.0
$ dpkg-query -W -f='${Package} ${Version}\n' iproute2
iproute2 6.1.0-1ubuntu6.4

Useful for comparing a report against another host. A newer distribution is not guaranteed to give you the same diagnostics or multicast-table behaviour.

2. Display the cache

Start with the plain command:

$ ip mroute show

On this machine it returns successfully with no lines, because there is nothing to display. On a router running a user-space multicast routing daemon, an entry can carry a source, multicast destination, incoming interface and outgoing interfaces. Lines are host-specific, so an empty result here is not proof the command is broken.

Checkpoint: capture the exit status too if you are diagnosing a script or monitoring check:

$ ip mroute show
$ printf 'status=%s\n' "$?"
status=0

Status 0 means the query completed, not that the cache held an entry.

3. Use the interface selector

To list entries whose multicast packets arrive through a particular interface, use iif plus the interface name:

$ ip mroute show iif lo
$ printf 'status=%s\n' "$?"
status=0

lo exists on any normal Linux host, so it is a safe smoke test. Swap in the real receiving interface when investigating an actual flow, such as eth0 or ens3. The selector creates nothing, an empty result just means no displayed entry matched that incoming interface.

Check names before copying one into a script:

$ ip link show

Also read-only. Do not confuse this iif filter with a command that actually changes an interface's multicast or forwarding configuration.

4. Select a multicast destination or source

The manual defines to PREFIX for destination multicast addresses and from PREFIX for source addresses. Use a prefix you know exists in the cache, not one guessed from an application config:

$ ip mroute show to MULTICAST_PREFIX
$ ip mroute show from SOURCE_PREFIX

Swap in the prefixes that matter for your deployment. Keep the placeholder in place until you have a real value from the daemon, a packet capture, or incident notes, a filter is a query, not a route declaration, and it cannot conjure a missing cache entry.

There is a genuine trap on this release: a syntactically plausible address is not automatically accepted as a multicast-route prefix in the current table context. This host, for example, rejects an arbitrary test prefix outright:

$ ip mroute show to 224.0.0.0/4
Error: ??? prefix is expected rather than "224.0.0.0/4"

Warning: do not silence that error and read the result as an empty cache. Check the address family, the prefix format the daemon expects, and whether a multicast route table even exists. The non-zero status is the important signal here, not the blank output.

5. Choose the multicast table

Use table when the host has more than one multicast table, or when you want the target table explicit. Documented names are local, main, default, all, or a numeric table ID:

$ ip mroute show table all
$ printf 'status=%s\n' "$?"
status=0

all is a good diagnostic first pass, asking across every available multicast table. On this host it is empty and succeeds. A named table can fail outright when that multicast table does not exist:

$ ip mroute show table main
Error: ipv4: MR table does not exist.
Dump terminated

Wording varies with kernel and iproute2 build. Treat a missing-table error as a configuration fact, not an empty result in disguise.

6. Combine filters without changing state

Once you have real values, combine selectors to narrow the investigation:

$ ip mroute show to MULTICAST_PREFIX from SOURCE_PREFIX iif RECEIVING_INTERFACE table all

Still a display operation throughout. No lines with status 0 means the selected entry is not present in that table right now. An error means keeping the diagnostic and status with the incident record, not turning it into a claim that traffic is absent.

For a repeatable check, save output without clobbering an existing capture:

$ ip mroute show table all > mroute-check.txt
$ test -s mroute-check.txt && echo 'entries were printed' || echo 'the query printed no entries'

Shell redirection creates or truncates mroute-check.txt, pick a new filename if an earlier result matters. None of the read-only examples above need sudo, elevate only if your host's normal access policy demands it and the command explicitly fails for that reason.

7. Find the real owner of a missing entry

ip mroute never populates the cache itself. The manpage describes these objects as created by a user-level multicast routing daemon such as pimd or mrouted. An empty cache means checking whether that daemon is installed and running, with your service manager's read-only status command:

$ systemctl status SERVICE_NAME --no-pager

Swap in the actual unit name, never guess one or start it during an investigation. A daemon, kernel multicast settings and live traffic all affect what the cache can show, review them separately, and use a maintenance window if a production router is involved.

There is no undo for anything in this guide because every command either reads state or writes a deliberately named text capture. Do not try to fix an empty cache by inventing an ip mroute add, this subcommand has no administrative add, change or delete operation at all.

Done means