Skip to content

Multicast Routing (layer 3)

T-X edited this page Jan 27, 2025 · 31 revisions

Overview

Multicast applications are often not that interesting with only a few listeners. The strength of multicast over unicast unfolds the more multicast listeners participate. On the other hand multicast applications are still niche, leading to a chicken and egg problem.

One way to address this issue could be to make sure multicast packets in one Freifunk Gluon domain can reach any other domain or even other Freifunk community. A protocol which can achieve this is PIM, Protocol Independent Multicast. The following describes the setup of how this was achieved in a test between Freifunk Lübeck (currently uses a 200 nodes single domain setup) and a domain at Freifunk Vogtland via pim6sd.

pim-gluon-setup pim-gluon-setup.svg

In this test case "Server @FFHL" and "Server @FFV" are actually both on the same physical server at FFHL. And the link between the pim6sd containers is then a veth pair installed via Proxmox (interface "ff_hl_v_mc_link" below). But the link between these containers can be a VPN tunnel interface instead, too.

pim-gluon-setup-interfaces pim-gluon-setup-interfaces.svg

Configuration

Gluon

A standard Gluon. All nodes in the network need at least Gluon v2021.1, to have the batman-adv multicast optimizations enabled. Nodes with multicast listeners wanting to receive routed multicast packets need at least Gluon v2021.1(check). Nodes with a multicast sender wanting to have their packets routed need at least Gluon v2022.1 (for batman-adv v2019.3). Nodes with a multicast router (like what this page focuses on) need at least Gluon v2023.2.

It is also recommended to have all nodes at least on batman-adv v2024.0, to be able to make use of the new batman-adv multicast packet type (either through the upcoming Gluon / OpenWrt 24.10 release, or through the gluon-batman-adv-next package feed, which also works for the deprecated 4/32MB devices.

It is also highly recommended to have gluon-mesh-batman-adv-brmldproxy installed on all nodes that have multicast listeners wanting to receive routed multicast packets and nodes that have a multicast router. Alternatively, but not very recommended, especially with larger broadcast domains, nodes with such multicast listeners and multicast routers would need to have filter_membership_reports=true in their site.conf.

Check the output of batctl mcast_flags. It should basically just show [U... . .] for/on all nodes. Except for the pim6sd, multicast router Gluon node the flags should show [U... R6.]. Any extra flag in there will likely mean that this or some other node will receive many more packets than necessary. See the batctl README for details.

Gluon Multicast Version History

Mainly for my own reference, to justify the version requirements outlined in the previous paragraph.

Milestones:

Gluon OpenWrt Linux batman-adv
2021.1[0] 19.07 4.14 v2019.2[1]
v2019.3[2]
- 21.02 5.4 v2021.1
v2021.2[3]
2022.1 22.03 5.10 v2022.0
5.14[4]
2023.2 23.05 5.15 v2023.1
v2024.0[5]
main 24.10 6.6 v2024.3

pim6sd container

The following examples are for a pim6sd container at FFHL. Addresses and prefixes need to be changed appropriately for another community/domain.

systemd-networkd

/etc/systemd/network/20-eth0-pim-router-id.network:

# /etc/systemd/network/20-eth0-pim-router-id.network
[Match]
Name=eth0

[Network]
Address=2001:67c:2d50::2/128

/etc/systemd/network/25-pim-router-id.netdev:

# /etc/systemd/network/25-pim-router-id.netdev
[NetDev]
Name=pim-router-id
Kind=dummy

25-pim-router-id.network:

# /etc/systemd/network/25-pim-router-id.network
[Match]
Name=pim-router-id

[Network]
Address=2001:67c:2d50::2/128

[Link]
Multicast=true

25-ff_hl_v_mc_link.network:

# /etc/systemd/network/25-ff_hl_v_mc_link.network
[Match]
Name=ff_hl_v_mc_link

Babel

Babel will take care of learning unicast addresses from neighbors and neighbors' neighbors on ff_hl_v_mc_link. PIM relies on previously established unicast routing table. Without Babel in this case PIM would (try to) route multicast packets via its IPv6 default route over eth0 and the Gluon mesh node. Instead of using the direct link through the ff_hl_v_mc_link interface.

/etc/default/babeld:

# Defaults for babeld initscript
# sourced by /etc/init.d/babeld

# List of interfaces on which the protocol should operate
INTERFACES="ff_hl_v_mc_link"

# Additional arguments
DAEMON_ARGS="-S /var/lib/babeld/state"

ToDo:

  • check if maybe only redistributing the PIM router ID IP addresses would be enough? E.g. by adding something like: redistribute local deny; redistribute local if pim-router-id allow

pim6sd

Source: https://github.com/troglobit/pim6sd

  • learn PIM router ID from pim-router-id interface
  • MLD: learn local multicast listeners on eth0
  • PIM: learn remote/routed multicast listeners + multicast senders on ff_hl_v_mc_link

/etc/pim6sd.conf:

# /etc/pim6sd.conf
# disable all interfaces by default
default_phyint_status disable;

# enable the pim-router-id interface first to acquire the correct primary address
phyint pim-router-id enable;

# Even with "nolistener", MLD reports will be parsed.
# However this allows disabling the MLD querier.
# Gluon provides the querier and we use mrdisc to
# announce ourself via MRD.
phyint eth0 nolistener mld_version any enable;

# This one is for PIM / routing, not listeners / MLD.
# Add more interfaces as required below
phyint ff_hl_v_mc_link nolistener enable;

# configure rendezvous point for the personal multicast prefix
cand_rp pim-router-id;
group_prefix ff7e:240:2001:67c:2d50::/96;

Embedded Rendezvous Point (RP) Calculation

Embedded RP, RFC3956, allows you to derive your own multicast subnet from your unicast prefix. group_prefix ff7e:240:2001:67c:2d50::/96 above was calculated as follows:

  • Pattern: ff7e:<RIID><plen>:<prefix>::/96
    • Prefix at FFHL: 2001:67c:2d50::/64
    • Prefix length: 64 == 0x40
    • RIID: An arbitrary number between 0x1 and 0xf, for instance 0x2
  • Result:
    • Multicast prefix: ff7e:240:2001:67c:2d50::/96
    • RP address: 2001:67c:2d50::<RIID> -> 2001:67c:2d50::2

mrdisc

Source: https://github.com/troglobit/mrdisc

Announce our own multicast router to upstream / our Gluon node via MRD (Multicast Router Discovery, RFC4286). batman-adv will detect this and will then route all routeable IPv6 multicast packets to this node. With the gluon-mesh-batman-adv-brmldproxy package a Gluon node will also enable its MLD querier (candidate), so that this host and its pim6sd daemon will be able to learn about multicast listeners/receivers from their (proxied) MLD reports in response to an MLD query.

/etc/systemd/system/[email protected]:

# /etc/systemd/system/[email protected]
# https://github.com/troglobit/mrdisc
# enable like this for instance: $ systemctl enable [email protected]
[Unit]
Description=Multicast Router Discovery daemon (RFC4286)
BindsTo=pim6sd.service

[Service]
Type=exec
RestartSteps=10
RestartMaxDelaySec=30
Restart=always
ExecStart=mrdisc -6 %i

[Install]
WantedBy=multi-user.target

Then run:

Clone this wiki locally