From b413df359d5f39d076d8e64e261ff8a3069f5341 Mon Sep 17 00:00:00 2001 From: David Bauer Date: Wed, 11 Aug 2021 02:18:02 +0200 Subject: [PATCH] modules: switch to OpenWrt master Signed-off-by: David Bauer --- modules | 12 +- ...n-t-create-DIR-825-B1-factory-image.patch} | 4 +- ...e-fritz7360-v2-using-incorrect-image.patch | 81 -- ...wake-up-calls-Android-bug-workaround.patch | 940 ------------------ ...t-build-in-parallel-and-bump-release.patch | 2 +- 5 files changed, 9 insertions(+), 1030 deletions(-) rename patches/openwrt/{0006-ath79-don-t-create-DIR-825-B1-factory-image.patch => 0004-ath79-don-t-create-DIR-825-B1-factory-image.patch} (88%) delete mode 100644 patches/openwrt/0004-xrx200-migrate-fritz7360-v2-using-incorrect-image.patch delete mode 100644 patches/openwrt/0005-kernel-bridge-Implement-MLD-Querier-wake-up-calls-Android-bug-workaround.patch diff --git a/modules b/modules index b14f68addd8..b5bb142ac46 100644 --- a/modules +++ b/modules @@ -1,16 +1,16 @@ GLUON_FEEDS='gluon packages routing' OPENWRT_REPO=https://github.com/openwrt/openwrt.git -OPENWRT_BRANCH=openwrt-23.05 -OPENWRT_COMMIT=7c43ced160a01ad2300bf103d457d9f2b20c2772 +OPENWRT_BRANCH=master +OPENWRT_COMMIT=df167450a5094034bf4c5ad6fbfce502b09662bb PACKAGES_GLUON_REPO=https://github.com/freifunk-gluon/packages.git PACKAGES_GLUON_COMMIT=dc99bbb906f9faae472e48da013dbf67e1a00c23 PACKAGES_PACKAGES_REPO=https://github.com/openwrt/packages.git -PACKAGES_PACKAGES_BRANCH=openwrt-23.05 -PACKAGES_PACKAGES_COMMIT=55aef54b755a3cb39cf9eb42513a2c3a3eeab36e +PACKAGES_PACKAGES_BRANCH=master +PACKAGES_PACKAGES_COMMIT=cb994bbf6c5d9b2d73f74b7cdb5c853d431a472c PACKAGES_ROUTING_REPO=https://github.com/openwrt/routing.git -PACKAGES_ROUTING_BRANCH=openwrt-23.05 -PACKAGES_ROUTING_COMMIT=83ef3784a9092cfd0a900cc28e2ed4e13671d667 +PACKAGES_ROUTING_BRANCH=master +PACKAGES_ROUTING_COMMIT=601bd6c045a738bb465ab9b5444ddffb8951e0e6 diff --git a/patches/openwrt/0006-ath79-don-t-create-DIR-825-B1-factory-image.patch b/patches/openwrt/0004-ath79-don-t-create-DIR-825-B1-factory-image.patch similarity index 88% rename from patches/openwrt/0006-ath79-don-t-create-DIR-825-B1-factory-image.patch rename to patches/openwrt/0004-ath79-don-t-create-DIR-825-B1-factory-image.patch index a9cfb41bda8..5355f8ca910 100644 --- a/patches/openwrt/0006-ath79-don-t-create-DIR-825-B1-factory-image.patch +++ b/patches/openwrt/0004-ath79-don-t-create-DIR-825-B1-factory-image.patch @@ -12,10 +12,10 @@ factory image and install a Gluon sysupgrade. Signed-off-by: David Bauer diff --git a/target/linux/ath79/image/generic.mk b/target/linux/ath79/image/generic.mk -index 1a558c30a05433c585cdf81967e265b1f7711af7..bfea8fb8e3623790cf627628d6d58760fce22a67 100644 +index b74ce345097d1402ae80ab7bf1e881949a0cbfa2..8539cf08576433fc187b871dad4d0a017005407c 100644 --- a/target/linux/ath79/image/generic.mk +++ b/target/linux/ath79/image/generic.mk -@@ -1073,11 +1073,6 @@ define Device/dlink_dir-825-b1 +@@ -1149,11 +1149,6 @@ define Device/dlink_dir-825-b1 DEVICE_PACKAGES := kmod-usb-ohci kmod-usb2 kmod-usb-ledtrig-usbport \ kmod-leds-reset kmod-owl-loader kmod-switch-rtl8366s IMAGE_SIZE := 7808k diff --git a/patches/openwrt/0004-xrx200-migrate-fritz7360-v2-using-incorrect-image.patch b/patches/openwrt/0004-xrx200-migrate-fritz7360-v2-using-incorrect-image.patch deleted file mode 100644 index bcf694ab13a..00000000000 --- a/patches/openwrt/0004-xrx200-migrate-fritz7360-v2-using-incorrect-image.patch +++ /dev/null @@ -1,81 +0,0 @@ -From: Grische -Date: Sun, 18 Sep 2022 14:03:16 +0200 -Subject: xrx200: migrate fritz7360-v2 using incorrect image - -Migrate AVM FRITZ!Box 7360 v2 boards flashed with the incorrect v1 image to use -the newly added v2 target image during the next upgrade. -Using the v2 target image allows the boards to read the TFFS partition, which -is misaligned when using the v1 image. - -Ref: https://github.com/freifunk-gluon/gluon/pull/2648 - -Co-authored-by: Jan-Niklas Burfeind - -diff --git a/target/linux/lantiq/xrx200/base-files/lib/preinit/01_sysinfo.sh b/target/linux/lantiq/xrx200/base-files/lib/preinit/01_sysinfo.sh -new file mode 100644 -index 0000000000000000000000000000000000000000..fab50d708e872f819c643cea79327e4f438de524 ---- /dev/null -+++ b/target/linux/lantiq/xrx200/base-files/lib/preinit/01_sysinfo.sh -@@ -0,0 +1,62 @@ -+set_sysinfo_xrx200_for_fritz7360_model() { -+ local board_name=$1 -+ local model -+ local urlader_version urlader_memsize urlader_flashsize -+ local hexdump_format='4/1 "%02x""\n"' -+ -+ # Values are based on urlader-parser-py -+ # https://github.com/grische/urlader-parser-py/blob/42970bf8dec7962317df4ff734c57ebf36df8905/parser.py#L77-L84 -+ urlader_version="$(dd if=/dev/mtd0ro bs=1 skip=$((0x580+0x0)) count=4 | hexdump -e "${hexdump_format}")" -+ if [ "${urlader_version}" != "00000003" ]; then -+ logger -s -p warn -t sysinfo-xrx200 "unexpected urlader version found: ${urlader_version}" -+ return -+ fi -+ -+ urlader_memsize="$(dd if=/dev/mtd0ro bs=1 skip=$((0x580+0x4)) count=4 | hexdump -e "${hexdump_format}")" -+ if [ "${urlader_memsize}" != "08000000" ]; then -+ logger -s -p warn -t sysinfo-xrx200 "unexpected memsize found: ${urlader_memsize}" -+ return -+ fi -+ -+ urlader_flashsize="$(dd if=/dev/mtd0ro bs=1 skip=$((0x580+0x8)) count=4 | hexdump -e "${hexdump_format}")" -+ case "${urlader_flashsize}" in -+ "02000000") # 32MB -+ # see vr9_avm_fritz7360-v2.dts -+ board_name="avm,fritz7360-v2" -+ model="AVM FRITZ!Box 7360 V2" -+ ;; -+ "01000000") # 16MB -+ return -+ ;; -+ *) -+ logger -s -p warn -t sysinfo-xrx200 "unexpected flashsize found: ${urlader_flashsize}" -+ return -+ ;; -+ esac -+ -+ logger -s -p notice -t sysinfo-xrx200 "detected ${board_name} from urlader partition /dev/mtd0ro. Enforcing model ${model}." -+ echo "${board_name}" > /tmp/sysinfo/board_name -+ echo "${model}" > /tmp/sysinfo/model -+} -+ -+do_sysinfo_xrx200() { -+ local reported_board board_name model -+ -+ [ -d /proc/device-tree ] || return -+ reported_board="$(strings /proc/device-tree/compatible | head -1)" -+ -+ mkdir -p /tmp/sysinfo -+ # 7360 is notoriously known for not writing "v2" on their labels and many -+ # routers have flashed the wrong firmware with the wrong flash layout. -+ # We ensure that the underlying hardware is reported correctly, so that -+ # future upgrades will use the correct flash layout. -+ # Using 7360v2 hardware, an upgrade from a 7360v1/sl firmware to a 7360v2 -+ # is working. -+ case "${reported_board}" in -+ avm,fritz7360sl) -+ set_sysinfo_xrx200_for_fritz7360_model "${reported_board}" -+ ;; -+ esac -+} -+ -+boot_hook_add preinit_main do_sysinfo_xrx200 diff --git a/patches/openwrt/0005-kernel-bridge-Implement-MLD-Querier-wake-up-calls-Android-bug-workaround.patch b/patches/openwrt/0005-kernel-bridge-Implement-MLD-Querier-wake-up-calls-Android-bug-workaround.patch deleted file mode 100644 index 862c5241843..00000000000 --- a/patches/openwrt/0005-kernel-bridge-Implement-MLD-Querier-wake-up-calls-Android-bug-workaround.patch +++ /dev/null @@ -1,940 +0,0 @@ -From: Linus Lüssing -Date: Sat, 1 Jan 2022 10:09:13 +0100 -Subject: kernel: bridge: Implement MLD Querier wake-up calls / Android bug workaround - -Implement a configurable MLD Querier wake-up calls "feature" which -works around a widely spread Android bug in connection with IGMP/MLD -snooping. - -Currently there are mobile devices (e.g. Android) which are not able -to receive and respond to MLD Queries reliably because the Wifi driver -filters a lot of ICMPv6 when the device is asleep - including -MLD. This in turn breaks IPv6 communication when MLD Snooping is -enabled. However there is one ICMPv6 type which is allowed to pass and -which can be used to wake up the mobile device: ICMPv6 Echo Requests. - -If this bridge is the selected MLD Querier then setting -"multicast_wakeupcall" to a number n greater than 0 will send n -ICMPv6 Echo Requests to each host behind this port to wake -them up with each MLD Query. Upon receiving a matching ICMPv6 Echo -Reply an MLD Query with a unicast ethernet destination will be sent -to the specific host(s). - -Link: https://issuetracker.google.com/issues/149630944 -Link: https://github.com/freifunk-gluon/gluon/issues/1832 - -Signed-off-by: Linus Lüssing - -diff --git a/package/network/config/netifd/patches/0001-bridge-Add-multicast_wakeupcall-option.patch b/package/network/config/netifd/patches/0001-bridge-Add-multicast_wakeupcall-option.patch -new file mode 100644 -index 0000000000000000000000000000000000000000..c9e3a2d4e4420387ae48cc5828d4284f2a987c3d ---- /dev/null -+++ b/package/network/config/netifd/patches/0001-bridge-Add-multicast_wakeupcall-option.patch -@@ -0,0 +1,199 @@ -+From d23a49e6542dc068b12fbc7b6a4520f9fb3626f9 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Linus=20L=C3=BCssing?= -+Date: Sun, 5 Jul 2020 23:33:51 +0200 -+Subject: [PATCH] bridge: Add multicast_wakeupcall option -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+This makes the new per bridge port multicast_wakeupcall feature -+for the Linux bridge configurable for wireless interfaces and enables it -+by default for an AP interface. -+ -+The MLD Querier wake-up calls "feature" works around a widely spread Android -+bug in connection with IGMP/MLD snooping. -+ -+Currently there are mobile devices (e.g. Android) which are not able -+to receive and respond to MLD Queries reliably because the Wifi driver -+filters a lot of ICMPv6 when the device is asleep - including -+MLD. This in turn breaks IPv6 communication when MLD Snooping is -+enabled. However there is one ICMPv6 type which is allowed to pass and -+which can be used to wake up the mobile device: ICMPv6 Echo Requests. -+ -+If this bridge is the selected MLD Querier then setting -+"multicast_wakeupcall" to a number n greater than 0 will send n -+ICMPv6 Echo Requests to each host behind this port to wake -+them up with each MLD Query. Upon receiving a matching ICMPv6 Echo -+Reply an MLD Query with a unicast ethernet destination will be sent -+to the specific host(s). -+ -+Link: https://issuetracker.google.com/issues/149630944 -+Link: https://github.com/freifunk-gluon/gluon/issues/1832 -+ -+Signed-off-by: Linus Lüssing -+--- -+ device.c | 9 +++++++++ -+ device.h | 3 +++ -+ system-linux.c | 13 +++++++++++++ -+ 3 files changed, 25 insertions(+) -+ -+--- a/device.c -++++ b/device.c -+@@ -47,6 +47,7 @@ static const struct blobmsg_policy dev_a -+ [DEV_ATTR_NEIGHGCSTALETIME] = { .name = "neighgcstaletime", .type = BLOBMSG_TYPE_INT32 }, -+ [DEV_ATTR_DADTRANSMITS] = { .name = "dadtransmits", .type = BLOBMSG_TYPE_INT32 }, -+ [DEV_ATTR_MULTICAST_TO_UNICAST] = { .name = "multicast_to_unicast", .type = BLOBMSG_TYPE_BOOL }, -++ [DEV_ATTR_MULTICAST_WAKEUPCALL] = { .name = "multicast_wakeupcall", .type = BLOBMSG_TYPE_INT32 }, -+ [DEV_ATTR_MULTICAST_ROUTER] = { .name = "multicast_router", .type = BLOBMSG_TYPE_INT32 }, -+ [DEV_ATTR_MULTICAST_FAST_LEAVE] = { .name = "multicast_fast_leave", . type = BLOBMSG_TYPE_BOOL }, -+ [DEV_ATTR_MULTICAST] = { .name ="multicast", .type = BLOBMSG_TYPE_BOOL }, -+@@ -267,6 +268,7 @@ device_merge_settings(struct device *dev -+ n->multicast = s->flags & DEV_OPT_MULTICAST ? -+ s->multicast : os->multicast; -+ n->multicast_to_unicast = s->multicast_to_unicast; -++ n->multicast_wakeupcall = s->multicast_wakeupcall; -+ n->multicast_router = s->multicast_router; -+ n->multicast_fast_leave = s->multicast_fast_leave; -+ n->learning = s->learning; -+@@ -438,6 +440,11 @@ device_init_settings(struct device *dev, -+ s->flags |= DEV_OPT_MULTICAST_TO_UNICAST; -+ } -+ -++ if ((cur = tb[DEV_ATTR_MULTICAST_WAKEUPCALL])) { -++ s->multicast_wakeupcall = blobmsg_get_u32(cur); -++ s->flags |= DEV_OPT_MULTICAST_WAKEUPCALL; -++ } -++ -+ if ((cur = tb[DEV_ATTR_MULTICAST_ROUTER])) { -+ s->multicast_router = blobmsg_get_u32(cur); -+ if (s->multicast_router <= 2) -+@@ -1281,6 +1288,8 @@ device_dump_status(struct blob_buf *b, s -+ blobmsg_add_u32(b, "dadtransmits", st.dadtransmits); -+ if (st.flags & DEV_OPT_MULTICAST_TO_UNICAST) -+ blobmsg_add_u8(b, "multicast_to_unicast", st.multicast_to_unicast); -++ if (st.flags & DEV_OPT_MULTICAST_WAKEUPCALL) -++ blobmsg_add_u32(b, "multicast_wakeupcall", st.multicast_wakeupcall); -+ if (st.flags & DEV_OPT_MULTICAST_ROUTER) -+ blobmsg_add_u32(b, "multicast_router", st.multicast_router); -+ if (st.flags & DEV_OPT_MULTICAST_FAST_LEAVE) -+--- a/device.h -++++ b/device.h -+@@ -44,6 +44,7 @@ enum { -+ DEV_ATTR_NEIGHREACHABLETIME, -+ DEV_ATTR_DADTRANSMITS, -+ DEV_ATTR_MULTICAST_TO_UNICAST, -++ DEV_ATTR_MULTICAST_WAKEUPCALL, -+ DEV_ATTR_MULTICAST_ROUTER, -+ DEV_ATTR_MULTICAST_FAST_LEAVE, -+ DEV_ATTR_MULTICAST, -+@@ -137,6 +138,7 @@ enum { -+ DEV_OPT_RXPAUSE = (1ULL << 34), -+ DEV_OPT_TXPAUSE = (1ULL << 35), -+ DEV_OPT_AUTONEG = (1ULL << 36), -++ DEV_OPT_MULTICAST_WAKEUPCALL = (1ULL << 63) -+ }; -+ -+ /* events broadcasted to all users of a device */ -+@@ -198,6 +200,7 @@ struct device_settings { -+ int neigh4locktime; -+ unsigned int dadtransmits; -+ bool multicast_to_unicast; -++ unsigned int multicast_wakeupcall; -+ unsigned int multicast_router; -+ bool multicast_fast_leave; -+ bool multicast; -+--- a/system-linux.c -++++ b/system-linux.c -+@@ -536,6 +536,11 @@ static void system_bridge_set_multicast_ -+ system_set_dev_sysfs("brport/multicast_to_unicast", dev->ifname, val); -+ } -+ -++static void system_bridge_set_multicast_wakeupcall(struct device *dev, const char *val) -++{ -++ system_set_dev_sysfs("brport/multicast_wakeupcall", dev->ifname, val); -++} -++ -+ static void system_bridge_set_multicast_fast_leave(struct device *dev, const char *val) -+ { -+ system_set_dev_sysfs("brport/multicast_fast_leave", dev->ifname, val); -+@@ -915,8 +920,10 @@ static char *system_get_bridge(const cha -+ static void -+ system_bridge_set_wireless(struct device *bridge, struct device *dev) -+ { -++ unsigned int mcast_wakeupcall = dev->wireless_ap ? 2 : 0; -+ bool mcast_to_ucast = dev->wireless_ap; -+ bool hairpin; -++ char buf[64]; -+ -+ if (dev->settings.flags & DEV_OPT_MULTICAST_TO_UNICAST) -+ mcast_to_ucast = dev->settings.multicast_to_unicast; -+@@ -931,6 +938,12 @@ system_bridge_set_wireless(struct device -+ system_bridge_set_multicast_to_unicast(dev, mcast_to_ucast ? "1" : "0"); -+ system_bridge_set_hairpin_mode(dev, hairpin ? "1" : "0"); -+ system_bridge_set_proxyarp_wifi(dev, dev->wireless_proxyarp ? "1" : "0"); -++ -++ if (bridge->settings.flags & DEV_OPT_MULTICAST_WAKEUPCALL) -++ mcast_wakeupcall = dev->settings.multicast_wakeupcall; -++ -++ snprintf(buf, sizeof(buf), "%u", mcast_wakeupcall); -++ system_bridge_set_multicast_wakeupcall(dev, buf); -+ } -+ -+ int system_bridge_addif(struct device *bridge, struct device *dev) -+--- a/interface.c -++++ b/interface.c -+@@ -1248,7 +1248,7 @@ interface_device_config_changed(struct i -+ struct blob_attr *ntb[__DEV_ATTR_MAX]; -+ struct blob_attr *otb[__DEV_ATTR_MAX]; -+ struct device *dev = if_old->main_dev.dev; -+- unsigned long diff = 0; -++ unsigned long diff[2] = {}; -+ -+ BUILD_BUG_ON(sizeof(diff) < __DEV_ATTR_MAX / 8); -+ -+@@ -1267,8 +1267,8 @@ interface_device_config_changed(struct i -+ blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, ntb, -+ blob_data(if_new->config), blob_len(if_new->config)); -+ -+- uci_blob_diff(ntb, otb, &device_attr_list, &diff); -+- return diff; -++ uci_blob_diff(ntb, otb, &device_attr_list, diff); -++ return diff[0] | diff[1]; -+ } -+ -+ static void -+--- a/bonding.c -++++ b/bonding.c -+@@ -442,7 +442,7 @@ bonding_reload(struct device *dev, struc -+ struct blob_attr *tb_dev[__DEV_ATTR_MAX]; -+ struct blob_attr *tb_b[__BOND_ATTR_MAX]; -+ enum dev_change_type ret = DEV_CONFIG_APPLIED; -+- unsigned long diff; -++ unsigned long diff[2]; -+ struct bonding_device *bdev; -+ -+ BUILD_BUG_ON(sizeof(diff) < __BOND_ATTR_MAX / 8); -+@@ -472,17 +472,17 @@ bonding_reload(struct device *dev, struc -+ blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, otb_dev, -+ blob_data(bdev->config_data), blob_len(bdev->config_data)); -+ -+- diff = 0; -+- uci_blob_diff(tb_dev, otb_dev, &device_attr_list, &diff); -+- if (diff) -++ diff[0] = diff[1] = 0; -++ uci_blob_diff(tb_dev, otb_dev, &device_attr_list, diff); -++ if (diff[0] | diff[1]) -+ ret = DEV_CONFIG_RESTART; -+ -+ blobmsg_parse(bonding_attrs, __BOND_ATTR_MAX, otb_b, -+ blob_data(bdev->config_data), blob_len(bdev->config_data)); -+ -+- diff = 0; -+- uci_blob_diff(tb_b, otb_b, &bonding_attr_list, &diff); -+- if (diff & ~(1 << BOND_ATTR_PORTS)) -++ diff[0] = diff[1] = 0; -++ uci_blob_diff(tb_b, otb_b, &bonding_attr_list, diff); -++ if (diff[0] & ~(1 << BOND_ATTR_PORTS)) -+ ret = DEV_CONFIG_RESTART; -+ -+ bonding_config_init(dev); -diff --git a/target/linux/generic/config-5.15 b/target/linux/generic/config-5.15 -index 214a1e6ecd83c067b96cb55ad052ae00b82fa8b5..bf6709ae2dbb87a21659558161d4882befd88b49 100644 ---- a/target/linux/generic/config-5.15 -+++ b/target/linux/generic/config-5.15 -@@ -761,6 +761,7 @@ CONFIG_BRIDGE=y - # CONFIG_BRIDGE_EBT_T_NAT is not set - # CONFIG_BRIDGE_EBT_VLAN is not set - CONFIG_BRIDGE_IGMP_SNOOPING=y -+CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS=y - # CONFIG_BRIDGE_MRP is not set - # CONFIG_BRIDGE_NETFILTER is not set - # CONFIG_BRIDGE_NF_EBTABLES is not set -diff --git a/target/linux/generic/hack-5.15/602-bridge-Implement-MLD-Querier-wake-up-calls-Android-b.patch b/target/linux/generic/hack-5.15/602-bridge-Implement-MLD-Querier-wake-up-calls-Android-b.patch -new file mode 100644 -index 0000000000000000000000000000000000000000..84f872ddc2433514ca5c210f73b37855723e5763 ---- /dev/null -+++ b/target/linux/generic/hack-5.15/602-bridge-Implement-MLD-Querier-wake-up-calls-Android-b.patch -@@ -0,0 +1,690 @@ -+From 4529dcf18d4c5e05d30cd2d6fabfbae201e6c347 Mon Sep 17 00:00:00 2001 -+From: =?UTF-8?q?Linus=20L=C3=BCssing?= -+Date: Mon, 29 Jun 2020 19:04:05 +0200 -+Subject: [PATCH] bridge: Implement MLD Querier wake-up calls / Android bug -+ workaround -+MIME-Version: 1.0 -+Content-Type: text/plain; charset=UTF-8 -+Content-Transfer-Encoding: 8bit -+ -+Implement a configurable MLD Querier wake-up calls "feature" which -+works around a widely spread Android bug in connection with IGMP/MLD -+snooping. -+ -+Currently there are mobile devices (e.g. Android) which are not able -+to receive and respond to MLD Queries reliably because the Wifi driver -+filters a lot of ICMPv6 when the device is asleep - including -+MLD. This in turn breaks IPv6 communication when MLD Snooping is -+enabled. However there is one ICMPv6 type which is allowed to pass and -+which can be used to wake up the mobile device: ICMPv6 Echo Requests. -+ -+If this bridge is the selected MLD Querier then setting -+"multicast_wakeupcall" to a number n greater than 0 will send n -+ICMPv6 Echo Requests to each host behind this port to wake -+them up with each MLD Query. Upon receiving a matching ICMPv6 Echo -+Reply an MLD Query with a unicast ethernet destination will be sent -+to the specific host(s). -+ -+Link: https://issuetracker.google.com/issues/149630944 -+Link: https://github.com/freifunk-gluon/gluon/issues/1832 -+ -+Signed-off-by: Linus Lüssing -+--- -+ include/linux/if_bridge.h | 1 + -+ include/net/addrconf.h | 1 + -+ include/uapi/linux/if_link.h | 1 + -+ net/bridge/Kconfig | 26 ++++ -+ net/bridge/br_fdb.c | 10 ++ -+ net/bridge/br_input.c | 4 +- -+ net/bridge/br_multicast.c | 291 ++++++++++++++++++++++++++++++++++- -+ net/bridge/br_netlink.c | 19 +++ -+ net/bridge/br_private.h | 20 +++ -+ net/bridge/br_sysfs_if.c | 18 +++ -+ net/core/rtnetlink.c | 2 +- -+ net/ipv6/mcast_snoop.c | 3 +- -+ 12 files changed, 386 insertions(+), 10 deletions(-) -+ -+diff --git a/include/linux/if_bridge.h b/include/linux/if_bridge.h -+index 18d3b264b754..5ee206fb5ee7 100644 -+--- a/include/linux/if_bridge.h -++++ b/include/linux/if_bridge.h -+@@ -59,6 +59,7 @@ struct br_ip_list { -+ #define BR_MRP_LOST_IN_CONT BIT(19) -+ #define BR_TX_FWD_OFFLOAD BIT(20) -+ #define BR_BPDU_FILTER BIT(21) -++#define BR_MULTICAST_WAKEUPCALL BIT(22) -+ -+ #define BR_DEFAULT_AGEING_TIME (300 * HZ) -+ -+diff --git a/include/net/addrconf.h b/include/net/addrconf.h -+index 53627afab104..f31ea1726efa 100644 -+--- a/include/net/addrconf.h -++++ b/include/net/addrconf.h -+@@ -233,6 +233,7 @@ void ipv6_mc_unmap(struct inet6_dev *idev); -+ void ipv6_mc_remap(struct inet6_dev *idev); -+ void ipv6_mc_init_dev(struct inet6_dev *idev); -+ void ipv6_mc_destroy_dev(struct inet6_dev *idev); -++int ipv6_mc_check_icmpv6(struct sk_buff *skb); -+ int ipv6_mc_check_mld(struct sk_buff *skb); -+ void addrconf_dad_failure(struct sk_buff *skb, struct inet6_ifaddr *ifp); -+ -+diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h -+index be0ad9a79da8..baf07b15e481 100644 -+--- a/include/uapi/linux/if_link.h -++++ b/include/uapi/linux/if_link.h -+@@ -537,6 +537,7 @@ enum { -+ IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT, -+ IFLA_BRPORT_MCAST_EHT_HOSTS_CNT, -+ IFLA_BRPORT_BPDU_FILTER, -++ IFLA_BRPORT_MCAST_WAKEUPCALL, -+ __IFLA_BRPORT_MAX -+ }; -+ #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) -+diff --git a/net/bridge/Kconfig b/net/bridge/Kconfig -+index 3c8ded7d3e84..1a11e22c7d51 100644 -+--- a/net/bridge/Kconfig -++++ b/net/bridge/Kconfig -+@@ -48,6 +48,32 @@ config BRIDGE_IGMP_SNOOPING -+ -+ If unsure, say Y. -+ -++config BRIDGE_IGMP_SNOOPING_WAKEUPCALLS -++ bool "MLD Querier wake-up calls" -++ depends on BRIDGE_IGMP_SNOOPING -++ depends on IPV6 -++ help -++ If you say Y here, then the MLD Snooping Querier will be built -++ with a per bridge port wake-up call "feature"/workaround. -++ -++ Currently there are mobile devices (e.g. Android) which are not able -++ to receive and respond to MLD Queries reliably because the Wifi driver -++ filters a lot of ICMPv6 when the device is asleep - including MLD. -++ This in turn breaks IPv6 communication when MLD Snooping is enabled. -++ However there is one ICMPv6 type which is allowed to pass and -++ which can be used to wake up the mobile device: ICMPv6 Echo Requests. -++ -++ If this bridge is the selected MLD Querier then setting -++ "multicast_wakeupcall" to a number n greater than 0 will send n -++ ICMPv6 Echo Requests to each host behind this port to wake them up -++ with each MLD Query. Upon receiving a matching ICMPv6 Echo Reply -++ an MLD Query with a unicast ethernet destination will be sent to the -++ specific host(s). -++ -++ Say N to exclude this support and reduce the binary size. -++ -++ If unsure, say N. -++ -+ config BRIDGE_VLAN_FILTERING -+ bool "VLAN filtering" -+ depends on BRIDGE -+diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c -+index 46812b659710..eec5f3770ff8 100644 -+--- a/net/bridge/br_fdb.c -++++ b/net/bridge/br_fdb.c -+@@ -84,6 +84,10 @@ static void fdb_rcu_free(struct rcu_head *head) -+ { -+ struct net_bridge_fdb_entry *ent -+ = container_of(head, struct net_bridge_fdb_entry, rcu); -++ -++#ifdef CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS -++ del_timer_sync(&ent->wakeupcall_timer); -++#endif -+ kmem_cache_free(br_fdb_cache, ent); -+ } -+ -+@@ -518,6 +522,12 @@ static struct net_bridge_fdb_entry *fdb_create(struct net_bridge *br, -+ fdb->key.vlan_id = vid; -+ fdb->flags = flags; -+ fdb->updated = fdb->used = jiffies; -++ -++#ifdef CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS -++ timer_setup(&fdb->wakeupcall_timer, -++ br_multicast_send_wakeupcall, 0); -++#endif -++ -+ if (rhashtable_lookup_insert_fast(&br->fdb_hash_tbl, -+ &fdb->rhnode, -+ br_fdb_rht_params)) { -+diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c -+index fe80b8e4c2d7..879ae7adb845 100644 -+--- a/net/bridge/br_input.c -++++ b/net/bridge/br_input.c -+@@ -164,8 +164,10 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb -+ if (dst) { -+ unsigned long now = jiffies; -+ -+- if (test_bit(BR_FDB_LOCAL, &dst->flags)) -++ if (test_bit(BR_FDB_LOCAL, &dst->flags)) { -++ br_multicast_wakeupcall_rcv(brmctx, pmctx, skb, vid); -+ return br_pass_frame_up(skb); -++ } -+ -+ if (now != dst->used) -+ dst->used = now; -+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -+index db4f2641d1cd..6822dfbafa71 100644 -+--- a/net/bridge/br_multicast.c -++++ b/net/bridge/br_multicast.c -+@@ -950,15 +950,16 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge_mcast *brm -+ const struct in6_addr *group, -+ bool with_srcs, bool over_llqt, -+ u8 sflag, u8 *igmp_type, -+- bool *need_rexmit) -++ bool *need_rexmit, -++ bool delay) -+ { -+ struct net_bridge_port *p = pg ? pg->key.port : NULL; -+ struct net_bridge_group_src *ent; -+ size_t pkt_size, mld_hdr_size; -+ unsigned long now = jiffies; -++ unsigned long interval = 0; -+ struct mld2_query *mld2q; -+ void *csum_start = NULL; -+- unsigned long interval; -+ __sum16 *csum = NULL; -+ struct ipv6hdr *ip6h; -+ struct mld_msg *mldq; -+@@ -1040,9 +1041,13 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge_mcast *brm -+ -+ /* ICMPv6 */ -+ skb_set_transport_header(skb, skb->len); -+- interval = ipv6_addr_any(group) ? -+- brmctx->multicast_query_response_interval : -+- brmctx->multicast_last_member_interval; -++ if (delay) { -++ interval = ipv6_addr_any(group) ? -++ brmctx->multicast_query_response_interval : -++ brmctx->multicast_last_member_interval; -++ interval = jiffies_to_msecs(interval); -++ } -++ -+ *igmp_type = ICMPV6_MGM_QUERY; -+ switch (brmctx->multicast_mld_version) { -+ case 1: -+@@ -1050,7 +1055,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge_mcast *brm -+ mldq->mld_type = ICMPV6_MGM_QUERY; -+ mldq->mld_code = 0; -+ mldq->mld_cksum = 0; -+- mldq->mld_maxdelay = htons((u16)jiffies_to_msecs(interval)); -++ mldq->mld_maxdelay = htons((u16)interval); -+ mldq->mld_reserved = 0; -+ mldq->mld_mca = *group; -+ csum = &mldq->mld_cksum; -+@@ -1141,7 +1146,7 @@ static struct sk_buff *br_multicast_alloc_query(struct net_bridge_mcast *brmctx, -+ &ip6_dst, &group->dst.ip6, -+ with_srcs, over_lmqt, -+ sflag, igmp_type, -+- need_rexmit); -++ need_rexmit, true); -+ } -+ #endif -+ } -+@@ -1619,6 +1624,169 @@ static void br_multicast_select_own_querier(struct net_bridge_mcast *brmctx, -+ #endif -+ } -+ -++#ifdef CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS -++ -++#define BR_MC_WAKEUP_ID htons(0xEC6B) /* random identifier */ -++#define BR_MC_ETH_ZERO { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } -++#define BR_MC_IN6_ZERO \ -++{ \ -++ .s6_addr32[0] = 0, .s6_addr32[1] = 0, \ -++ .s6_addr32[2] = 0, .s6_addr32[3] = 0, \ -++} -++ -++#define BR_MC_IN6_FE80 \ -++{ \ -++ .s6_addr32[0] = htonl(0xfe800000), \ -++ .s6_addr32[1] = 0, \ -++ .s6_addr32[2] = htonl(0x000000ff), \ -++ .s6_addr32[3] = htonl(0xfe000000), \ -++} -++ -++#define BR_MC_ECHO_LEN sizeof(pkt->echohdr) -++ -++static struct sk_buff *br_multicast_alloc_wakeupcall(struct net_bridge *br, -++ struct net_bridge_port *port, -++ u8 *eth_dst) -++{ -++ struct in6_addr ip6_src, ip6_dst = BR_MC_IN6_FE80; -++ struct sk_buff *skb; -++ __wsum csum_part; -++ __sum16 csum; -++ -++ struct wakeupcall_pkt { -++ struct ethhdr ethhdr; -++ struct ipv6hdr ip6hdr; -++ struct icmp6hdr echohdr; -++ } __packed; -++ -++ struct wakeupcall_pkt *pkt; -++ -++ static const struct wakeupcall_pkt __pkt_template = { -++ .ethhdr = { -++ .h_dest = BR_MC_ETH_ZERO, // update -++ .h_source = BR_MC_ETH_ZERO, // update -++ .h_proto = htons(ETH_P_IPV6), -++ }, -++ .ip6hdr = { -++ .priority = 0, -++ .version = 0x6, -++ .flow_lbl = { 0x00, 0x00, 0x00 }, -++ .payload_len = htons(BR_MC_ECHO_LEN), -++ .nexthdr = IPPROTO_ICMPV6, -++ .hop_limit = 1, -++ .saddr = BR_MC_IN6_ZERO, // update -++ .daddr = BR_MC_IN6_ZERO, // update -++ }, -++ .echohdr = { -++ .icmp6_type = ICMPV6_ECHO_REQUEST, -++ .icmp6_code = 0, -++ .icmp6_cksum = 0, // update -++ .icmp6_dataun.u_echo = { -++ .identifier = BR_MC_WAKEUP_ID, -++ .sequence = 0, -++ }, -++ }, -++ }; -++ -++ memcpy(&ip6_dst.s6_addr32[2], ð_dst[0], ETH_ALEN / 2); -++ memcpy(&ip6_dst.s6_addr[13], ð_dst[3], ETH_ALEN / 2); -++ ip6_dst.s6_addr[8] ^= 0x02; -++ if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6_dst, 0, -++ &ip6_src)) -++ return NULL; -++ -++ skb = netdev_alloc_skb_ip_align(br->dev, sizeof(*pkt)); -++ if (!skb) -++ return NULL; -++ -++ skb->protocol = htons(ETH_P_IPV6); -++ skb->dev = port->dev; -++ -++ pkt = (struct wakeupcall_pkt *)skb->data; -++ *pkt = __pkt_template; -++ -++ ether_addr_copy(pkt->ethhdr.h_source, br->dev->dev_addr); -++ ether_addr_copy(pkt->ethhdr.h_dest, eth_dst); -++ -++ pkt->ip6hdr.saddr = ip6_src; -++ pkt->ip6hdr.daddr = ip6_dst; -++ -++ csum_part = csum_partial(&pkt->echohdr, sizeof(pkt->echohdr), 0); -++ csum = csum_ipv6_magic(&ip6_src, &ip6_dst, sizeof(pkt->echohdr), -++ IPPROTO_ICMPV6, csum_part); -++ pkt->echohdr.icmp6_cksum = csum; -++ -++ skb_reset_mac_header(skb); -++ skb_set_network_header(skb, offsetof(struct wakeupcall_pkt, ip6hdr)); -++ skb_set_transport_header(skb, offsetof(struct wakeupcall_pkt, echohdr)); -++ skb_put(skb, sizeof(*pkt)); -++ __skb_pull(skb, sizeof(pkt->ethhdr)); -++ -++ return skb; -++} -++ -++void br_multicast_send_wakeupcall(struct timer_list *t) -++{ -++ struct net_bridge_fdb_entry *fdb = from_timer(fdb, t, wakeupcall_timer); -++ struct net_bridge_port *port = fdb->dst; -++ struct net_bridge *br = port->br; -++ struct sk_buff *skb, *skb0; -++ int i; -++ -++ skb0 = br_multicast_alloc_wakeupcall(br, port, fdb->key.addr.addr); -++ if (!skb0) -++ return; -++ -++ for (i = port->wakeupcall_num_rings; i > 0; i--) { -++ if (i > 1) { -++ skb = skb_clone(skb0, GFP_ATOMIC); -++ if (!skb) { -++ kfree_skb(skb0); -++ break; -++ } -++ } else { -++ skb = skb0; -++ } -++ -++ NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, -++ dev_net(port->dev), NULL, skb, NULL, skb->dev, -++ br_dev_queue_push_xmit); -++ } -++} -++ -++static void -++br_multicast_schedule_wakeupcalls(struct net_bridge_mcast *brmctx, -++ struct net_bridge_mcast_port *pmctx, -++ const struct in6_addr *group) -++{ -++ struct net_bridge_fdb_entry *fdb; -++ unsigned long delay; -++ -++ rcu_read_lock(); -++ hlist_for_each_entry_rcu(fdb, &brmctx->br->fdb_list, fdb_node) { -++ if (!fdb->dst || fdb->dst->dev != pmctx->port->dev) -++ continue; -++ -++ /* Wake-up calls to VLANs unsupported for now */ -++ if (fdb->key.vlan_id) -++ continue; -++ -++ /* Spread the ICMPv6 Echo Requests to avoid congestion. -++ * We then won't use a max response delay for the queries later, -++ * as that would be redundant. Spread randomly by a little less -++ * than max response delay to anticipate the extra round trip. -++ */ -++ delay = ipv6_addr_any(group) ? -++ brmctx->multicast_query_response_interval : -++ brmctx->multicast_last_member_interval; -++ delay = prandom_u32() % (3 * delay / 4); -++ -++ timer_reduce(&fdb->wakeupcall_timer, jiffies + delay); -++ } -++ rcu_read_unlock(); -++} -++#endif /* CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS */ -++ -+ static void __br_multicast_send_query(struct net_bridge_mcast *brmctx, -+ struct net_bridge_mcast_port *pmctx, -+ struct net_bridge_port_group *pg, -+@@ -1651,6 +1819,13 @@ static void __br_multicast_send_query(struct net_bridge_mcast *brmctx, -+ dev_net(pmctx->port->dev), NULL, skb, NULL, skb->dev, -+ br_dev_queue_push_xmit); -+ -++#ifdef CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS -++ if (pmctx->port->wakeupcall_num_rings && -++ group->proto == htons(ETH_P_IPV6)) -++ br_multicast_schedule_wakeupcalls(brmctx, pmctx, -++ &group->dst.ip6); -++#endif -++ -+ if (over_lmqt && with_srcs && sflag) { -+ over_lmqt = false; -+ goto again_under_lmqt; -+@@ -3801,6 +3976,99 @@ int br_multicast_rcv(struct net_bridge_mcast **brmctx, -+ return ret; -+ } -+ -++#ifdef CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS -++ -++static bool br_multicast_wakeupcall_check(struct net_bridge *br, -++ struct net_bridge_port *port, -++ struct sk_buff *skb, u16 vid) -++{ -++ struct ethhdr *eth = eth_hdr(skb); -++ const struct ipv6hdr *ip6h; -++ unsigned int offset, len; -++ struct icmp6hdr *icmp6h; -++ -++ /* Wake-up calls to VLANs unsupported for now */ -++ if (!port->wakeupcall_num_rings || vid || -++ eth->h_proto != htons(ETH_P_IPV6)) -++ return false; -++ -++ if (!ether_addr_equal(eth->h_dest, br->dev->dev_addr) || -++ is_multicast_ether_addr(eth->h_source) || -++ is_zero_ether_addr(eth->h_source)) -++ return false; -++ -++ offset = skb_network_offset(skb) + sizeof(*ip6h); -++ if (!pskb_may_pull(skb, offset)) -++ return false; -++ -++ ip6h = ipv6_hdr(skb); -++ -++ if (ip6h->version != 6) -++ return false; -++ -++ len = offset + ntohs(ip6h->payload_len); -++ if (skb->len < len || len <= offset) -++ return false; -++ -++ if (ip6h->nexthdr != IPPROTO_ICMPV6) -++ return false; -++ -++ skb_set_transport_header(skb, offset); -++ -++ if (ipv6_mc_check_icmpv6(skb) < 0) -++ return false; -++ -++ icmp6h = (struct icmp6hdr *)skb_transport_header(skb); -++ if (icmp6h->icmp6_type != ICMPV6_ECHO_REPLY || -++ icmp6h->icmp6_dataun.u_echo.identifier != BR_MC_WAKEUP_ID) -++ return false; -++ -++ return true; -++} -++ -++static void br_multicast_wakeupcall_send_mldq(struct net_bridge_mcast *brmctx, -++ struct net_bridge_mcast_port *pmctx, -++ const u8 *eth_dst) -++{ -++ const struct in6_addr group = BR_MC_IN6_ZERO; -++ struct in6_addr ip6_dst; -++ struct sk_buff *skb; -++ u8 igmp_type; -++ -++ /* we might have been triggered by multicast-address-specific query -++ * but reply with a general MLD query for now to keep things simple -++ */ -++ ipv6_addr_set(&ip6_dst, htonl(0xff020000), 0, 0, htonl(1)); -++ -++ skb = br_ip6_multicast_alloc_query(brmctx, pmctx, NULL, &ip6_dst, -++ &group, false, false, false, -++ &igmp_type, NULL, false); -++ if (!skb) -++ return; -++ -++ skb->dev = pmctx->port->dev; -++ ether_addr_copy(eth_hdr(skb)->h_dest, eth_dst); -++ -++ br_multicast_count(brmctx->br, pmctx->port, skb, igmp_type, -++ BR_MCAST_DIR_TX); -++ NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, -++ dev_net(pmctx->port->dev), NULL, skb, NULL, skb->dev, -++ br_dev_queue_push_xmit); -++} -++ -++void br_multicast_wakeupcall_rcv(struct net_bridge_mcast *brmctx, -++ struct net_bridge_mcast_port *pmctx, -++ struct sk_buff *skb, u16 vid) -++{ -++ if (!br_multicast_wakeupcall_check(brmctx->br, pmctx->port, skb, vid)) -++ return; -++ -++ br_multicast_wakeupcall_send_mldq(brmctx, pmctx, -++ eth_hdr(skb)->h_source); -++} -++ -++#endif /* CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS */ -++ -+ static void br_multicast_query_expired(struct net_bridge_mcast *brmctx, -+ struct bridge_mcast_own_query *query, -+ struct bridge_mcast_querier *querier) -+@@ -4325,6 +4593,15 @@ int br_multicast_set_vlan_router(struct net_bridge_vlan *v, u8 mcast_router) -+ return err; -+ } -+ -++int br_multicast_set_wakeupcall(struct net_bridge_port *p, unsigned long val) -++{ -++ if (val > U8_MAX) -++ return -EINVAL; -++ -++ p->wakeupcall_num_rings = val; -++ return 0; -++} -++ -+ static void br_multicast_start_querier(struct net_bridge_mcast *brmctx, -+ struct bridge_mcast_own_query *query) -+ { -+diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c -+index ae6007309a17..09d4861b7336 100644 -+--- a/net/bridge/br_netlink.c -++++ b/net/bridge/br_netlink.c -+@@ -198,6 +198,9 @@ static inline size_t br_port_info_size(void) -+ + nla_total_size_64bit(sizeof(u64)) /* IFLA_BRPORT_HOLD_TIMER */ -+ #ifdef CONFIG_BRIDGE_IGMP_SNOOPING -+ + nla_total_size(sizeof(u8)) /* IFLA_BRPORT_MULTICAST_ROUTER */ -++#endif -++#ifdef CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS -++ + nla_total_size(sizeof(u8)) /* IFLA_BRPORT_MCAST_WAKEUPCALL */ -+ #endif -+ + nla_total_size(sizeof(u16)) /* IFLA_BRPORT_GROUP_FWD_MASK */ -+ + nla_total_size(sizeof(u8)) /* IFLA_BRPORT_MRP_RING_OPEN */ -+@@ -296,6 +299,11 @@ static int br_port_fill_attrs(struct sk_buff *skb, -+ p->multicast_eht_hosts_cnt)) -+ return -EMSGSIZE; -+ #endif -++#ifdef CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS -++ if (nla_put_u8(skb, IFLA_BRPORT_MCAST_WAKEUPCALL, -++ p->wakeupcall_num_rings)) -++ return -EMSGSIZE; -++#endif -+ -+ /* we might be called only with br->lock */ -+ rcu_read_lock(); -+@@ -823,6 +831,7 @@ static const struct nla_policy br_port_policy[IFLA_BRPORT_MAX + 1] = { -+ [IFLA_BRPORT_PROXYARP_WIFI] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_MULTICAST_ROUTER] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_MCAST_TO_UCAST] = { .type = NLA_U8 }, -++ [IFLA_BRPORT_MCAST_WAKEUPCALL] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_MCAST_FLOOD] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_BCAST_FLOOD] = { .type = NLA_U8 }, -+ [IFLA_BRPORT_VLAN_TUNNEL] = { .type = NLA_U8 }, -+@@ -952,6 +961,16 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[], -+ } -+ #endif -+ -++#ifdef CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS -++ if (tb[IFLA_BRPORT_MCAST_WAKEUPCALL]) { -++ u8 wakeupcall = nla_get_u8(tb[IFLA_BRPORT_MCAST_WAKEUPCALL]); -++ -++ err = br_multicast_set_wakeupcall(p, wakeupcall); -++ if (err) -++ return err; -++ } -++#endif -++ -+ if (tb[IFLA_BRPORT_GROUP_FWD_MASK]) { -+ u16 fwd_mask = nla_get_u16(tb[IFLA_BRPORT_GROUP_FWD_MASK]); -+ -+diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h -+index bd218c2b2cd9..32191519b500 100644 -+--- a/net/bridge/br_private.h -++++ b/net/bridge/br_private.h -+@@ -269,6 +269,10 @@ struct net_bridge_fdb_entry { -+ unsigned long used; -+ -+ struct rcu_head rcu; -++ -++#ifdef CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS -++ struct timer_list wakeupcall_timer; -++#endif -+ }; -+ -+ #define MDB_PG_FLAGS_PERMANENT BIT(0) -+@@ -382,6 +386,7 @@ struct net_bridge_port { -+ u32 multicast_eht_hosts_limit; -+ u32 multicast_eht_hosts_cnt; -+ struct hlist_head mglist; -++ u8 wakeupcall_num_rings; -+ #endif -+ -+ #ifdef CONFIG_SYSFS -+@@ -1418,6 +1423,21 @@ br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1, -+ } -+ #endif -+ -++#ifdef CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS -++void br_multicast_wakeupcall_rcv(struct net_bridge_mcast *brmctx, -++ struct net_bridge_mcast_port *pmctx, -++ struct sk_buff *skb, u16 vid); -++void br_multicast_send_wakeupcall(struct timer_list *t); -++int br_multicast_set_wakeupcall(struct net_bridge_port *p, unsigned long val); -++#else -++static inline void -++br_multicast_wakeupcall_rcv(struct net_bridge_mcast *brmctx, -++ struct net_bridge_mcast_port *pmctx, -++ struct sk_buff *skb, u16 vid) -++{ -++} -++#endif /* CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS */ -++ -+ /* br_vlan.c */ -+ #ifdef CONFIG_BRIDGE_VLAN_FILTERING -+ bool br_allowed_ingress(const struct net_bridge *br, -+diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c -+index 9ee9c60738e2..9dcd4a9204db 100644 -+--- a/net/bridge/br_sysfs_if.c -++++ b/net/bridge/br_sysfs_if.c -+@@ -260,6 +260,21 @@ BRPORT_ATTR_FLAG(multicast_fast_leave, BR_MULTICAST_FAST_LEAVE); -+ BRPORT_ATTR_FLAG(multicast_to_unicast, BR_MULTICAST_TO_UNICAST); -+ #endif -+ -++#ifdef CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS -++static ssize_t show_multicast_wakeupcall(struct net_bridge_port *p, char *buf) -++{ -++ return sprintf(buf, "%d\n", p->wakeupcall_num_rings); -++} -++ -++static int store_multicast_wakeupcall(struct net_bridge_port *p, -++ unsigned long v) -++{ -++ return br_multicast_set_wakeupcall(p, v); -++} -++static BRPORT_ATTR(multicast_wakeupcall, 0644, show_multicast_wakeupcall, -++ store_multicast_wakeupcall); -++#endif -++ -+ static const struct brport_attribute *brport_attrs[] = { -+ &brport_attr_path_cost, -+ &brport_attr_priority, -+@@ -285,6 +300,9 @@ static const struct brport_attribute *brport_attrs[] = { -+ &brport_attr_multicast_router, -+ &brport_attr_multicast_fast_leave, -+ &brport_attr_multicast_to_unicast, -++#endif -++#ifdef CONFIG_BRIDGE_IGMP_SNOOPING_WAKEUPCALLS -++ &brport_attr_multicast_wakeupcall, -+ #endif -+ &brport_attr_proxyarp, -+ &brport_attr_proxyarp_wifi, -+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -+index e0fa875832a0..caf454185dc8 100644 -+--- a/net/core/rtnetlink.c -++++ b/net/core/rtnetlink.c -+@@ -55,7 +55,7 @@ -+ #include -+ -+ #define RTNL_MAX_TYPE 50 -+-#define RTNL_SLAVE_MAX_TYPE 41 -++#define RTNL_SLAVE_MAX_TYPE 42 -+ -+ struct rtnl_link { -+ rtnl_doit_func doit; -+diff --git a/net/ipv6/mcast_snoop.c b/net/ipv6/mcast_snoop.c -+index 04d5fcdfa6e0..9a5061edbaf3 100644 -+--- a/net/ipv6/mcast_snoop.c -++++ b/net/ipv6/mcast_snoop.c -+@@ -131,7 +131,7 @@ static inline __sum16 ipv6_mc_validate_checksum(struct sk_buff *skb) -+ return skb_checksum_validate(skb, IPPROTO_ICMPV6, ip6_compute_pseudo); -+ } -+ -+-static int ipv6_mc_check_icmpv6(struct sk_buff *skb) -++int ipv6_mc_check_icmpv6(struct sk_buff *skb) -+ { -+ unsigned int len = skb_transport_offset(skb) + sizeof(struct icmp6hdr); -+ unsigned int transport_len = ipv6_transport_len(skb); -+@@ -150,6 +150,7 @@ static int ipv6_mc_check_icmpv6(struct sk_buff *skb) -+ -+ return 0; -+ } -++EXPORT_SYMBOL(ipv6_mc_check_icmpv6); -+ -+ /** -+ * ipv6_mc_check_mld - checks whether this is a sane MLD packet -+-- -+2.40.1 -+ diff --git a/patches/packages/packages/0001-perl-don-t-build-in-parallel-and-bump-release.patch b/patches/packages/packages/0001-perl-don-t-build-in-parallel-and-bump-release.patch index 49e0da3d64e..6dfa56ed94d 100644 --- a/patches/packages/packages/0001-perl-don-t-build-in-parallel-and-bump-release.patch +++ b/patches/packages/packages/0001-perl-don-t-build-in-parallel-and-bump-release.patch @@ -8,7 +8,7 @@ https://github.com/openwrt/packages/issues/8238 https://github.com/openwrt/packages/pull/17274 diff --git a/lang/perl/Makefile b/lang/perl/Makefile -index 40532b5f0163ffffc3ce8dfb697592c3a81e0af0..17e9202847b555a8e78a14f22b3536c2ceef9dd7 100644 +index 7b603b5af28842f35a8873f07b6259a667037c1c..59b55fc68049a85c8d0096102fc6cce37ceb3287 100644 --- a/lang/perl/Makefile +++ b/lang/perl/Makefile @@ -34,8 +34,8 @@ PKG_BUILD_DIR:=$(BUILD_DIR)/perl/$(PKG_NAME)-$(PKG_VERSION)