gluon-ebtables: unconditionally segment IGMP/MLD
We must ensure that each node becomes IGMP/MLD querier for its local clients; having only a single querier for the whole mesh is generally unreliable, leading to frequent "IGMP/MLD querier appeared/disappeared" messages from batman-adv and unreliable snooping. In smaller meshes it might be interesting only segment querier domains, but allow membership reports to pass through the mesh, in order to support snooping switches outside the mesh without special configuration. A site.conf switch is provided to control this behaviour. Fixes #1320
This commit is contained in:
parent
7c9e1e1007
commit
17370d8462
@ -60,7 +60,6 @@ Several Freifunk communities in Germany use Gluon as the foundation of their Fre
|
||||
package/gluon-config-mode-geo-location
|
||||
package/gluon-ebtables-filter-multicast
|
||||
package/gluon-ebtables-filter-ra-dhcp
|
||||
package/gluon-ebtables-segment-mld
|
||||
package/gluon-ebtables-source-filter
|
||||
package/gluon-radv-filterd
|
||||
package/gluon-web-admin
|
||||
|
@ -1,16 +0,0 @@
|
||||
gluon-ebtables-segment-mld
|
||||
==========================
|
||||
|
||||
These filters drop IGMP/MLD packets before they enter the mesh and
|
||||
filter any IGMP/MLD packets coming from the mesh.
|
||||
|
||||
IGMP/MLD have the concept of a local, elected Querier. For more
|
||||
decentralization and increased robustness, the idea of this package is
|
||||
to split the IGMP/MLD domain a querier is responsible for, allowing to
|
||||
have a querier per node. The split IGMP/MLD domain will also reduce
|
||||
overhead for this packet type, increasing scalability.
|
||||
|
||||
Beware of the consequences of using this package though: You might need
|
||||
to explicitly, manually mark ports on snooping switches leading towards
|
||||
your mesh node as multicast router ports for now (Multicast Router
|
||||
Discovery, MRD, not implemented yet).
|
@ -183,20 +183,36 @@ next_node \: package
|
||||
in the ``name`` field.
|
||||
|
||||
mesh \: optional
|
||||
Options specific to routing protocols.
|
||||
Configuration of general mesh functionality.
|
||||
|
||||
At the moment, only the ``batman_adv`` routing protocol has such options:
|
||||
Gluon generally segments layer-2 meshes so that each node becomes IGMP/MLD
|
||||
querier for its own local clients. This is necessary for reliable multicast
|
||||
snooping. The segmentation is realized by preventing IGMP/MLD queries from
|
||||
passing through the mesh.
|
||||
|
||||
The optional value ``gw_sel_class`` sets the gateway selection class. The default
|
||||
class 20 is based on the link quality (TQ) only, class 1 is calculated from
|
||||
both the TQ and the announced bandwidth.
|
||||
By default, not only queries are filtered, but also membership report and
|
||||
leave packets, as they add to the background noise of the mesh. As a
|
||||
consequence, snooping switches outside the mesh that are connected to a
|
||||
Gluon node need to be configured to forward all multicast traffic towards
|
||||
the mesh; this is usually not a problem, as such setups are unusual. If
|
||||
you run a special-purpose mesh that requires membership reports to be
|
||||
working, this filtering can be disabled by setting the
|
||||
*filter_membership_reports* option to ``false``.
|
||||
|
||||
In addition, options specific to the batman-adv routing protocol can be set
|
||||
in the *batman_adv* section:
|
||||
|
||||
The optional value *gw_sel_class* sets the gateway selection class. The
|
||||
default is class 20, which is based on the link quality (TQ) only; class 1
|
||||
is calculated from both the TQ and the announced bandwidth.
|
||||
::
|
||||
|
||||
mesh = {
|
||||
batman_adv = {
|
||||
gw_sel_class = 1,
|
||||
},
|
||||
}
|
||||
mesh = {
|
||||
filter_membership_reports = false,
|
||||
batman_adv = {
|
||||
gw_sel_class = 1,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
mesh_vpn
|
||||
|
@ -1,51 +0,0 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=gluon-ebtables-segment-mld
|
||||
PKG_VERSION:=1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/gluon-ebtables-segment-mld
|
||||
SECTION:=gluon
|
||||
CATEGORY:=Gluon
|
||||
TITLE:=Ebtables filters for IGMP/MLD packets
|
||||
DEPENDS:=+gluon-core +gluon-ebtables gluon-mesh-batman-adv
|
||||
endef
|
||||
|
||||
define Package/gluon-ebtables-segment-mld/description
|
||||
Gluon community wifi mesh firmware framework: Ebtables filters for
|
||||
IGMP/MLD packets
|
||||
|
||||
These filters drop IGMP/MLD packets before they enter the mesh and
|
||||
filter any IGMP/MLD packets coming from the mesh.
|
||||
|
||||
IGMP/MLD have the concept of a local, elected Querier. For more
|
||||
decentralization and increased robustness, the idea of this package is
|
||||
to split the IGMP/MLD domain a querier is responsible for, allowing to
|
||||
have a querier per node. The split IGMP/MLD domain will also reduce
|
||||
overhead for this packet type, increasing scalability.
|
||||
|
||||
Beware of the consequences of using this package though: You might need
|
||||
to explicitly, manually mark ports on snooping switches leading towards
|
||||
your mesh node as multicast router ports for now (Multicast Router
|
||||
Discovery, MRD, not implemented yet).
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/gluon-ebtables-segment-mld/install
|
||||
$(CP) ./files/* $(1)/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,gluon-ebtables-segment-mld))
|
@ -1,2 +0,0 @@
|
||||
chain('MULTICAST_IN', 'RETURN', 'nat')
|
||||
chain('MULTICAST_IN_ICMPV6', 'RETURN', 'nat')
|
@ -1,2 +0,0 @@
|
||||
rule ('PREROUTING -d Multicast --logical-in br-client -i bat0 -j MULTICAST_IN', 'nat')
|
||||
rule ('MULTICAST_IN -p IPv6 --ip6-protocol ipv6-icmp -j MULTICAST_IN_ICMPV6', 'nat')
|
@ -1,2 +0,0 @@
|
||||
rule('MULTICAST_OUT -p IPv4 --ip-protocol igmp -j DROP')
|
||||
rule('MULTICAST_IN -p IPv4 --ip-protocol igmp -j DROP', 'nat')
|
@ -1,9 +0,0 @@
|
||||
rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 130 -j DROP') -- MLD Query
|
||||
rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 131 -j DROP') -- MLDv1 Report
|
||||
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 130 -j DROP', 'nat') -- MLD Query
|
||||
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
|
@ -6,7 +6,7 @@ PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include ../gluon.mk
|
||||
|
||||
|
||||
define Package/gluon-ebtables
|
||||
@ -34,4 +34,9 @@ define Package/gluon-ebtables/install
|
||||
$(CP) ./files/* $(1)/
|
||||
endef
|
||||
|
||||
define Package/gluon-ebtables/postinst
|
||||
#!/bin/sh
|
||||
$(call GluonCheckSite,check_site.lua)
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,gluon-ebtables))
|
||||
|
1
package/gluon-ebtables/check_site.lua
Normal file
1
package/gluon-ebtables/check_site.lua
Normal file
@ -0,0 +1 @@
|
||||
need_boolean({'mesh', 'filter_membership_reports'}, false)
|
@ -1,5 +1,9 @@
|
||||
chain('IN_ONLY', 'RETURN')
|
||||
chain('OUT_ONLY', 'RETURN')
|
||||
|
||||
-- nat chain runs early, so we can drop IGMP/MLD
|
||||
chain('MULTICAST_IN', 'RETURN', 'nat')
|
||||
chain('MULTICAST_IN_ICMPV6', 'RETURN', 'nat')
|
||||
|
||||
chain('MULTICAST_OUT', 'RETURN')
|
||||
chain('MULTICAST_OUT_ICMPV6', 'RETURN')
|
||||
|
@ -0,0 +1,20 @@
|
||||
local site = require 'gluon.site'
|
||||
|
||||
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')
|
||||
|
||||
rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 130 -j DROP') -- MLD Query
|
||||
rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 130 -j DROP', 'nat') -- MLD Query
|
||||
|
||||
if site.mesh.filter_membership_reports(true) then
|
||||
rule('MULTICAST_IN -p IPv4 --ip-protocol igmp -j DROP', 'nat')
|
||||
rule('MULTICAST_OUT -p IPv4 --ip-protocol igmp -j DROP')
|
||||
|
||||
rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 131 -j DROP') -- MLDv1 Report
|
||||
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
|
||||
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
|
@ -1,4 +1,6 @@
|
||||
rule ('PREROUTING -d Multicast --logical-in br-client -i bat0 -j MULTICAST_IN', 'nat')
|
||||
rule 'OUTPUT -d Multicast --logical-out br-client -o bat0 -j MULTICAST_OUT'
|
||||
rule 'FORWARD -d Multicast --logical-out br-client -o bat0 -j MULTICAST_OUT'
|
||||
|
||||
rule ('MULTICAST_IN -p IPv6 --ip6-protocol ipv6-icmp -j MULTICAST_IN_ICMPV6', 'nat')
|
||||
rule 'MULTICAST_OUT -p IPv6 --ip6-protocol ipv6-icmp -j MULTICAST_OUT_ICMPV6'
|
||||
|
Loading…
Reference in New Issue
Block a user