From 17370d8462637a7d53bc1705e49e542acd92455e Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 2 Mar 2018 23:51:48 +0100 Subject: [PATCH] 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 --- docs/index.rst | 1 - docs/package/gluon-ebtables-segment-mld.rst | 16 ------ docs/user/site.rst | 36 +++++++++---- package/gluon-ebtables-segment-mld/Makefile | 51 ------------------- .../lib/gluon/ebtables/100-mcast-in-chain | 2 - .../lib/gluon/ebtables/101-mcast-in-rule | 2 - .../lib/gluon/ebtables/105-mcast-drop-igmp | 2 - .../lib/gluon/ebtables/105-mcast-drop-mld | 9 ---- package/gluon-ebtables/Makefile | 7 ++- package/gluon-ebtables/check_site.lua | 1 + .../files/lib/gluon/ebtables/100-dir-chain | 4 ++ .../gluon/ebtables/105-mcast-drop-igmp-mld | 20 ++++++++ .../lib/gluon/ebtables/350-mcast-dir-rules | 2 + 13 files changed, 59 insertions(+), 94 deletions(-) delete mode 100644 docs/package/gluon-ebtables-segment-mld.rst delete mode 100644 package/gluon-ebtables-segment-mld/Makefile delete mode 100644 package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/100-mcast-in-chain delete mode 100644 package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/101-mcast-in-rule delete mode 100644 package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-igmp delete mode 100644 package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-mld create mode 100644 package/gluon-ebtables/check_site.lua create mode 100644 package/gluon-ebtables/files/lib/gluon/ebtables/105-mcast-drop-igmp-mld diff --git a/docs/index.rst b/docs/index.rst index 1bf5df90..1dd53d90 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -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 diff --git a/docs/package/gluon-ebtables-segment-mld.rst b/docs/package/gluon-ebtables-segment-mld.rst deleted file mode 100644 index 7e197ece..00000000 --- a/docs/package/gluon-ebtables-segment-mld.rst +++ /dev/null @@ -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). diff --git a/docs/user/site.rst b/docs/user/site.rst index 1ab1b176..5f0d411a 100644 --- a/docs/user/site.rst +++ b/docs/user/site.rst @@ -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 diff --git a/package/gluon-ebtables-segment-mld/Makefile b/package/gluon-ebtables-segment-mld/Makefile deleted file mode 100644 index 3d651aee..00000000 --- a/package/gluon-ebtables-segment-mld/Makefile +++ /dev/null @@ -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)) diff --git a/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/100-mcast-in-chain b/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/100-mcast-in-chain deleted file mode 100644 index 69d6bf18..00000000 --- a/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/100-mcast-in-chain +++ /dev/null @@ -1,2 +0,0 @@ -chain('MULTICAST_IN', 'RETURN', 'nat') -chain('MULTICAST_IN_ICMPV6', 'RETURN', 'nat') diff --git a/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/101-mcast-in-rule b/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/101-mcast-in-rule deleted file mode 100644 index 4eef2e7e..00000000 --- a/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/101-mcast-in-rule +++ /dev/null @@ -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') diff --git a/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-igmp b/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-igmp deleted file mode 100644 index 08052721..00000000 --- a/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-igmp +++ /dev/null @@ -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') diff --git a/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-mld b/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-mld deleted file mode 100644 index b6090c22..00000000 --- a/package/gluon-ebtables-segment-mld/files/lib/gluon/ebtables/105-mcast-drop-mld +++ /dev/null @@ -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 diff --git a/package/gluon-ebtables/Makefile b/package/gluon-ebtables/Makefile index 43185c73..066009b5 100644 --- a/package/gluon-ebtables/Makefile +++ b/package/gluon-ebtables/Makefile @@ -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)) diff --git a/package/gluon-ebtables/check_site.lua b/package/gluon-ebtables/check_site.lua new file mode 100644 index 00000000..68747b78 --- /dev/null +++ b/package/gluon-ebtables/check_site.lua @@ -0,0 +1 @@ +need_boolean({'mesh', 'filter_membership_reports'}, false) diff --git a/package/gluon-ebtables/files/lib/gluon/ebtables/100-dir-chain b/package/gluon-ebtables/files/lib/gluon/ebtables/100-dir-chain index e6bf98e3..62b92947 100644 --- a/package/gluon-ebtables/files/lib/gluon/ebtables/100-dir-chain +++ b/package/gluon-ebtables/files/lib/gluon/ebtables/100-dir-chain @@ -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') diff --git a/package/gluon-ebtables/files/lib/gluon/ebtables/105-mcast-drop-igmp-mld b/package/gluon-ebtables/files/lib/gluon/ebtables/105-mcast-drop-igmp-mld new file mode 100644 index 00000000..3b1ecab3 --- /dev/null +++ b/package/gluon-ebtables/files/lib/gluon/ebtables/105-mcast-drop-igmp-mld @@ -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 diff --git a/package/gluon-ebtables/files/lib/gluon/ebtables/350-mcast-dir-rules b/package/gluon-ebtables/files/lib/gluon/ebtables/350-mcast-dir-rules index 01609068..5b625f99 100644 --- a/package/gluon-ebtables/files/lib/gluon/ebtables/350-mcast-dir-rules +++ b/package/gluon-ebtables/files/lib/gluon/ebtables/350-mcast-dir-rules @@ -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'