From da50843b3739485f2a06ab4f3e80836225b93cb6 Mon Sep 17 00:00:00 2001 From: Markus Gothe Date: Thu, 19 Dec 2024 14:24:22 +0100 Subject: [PATCH] mcastmngr: Fix snooping stats. --- bridgemngr/files/etc/config/bridging | 7 ++ ebtables-extensions/Makefile | 36 +++++++++- mcastmngr/Makefile | 5 +- mcastmngr/files/linux/lib/mcast/linux.sh | 31 +++++++++ mcastmngr/files/linux/usr/libexec/rpcd/mcast | 70 +++----------------- 5 files changed, 84 insertions(+), 65 deletions(-) diff --git a/bridgemngr/files/etc/config/bridging b/bridgemngr/files/etc/config/bridging index 5bf163ca5..17ff521f5 100644 --- a/bridgemngr/files/etc/config/bridging +++ b/bridgemngr/files/etc/config/bridging @@ -24,3 +24,10 @@ config chain 'prevlanxlate' option chain 'BROUTING' option policy 'RETURN' option append 'false' + +config chain 'mcsnooping' + option target 'mcsnooping' + option table 'broute' + option chain 'BROUTING' + option policy 'RETURN' + option append 'false' diff --git a/ebtables-extensions/Makefile b/ebtables-extensions/Makefile index 25eb9db5d..790a8a889 100644 --- a/ebtables-extensions/Makefile +++ b/ebtables-extensions/Makefile @@ -6,13 +6,13 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=ebtables-extensions -PKG_VERSION:=2.0.1 +PKG_VERSION:=2.0.2 PKG_LICENSE:=GPL-2.0 LOCAL_DEV:=0 ifneq ($(LOCAL_DEV),1) PKG_SOURCE_PROTO:=git -PKG_SOURCE_VERSION:=5ef3a5b057f6b59a4b90bd5ca15a852b0c27f3b3 +PKG_SOURCE_VERSION:=6c188fa33b06509e05b0f51ba5d41384a309432a PKG_SOURCE_URL:=https://dev.iopsys.eu/network/ebtables-extensions.git PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz PKG_MIRROR_HASH:=skip @@ -119,6 +119,24 @@ define KernelPackage/xtip6 KCONFIG:= endef +define KernelPackage/igmpsnooping + SUBMENU:=Other modules + TITLE:=Kernel module for ebtables IGMP snooping + FILES:=$(PKG_BUILD_DIR)/src/ebt_igmpsnooping.ko + DEPENDS+=+kmod-ebtables + # AUTOLOAD:=$(call AutoLoad,30,ebt_igmpsnooping) - Will be loaded on demand + KCONFIG:= +endef + +define KernelPackage/mldsnooping + SUBMENU:=Other modules + TITLE:=Kernel module for ebtables MLD snooping + FILES:=$(PKG_BUILD_DIR)/src/ebt_mldsnooping.ko + DEPENDS+=+kmod-ebtables + # AUTOLOAD:=$(call AutoLoad,30,ebt_mldsnooping) - Will be loaded on demand + KCONFIG:= +endef + define KernelPackage/dhcp/description Kernel module to enable DHCP snooping for ebtables endef @@ -163,6 +181,14 @@ define KernelPackage/dscp2pbit/description Kernel module to enable DSCP-to-Pbit mapping for ebtables endef +define KernelPackage/igmpsnooping/description + Kernel module to enable IGMP snooping for ebtables +endef + +define KernelPackage/mldsnooping/description + Kernel module to enable MLD snooping for ebtables +endef + ifeq ($(CONFIG_TARGET_brcmbca),y) include ../../broadcom/bcmkernel/bcm-kernel-toolchain.mk endif @@ -187,6 +213,8 @@ endif $(CP) $(PKG_BUILD_DIR)/src/ebt_xtarp.h $(LINUX_DIR)/include/uapi/linux/netfilter_bridge/ $(CP) $(PKG_BUILD_DIR)/src/ebt_xtip.h $(LINUX_DIR)/include/uapi/linux/netfilter_bridge/ $(CP) $(PKG_BUILD_DIR)/src/ebt_xtip6.h $(LINUX_DIR)/include/uapi/linux/netfilter_bridge/ + $(CP) $(PKG_BUILD_DIR)/src/ebt_igmpsnooping.h $(LINUX_DIR)/include/uapi/linux/netfilter_bridge/ + $(CP) $(PKG_BUILD_DIR)/src/ebt_mldsnooping.h $(LINUX_DIR)/include/uapi/linux/netfilter_bridge/ endef define Build/InstallDev @@ -204,6 +232,8 @@ endif $(CP) $(PKG_BUILD_DIR)/src/ebt_xtarp.h $(1)/include/uapi/linux/netfilter_bridge/ $(CP) $(PKG_BUILD_DIR)/src/ebt_xtip.h $(1)/include/uapi/linux/netfilter_bridge/ $(CP) $(PKG_BUILD_DIR)/src/ebt_xtip6.h $(1)/include/uapi/linux/netfilter_bridge/ + $(CP) $(PKG_BUILD_DIR)/src/ebt_igmpsnooping.h $(1)/include/uapi/linux/netfilter_bridge/ + $(CP) $(PKG_BUILD_DIR)/src/ebt_mldsnooping.h $(1)/include/uapi/linux/netfilter_bridge/ endef KERNEL_MAKE_FLAGS += -I$(LINUX_DIR)/include @@ -226,3 +256,5 @@ $(eval $(call KernelPackage,l2pt)) $(eval $(call KernelPackage,xtarp)) $(eval $(call KernelPackage,xtip)) $(eval $(call KernelPackage,xtip6)) +$(eval $(call KernelPackage,igmpsnooping)) +$(eval $(call KernelPackage,mldsnooping)) diff --git a/mcastmngr/Makefile b/mcastmngr/Makefile index 79b65771f..43a960b80 100644 --- a/mcastmngr/Makefile +++ b/mcastmngr/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mcastmngr -PKG_VERSION:=1.2.8 +PKG_VERSION:=1.2.9 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) LOCAL_DEV:=0 @@ -31,7 +31,8 @@ define Package/mcastmngr TITLE:=Multicast Proxy/Snooping Manager DEPENDS:=+libuci +libubox +libubus +libblobmsg-json DEPENDS+=+!TARGET_brcmbca:mcproxy +!TARGET_brcmbca:sipcalc - DEPENDS+=+libbbfdm-api +libbbfdm-ubus +dm-service + DEPENDS+=+libbbfdm-api +libbbfdm-ubus +dm-service +!TARGET_brcmbca:kmod-igmpsnooping +!TARGET_brcmbca:kmod-mldsnooping + DEPENDS+=+!TARGET_brcmbca:ebtables-legacy +bridgemngr endef define Package/mcastmngr/description diff --git a/mcastmngr/files/linux/lib/mcast/linux.sh b/mcastmngr/files/linux/lib/mcast/linux.sh index 0a5327456..dcec121af 100755 --- a/mcastmngr/files/linux/lib/mcast/linux.sh +++ b/mcastmngr/files/linux/lib/mcast/linux.sh @@ -9,6 +9,7 @@ CONFFILE= PROG_EXE=/usr/sbin/mcproxy PROG_PARAMS= PROG_PARAMS_SEPARATOR=: +readonly WANPORT="$(jsonfilter -i /etc/board.json -e @.network.wan.device)" snooping_bridges= @@ -311,6 +312,22 @@ config_mcproxy_instance() { [ -n $fast_leave ] && config_sysfs_mcast_fastleave "$downstreams" "$fast_leave" config_sysfs_mcast_flood "$downstreams" "$mcast_mode" + + for iface in $downstreams; do + if device_is_bridge "$iface"; then + if [ "${protocol}" = "mld" ]; then + ebtables -t broute -I mcsnooping -s Unicast -d 33:33:00:00:00:00/ff:ff:00:00:00:00 --logical-in ${iface} ! -i "${WANPORT}+" --mld-snooping + elif [ "${protocol}" = "igmp" ]; then + ebtables -t broute -I mcsnooping -s Unicast -d 01:00:5e:00:00:00/ff:ff:ff:00:00:00 --logical-in ${iface} ! -i "${WANPORT}+" --igmp-snooping + fi + else + if [ "${protocol}" = "mld" ]; then + ebtables -t broute -I mcsnooping -s Unicast -d 33:33:00:00:00:00/ff:ff:00:00:00:00 -i ${iface} --mld-snooping + elif [ "${protocol}" = "igmp" ]; then + ebtables -t broute -I mcsnooping -s Unicast -d 01:00:5e:00:00:00/ff:ff:ff:00:00:00 -i ${iface} --igmp-snooping + fi + fi + done fi PROG_PARAMS="${PROG_PARAMS} -f ${CONFFILE}${PROG_PARAMS_SEPARATOR}" @@ -324,6 +341,12 @@ disable_snooping_iface() { disable_snooping() { config_load network config_foreach disable_snooping_iface device + + ebtables --concurrent -t broute -F mcsnooping + + # Clean up populated /procfs entries + rmmod ebt_igmpsnooping 2> /dev/null #Loaded on demand + rmmod ebt_mldsnooping 2> /dev/null #Loaded on demand } config_snooping() { @@ -395,6 +418,14 @@ config_snooping() { [ -n "$q_resp_interval" ] && config_sysfs_mcast_q_resp_interval "$interfaces" "$q_resp_interval" [ -n "$last_mem_q_int" ] && config_sysfs_mcast_last_mem_q_int "$interfaces" "$last_mem_q_int" [ -n "$fast_leave" ] && config_sysfs_mcast_fastleave "$interfaces" "$fast_leave" + + for iface in $snooping_bridges; do + if [ "${protocol}" = "mld" ]; then + ebtables -t broute -I mcsnooping -s Unicast -d 33:33:00:00:00:00/ff:ff:00:00:00:00 --logical-in ${iface} ! -i "${WANPORT}+" --mld-snooping + elif [ "${protocol}" = "igmp" ]; then + ebtables -t broute -I mcsnooping -s Unicast -d 01:00:5e:00:00:00/ff:ff:ff:00:00:00 --logical-in ${iface} ! -i "${WANPORT}+" --igmp-snooping + fi + done } config_mcproxy() { diff --git a/mcastmngr/files/linux/usr/libexec/rpcd/mcast b/mcastmngr/files/linux/usr/libexec/rpcd/mcast index 0ed209869..9c8a793e8 100755 --- a/mcastmngr/files/linux/usr/libexec/rpcd/mcast +++ b/mcastmngr/files/linux/usr/libexec/rpcd/mcast @@ -5,61 +5,11 @@ readonly TEMPFILE="/tmp/snooping_stats_"$$ -mcast_snooping_interface() { - local interface intf gip vid port - - config_get interface "$1" interface - - for intf in $interface; do - [ -z "$(bridge mdb show dev "$intf" 2> /dev/null | grep -v -F "port ${intf} " | xargs)" ] && continue - json_add_object "" - json_add_string "interface" "$intf" - json_add_array "groups" - for gip in $(bridge mdb show dev "$intf" | grep -v -F "port ${intf} " | cut -f6 -d' ' | sort -u | xargs); do - json_add_object "" - json_add_string "groupaddr" "$gip" - json_add_array "clients" - for port in $(bridge mdb show dev "$intf" | grep -v -F "port ${intf} " | grep -F "grp ${gip} " | cut -f4 -d' ' | sort -u | xargs); do - json_add_object "" - json_add_string "device" "$port" - for vid in $(bridge mdb show dev "$intf" | grep -F "port ${port} grp ${gip} " | grep -F ' vid ' | cut -f9 -d' ' | sort -u | xargs); do - json_add_object "" - json_add_string "vid" "$vid" - json_close_object #close the associated vid object - done - json_close_object #close the associated device object - done - json_close_array #close the associated devices array - json_close_object # close the groups object - done # close the loop for group addresses - json_close_array #close the groups array - json_close_object # close the snooping object - done # close the loop for interfaces -} meld_files() { local type="$1" - local snooping_stats="/tmp/${type}_snooping_stats" - local old_mod_time=$(date +%s 2>/dev/null -r "$snooping_stats") - # Sending signal to mcproxy to dump multicast data in /tmp/${type}_snooping_stats - local mcast_pids=$(pidof mcproxy) - for pid in $mcast_pids - do - $(kill -10 $pid) - done - - # Wait for signal is being processed by mcproxy - if [ -n "$mcast_pids" ]; then - for i in 1 2 3; do - local new_mod_time=$(date +%s 2>/dev/null -r "$snooping_stats") - [ -n "$new_mod_time" ] && [ "$new_mod_time" != "$old_mod_time" ] && break - sleep 0.1 - done - fi - - [ ! -e "$snooping_stats" ] && return 0 - cat "$snooping_stats" >> "$TEMPFILE" + tail -n +2 "/proc/net/${type}_snooping" >> "$TEMPFILE" } read_snooping_file() { @@ -98,7 +48,8 @@ read_snooping_file() { case $line in br-*) found_ip=0 - grp_ip="$(echo $line | awk -F ' ' '{ print $2 }')" + grp_ip="$(echo $line | awk -F ' ' '{ print $7 }')" + if [ -z "$mcast_addrs" ]; then mcast_addrs="$grp_ip" continue @@ -136,7 +87,7 @@ read_snooping_file() { if [ "$snoop_iface" != "$intf" ]; then continue fi - grp_ip="$(echo $line | awk -F ' ' '{ print $2 }')" + grp_ip="$(echo $line | awk -F ' ' '{ print $7 }')" if [ "$grp_ip" != "$gip_addr" ]; then continue fi @@ -145,7 +96,7 @@ read_snooping_file() { if [ -n "$(echo $gip_addr | grep -oE "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$")" ]; then gip="$(ipcalc.sh $gip_addr | grep IP | awk '{print substr($0,4)}')" else - gip="$(echo $gip_addr | grep -oE '^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$')" + gip="$(sipcalc -6 "$gip_addr" | awk '/^Compressed address/{print $4}')" fi json_add_string "groupaddr" "$gip" json_add_array "clients" @@ -153,16 +104,16 @@ read_snooping_file() { fi json_add_object "" - host_ip="$(echo $line | awk -F ' ' '{ print $3 }')" + host_ip="$(echo $line | awk -F ' ' '{ print $8 }')" if [ -n "$(echo $host_ip | grep -oE "^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$")" ]; then h_ip="$(ipcalc.sh $host_ip | grep IP | awk '{print substr($0,4)}')" else - h_ip="$(echo $host_ip | grep -oE '^([0-9a-fA-F]{0,4}:){1,7}[0-9a-fA-F]{0,4}$')" + h_ip="$(sipcalc -6 "$host_ip" | awk '/^Compressed address/{print $4}')" fi json_add_string "ipaddr" "$h_ip" - src_port="$(echo $line | awk -F ' ' '{ print $4 }')" + src_port="$(echo $line | awk -F ' ' '{ print $2 }')" json_add_string "device" "$src_port" - timeout="$(echo $line | awk -F ' ' '{ print $5 }')" + timeout="$(echo $line | awk -F ' ' '{ print $9 }')" json_add_int "timeout" "$timeout" json_close_object #close the associated device object ;; @@ -186,9 +137,6 @@ read_mcast_stats() { meld_files "igmp" meld_files "mld" read_snooping_file - # L2 Snooping goes here - config_load mcast - config_foreach mcast_snooping_interface "snooping" json_close_array # close the snooping array json_dump