Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gluon-mesh-batman-adv-brmldproxy: add package #2995

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ Several Freifunk communities in Germany use Gluon as the foundation of their Fre
package/gluon-hoodselector
package/gluon-logging
package/gluon-mesh-batman-adv
package/gluon-mesh-batman-adv-brmldproxy
package/gluon-mesh-wireless-sae
package/gluon-radv-filterd
package/gluon-scheduled-domain-switch
Expand Down
29 changes: 29 additions & 0 deletions docs/package/gluon-mesh-batman-adv-brmldproxy.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
gluon-mesh-batman-adv-brmldproxy
================================

The *gluon-mesh-batman-adv-brmldproxy* package adds configuration
to enable `brmldproxy`_ in Gluon with batman-adv.

If `filter_membership_reports` :ref:`site.conf <user-site-mesh>` is false in the site.conf
then no multicast listener is filtered, but the node will
respond on behalf of any of its local listeners, potentially
reducing duplicate MLD report overhead.

If `filter_membership_reports` :ref:`site.conf <user-site-mesh>` is true in the site.conf
or absent then brmldproxy is additionally configured to
only send MLD reports for routeable IPv6 multicast addresses
and only to detected IPv6 multicast routers. If no such
router is detected or no local listeners for routeable
IPv6 multicast addresses exists then no MLD report is send
into the mesh. Which greatly reduces MLD overhead while
still allowing the usage of layer 3 IPv6 multicast routers.
This is the recommended setting especially in larger meshes.

----

Notable layer 3 IPv6 multicast router implementations:

* pim6sd: https://github.com/troglobit/pim6sd
* HowTo at DN42: https://dn42.dev/howto/IPv6-Multicast

.. _brmldproxy: https://github.com/T-X/brmldproxy
19 changes: 16 additions & 3 deletions docs/package/gluon-mesh-batman-adv.rst
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,16 @@ batman-adv. Which even with IGMP/MLD filtered, will have full multicast
membership knowledge through its own propagation through the batman-adv
translation table.

Advantages are:
**Advantages:**

* Reduced overhead through reactive batman-adv multicast TT vs.
periodic IGMP/MLD messages in the mesh
* Increased IGMP/MLD snooping robustness via local, per node
IGMP/MLD queriers
* DDoS vector mitigation

**Limitations:**

**Note:** For nodes running an operating system other than Gluon, but a bridge
interface on top of the batman-adv interface, you will need to set the
multicast router flag there manually:
Expand All @@ -159,12 +161,23 @@ assume that there is no multicast router behind this port, meaning
to only forward multicast to this port if an according multicast
listener on this link was detected.

Further limitations: IGMP/MLD snooping switches (e.g. "enterprise switches")
IGMP/MLD snooping switches (e.g. "enterprise switches")
behind the client network of a node (LAN ports) are unsupported. It is
advised to disable IGMP/MLD snooping on those enterprise switches for now
or to at least manually mark the port to the Gluon router as a
"multicast router port".

Alternatively, the filtering of IGMP/MLD reports can be disabled via
Also IPv4/IPv6 multicast routers are unsupported, unless the
:doc:`gluon-mesh-batman-adv-brmldproxy` package is installed.

**Configuration options:**

The filtering of IGMP/MLD reports can be disabled via
the site.conf (which is not recommended in large meshes though).
See :ref:`site.conf mesh section <user-site-mesh>` for details.

Another alternative is to install the :doc:`gluon-mesh-batman-adv-brmldproxy`
package. Which allows proxied MLD reports for listeners of
routable IPv6 multicast addresses, while keeping link-local
IPv6 multicast addresses filtered. This allows using IPv6
multicast routers.
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
local site = require 'gluon.site'

local function file_exists(file)
local f = io.open(file)
if not f then
return false
end
f:close()
return true
end

rule('MULTICAST_IN -p IPv4 --ip-protocol igmp --ip-igmp-type membership-query -j DROP', 'nat')
rule('MULTICAST_OUT -p IPv4 --ip-protocol igmp --ip-igmp-type membership-query -j DROP')

Expand All @@ -14,7 +23,10 @@ if site.mesh.filter_membership_reports(true) then
rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 132 -j DROP') -- MLDv1 Done
rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 143 -j DROP') -- MLDv2 Report

rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 131 -j DROP', 'nat') -- MLDv1 Report
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these be allowed unconditionally, or only when the feature is enabled?

rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 132 -j DROP', 'nat') -- MLDv1 Done
rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 143 -j DROP', 'nat') -- MLDv2 Report
# only install if gluon-mesh-batman-adv-brmldproxy is not
if not file_exists("/lib/gluon/upgrade/400-brmldproxy") then
rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 131 -j DROP', 'nat') -- MLDv1 Report
rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 132 -j DROP', 'nat') -- MLDv1 Done
rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 143 -j DROP', 'nat') -- MLDv2 Report
end
end
36 changes: 36 additions & 0 deletions package/gluon-mesh-batman-adv-brmldproxy/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
include $(TOPDIR)/rules.mk

PKG_NAME:=gluon-mesh-batman-adv-brmldproxy

include ../gluon.mk

define Package/gluon-mesh-batman-adv-brmldproxy
TITLE:=Bridge MLD Proxy for Gluon
DEPENDS:=+brmldproxy gluon-mesh-batman-adv
endef

define Package/gluon-mesh-batman-adv-brmldproxy/description
Gluon community wifi mesh firmware framework: Configuration to
enable brmldproxy in Gluon with batman-adv.

If filter_membership_reports is false in the site.conf
then no multicast listener is filtered, but the node will
respond on behalf of any of its local listeners, potentially
reducing duplicate MLD report overhead.

If filter_membership_reports is true in the site.conf
or absent then brmldproxy is additionally configured to
only send MLD reports for routeable IPv6 multicast addresses
and only to detected IPv6 multicast routers. If no such
router is detected or no local listeners for routeable
IPv6 multicast addresses exists then no MLD report is send
into the mesh. Which greatly reduces MLD overhead while
still allowing the usage of layer 3 IPv6 multicast routers.
This is the recommended setting especially in larger meshes.
endef

define Package/gluon-mesh-batman-adv-brmldproxy/conffiles
/etc/config/brmldproxy
endef

$(eval $(call BuildPackageGluon,gluon-mesh-batman-adv-brmldproxy))
1 change: 1 addition & 0 deletions package/gluon-mesh-batman-adv-brmldproxy/check_site.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
need_boolean({'mesh', 'filter_membership_reports'}, false)
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/sh

([ "$INTERFACE" != "bat0" ] || [ "$ACTION" != "ifup" ]) && exit 0

lookup_site() {
local path="$1" default="$2"
lua -e "print(require('gluon.site').$path('$default'))"
}

[ "$(lookup_site 'mesh.filter_membership_reports' 'true')" = "false" ] && exit 0

batctl multicast_mld_rtr_only 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/lua

local site = require 'gluon.site'
local uci = require('simple-uci').cursor()

local excludefilters = { 'ff00::/ff0e::' }
if site.mesh.filter_membership_reports(true) then
table.insert(excludefilters, 'ff02::/ff0f::')
table.insert(excludefilters, 'ff05::2:1001')
end

uci:delete('brmldproxy', 'client')
uci:section('brmldproxy', 'brmldproxy', 'client', {
disabled = 0,
bridge = 'client',
family = 'ipv6',
proxiedport = { 'bat0' },
excludedport = { 'local-port' },
excludefilter = excludefilters,
})
uci:save('brmldproxy')

-- Allow incoming MLD on brmldp0/1/... devices
uci:section('firewall', 'rule', 'brmldproxy_mld_in', {
name = 'brmldproxy_mld_in',
device = 'brmldp+',
direction = 'in',
src = '*',
src_ip = 'fe80::/10',
target = 'ACCEPT',
family = 'ipv6',
proto = 'icmp',
icmp_type = { '130/0', '131/0', '132/0', '143/0', },
})

-- Fix default mark of MLDv2 reports (bug in the Linux IPv6 stack)
-- See: https://marc.info/?l=netfilter&m=168959399302909
-- Subject: skb->mark not cleared for MLDv2 Reports? (skb->mark == 212 / 0xd4)
uci:section('firewall', 'rule', 'brmldproxy_mldv2_mark_fixup', {
name = 'brmldproxy_mldv2_mark_fixup',
device = 'brmldp+',
direction = 'out',
dest = '*',
src_ip = 'fe80::/10',
target = 'MARK',
set_mark = '0x0',
family = 'ipv6',
proto = 'icmp',
icmp_type = { '143/0', },
})

uci:save('firewall')
Loading
Loading