Merge pull request #624 from ecsv/batadv-for-18.06 openwrt-18.06
authorSimon Wunderlich <sw@simonwunderlich.de>
Tue, 27 Oct 2020 16:07:28 +0000 (17:07 +0100)
committerGitHub <noreply@github.com>
Tue, 27 Oct 2020 16:07:28 +0000 (17:07 +0100)
batman-adv: Fix missing include for backported 2020.4 patch

45 files changed:
babeld/Makefile
batctl/Makefile
batctl/patches/0001-batctl-Return-EXIT_FAILURE-when-throughputmeter-fail.patch [new file with mode: 0644]
batctl/patches/0002-batctl-fix-endianness-when-reading-radiotap-header.patch [new file with mode: 0644]
batctl/patches/0003-batctl-Only-remove-batadv-interface-on-hardif-reduct.patch [new file with mode: 0644]
batctl/patches/0004-batctl-tcpdump-Fix-endianness-in-ICMPv6-Echo-Request.patch [new file with mode: 0644]
batman-adv/Makefile
batman-adv/patches/0032-batman-adv-Fix-duplicated-OGMs-on-NETDEV_UP.patch [new file with mode: 0644]
batman-adv/patches/0033-batman-adv-fix-uninit-value-in-batadv_netlink_get_if.patch [new file with mode: 0644]
batman-adv/patches/0034-batman-adv-Only-read-OGM-tvlv_len-after-buffer-len-c.patch [new file with mode: 0644]
batman-adv/patches/0035-batman-adv-Only-read-OGM2-tvlv_len-after-buffer-len-.patch [new file with mode: 0644]
batman-adv/patches/0036-batman-adv-Avoid-free-alloc-race-when-handling-OGM2-.patch [new file with mode: 0644]
batman-adv/patches/0037-batman-adv-Avoid-free-alloc-race-when-handling-OGM-b.patch [new file with mode: 0644]
batman-adv/patches/0038-batman-adv-Introduce-own-OGM2-buffer-mutex.patch [new file with mode: 0644]
batman-adv/patches/0039-batman-adv-Avoid-OGM-workqueue-synchronous-cancel-de.patch [new file with mode: 0644]
batman-adv/patches/0040-batman-adv-Fix-DAT-candidate-selection-on-little-end.patch [new file with mode: 0644]
batman-adv/patches/0041-batman-adv-Don-t-schedule-OGM-for-disabled-interface.patch [new file with mode: 0644]
batman-adv/patches/0042-batman-adv-fix-batadv_nc_random_weight_tq.patch [new file with mode: 0644]
batman-adv/patches/0043-batman-adv-Fix-refcnt-leak-in-batadv_show_throughput.patch [new file with mode: 0644]
batman-adv/patches/0044-batman-adv-Fix-refcnt-leak-in-batadv_store_throughpu.patch [new file with mode: 0644]
batman-adv/patches/0045-batman-adv-Fix-refcnt-leak-in-batadv_v_ogm_process.patch [new file with mode: 0644]
batman-adv/patches/0046-batman-adv-Avoid-uninitialized-chaddr-when-handling-.patch [new file with mode: 0644]
batman-adv/patches/0047-batman-adv-Fix-own-OGM-check-in-aggregated-OGMs.patch [new file with mode: 0644]
batman-adv/patches/0048-batman-adv-bla-use-netif_rx_ni-when-not-in-interrupt.patch [new file with mode: 0644]
batman-adv/patches/0049-batman-adv-bla-fix-type-misuse-for-backbone_gw-hash-.patch [new file with mode: 0644]
batman-adv/patches/0050-batman-adv-mcast-TT-fix-wrongly-dropped-or-rerouted-.patch [new file with mode: 0644]
batman-adv/patches/0051-batman-adv-Add-missing-include-for-in_interrupt.patch [new file with mode: 0644]
batman-adv/patches/0052-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch [new file with mode: 0644]
batman-adv/patches/0053-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch [new file with mode: 0644]
batman-adv/patches/0054-batman-adv-mcast-fix-duplicate-mcast-packets-from-BL.patch [new file with mode: 0644]
bird/Makefile
nodogsplash/Makefile
nodogsplash/files/etc/config/nodogsplash [deleted file]
nodogsplash/files/etc/init.d/nodogsplash [deleted file]
nodogsplash/files/etc/uci-defaults/40_nodogsplash [deleted file]
nodogsplash/files/usr/lib/nodogsplash/restart.sh [deleted file]
nodogsplash/patches/0001-fix-invalid-pointer-when-clock-is-turned-back.patch [deleted file]
pimbd/Makefile
quagga/Makefile
quagga/patches/001-bgpd-Fix-AS_PATH-size-calculation-for-long-paths.patch [new file with mode: 0644]
quagga/patches/002-Quagga-2018-0543.patch [new file with mode: 0644]
quagga/patches/003-Quagga-2018-1114.patch [new file with mode: 0644]
quagga/patches/004-Quagga-2018-1550.patch [new file with mode: 0644]
quagga/patches/005-Quagga-2018-1975.patch [new file with mode: 0644]
quagga/patches/150-no-cross-fs-link.patch

index 5cf136d2b856a19d9e7e149ad551e65eeb0c969c..972862ceaaf59146ac0e3e58b86c1a22a925ef54 100644 (file)
@@ -8,13 +8,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=babeld
-PKG_VERSION:=1.8.2
+PKG_VERSION:=1.8.5
 PKG_RELEASE:=1
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://www.irif.fr/~jch/software/files/
-PKG_MD5SUM:=eec395ade02524b3f351507a21742939
-PKG_HASH:=07edecb132386d5561a767482bc5200e04239b18e48c2f0f47ae1c78d60fe5dc
+PKG_HASH:=202d99c275604507c6ce133710522f1ddfb62cb671c26f1ac2d3ab44af3d5bc4
 PKG_LICENSE:=MIT
 
 include $(INCLUDE_DIR)/package.mk
index 4e67512844d07607852a5447a336dc9f93f5990a..ba83914217732ee49a66a304f18e46f07b1225e6 100644 (file)
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
 PKG_NAME:=batctl
 
 PKG_VERSION:=2018.1
-PKG_RELEASE:=1
+PKG_RELEASE:=4
 PKG_HASH:=27877d0da6916f88a6cecbbb3f3d23cc4558ef7c7294324bf4fd050ed606b553
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
diff --git a/batctl/patches/0001-batctl-Return-EXIT_FAILURE-when-throughputmeter-fail.patch b/batctl/patches/0001-batctl-Return-EXIT_FAILURE-when-throughputmeter-fail.patch
new file mode 100644 (file)
index 0000000..87858f9
--- /dev/null
@@ -0,0 +1,37 @@
+From: Leonardo Mörlein <me@irrelefant.net>
+Date: Wed, 8 Apr 2020 23:49:03 +0200
+Subject: batctl: Return EXIT_FAILURE when throughputmeter failed
+
+The command returned a success even an error was shown during the
+execution.
+
+  $ (sudo batctl tp 77:77:77:77:77:77 && echo true) || echo false
+  Destination unreachable
+  true
+
+Instead it should indicate a failure when the kernel replied with a
+non-success return_value:
+
+  $ (sudo ./batctl tp 77:77:77:77:77:77 && echo true) || echo false
+  Destination unreachable
+  false
+
+Fixes: f109b3473f86 ("batctl: introduce throughput meter support")
+Signed-off-by: Leonardo Mörlein <me@irrelefant.net>
+[sven@narfation.org: adjusted commit message]
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batctl.git/commit/df8bf5164b6904f61ae0b0db090fb5bb41b4f06d
+
+diff --git a/tp_meter.c b/tp_meter.c
+index c7904857865c5b2a51cf30e7963394dd9b6c029c..403c88452b4ad56f4049f64829c6d2bdd015810a 100644
+--- a/tp_meter.c
++++ b/tp_meter.c
+@@ -480,6 +480,7 @@ int tp_meter(char *mesh_iface, int argc, char **argv)
+               goto out;
+       }
++      ret = EXIT_FAILURE;
+       switch (result.return_value) {
+       case BATADV_TP_REASON_DST_UNREACHABLE:
+               fprintf(stderr, "Destination unreachable\n");
diff --git a/batctl/patches/0002-batctl-fix-endianness-when-reading-radiotap-header.patch b/batctl/patches/0002-batctl-fix-endianness-when-reading-radiotap-header.patch
new file mode 100644 (file)
index 0000000..2816149
--- /dev/null
@@ -0,0 +1,38 @@
+From: Marek Lindner <mareklindner@neomailbox.ch>
+Date: Wed, 29 Apr 2020 12:09:44 +0200
+Subject: batctl: fix endianness when reading radiotap header
+
+All radiotap header fields are specified in little endian byte-order.
+Header length conversion is necessary on some platforms.
+
+Fixes: c6fcdb6dc9a9 ("batctl: add radiotap wifi packet decapsulation support")
+Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batctl.git/commit/440ae55a6ef96eb73ee628f9237915cf9fb26dee
+
+diff --git a/tcpdump.c b/tcpdump.c
+index dc4ccd37c3ddf8650cb79737defd923fe9f33c64..c41500e21eda0abc1f024a3265c23fc3a4802d17 100644
+--- a/tcpdump.c
++++ b/tcpdump.c
+@@ -29,6 +29,7 @@
+ #include <time.h>
+ #include <sys/time.h>
+ #include <arpa/inet.h>
++#include <endian.h>
+ #include <net/if.h>
+ #include <net/if_arp.h>
+ #include <netinet/in.h>
+@@ -1048,10 +1049,10 @@ static int monitor_header_length(unsigned char *packet_buff, ssize_t buff_len, i
+                       return -1;
+               radiotap_hdr = (struct radiotap_header*)packet_buff;
+-              if (buff_len <= radiotap_hdr->it_len)
++              if (buff_len <= le16toh(radiotap_hdr->it_len))
+                       return -1;
+               else
+-                      return radiotap_hdr->it_len;
++                      return le16toh(radiotap_hdr->it_len);
+       }
+       return -1;
diff --git a/batctl/patches/0003-batctl-Only-remove-batadv-interface-on-hardif-reduct.patch b/batctl/patches/0003-batctl-Only-remove-batadv-interface-on-hardif-reduct.patch
new file mode 100644 (file)
index 0000000..01cf039
--- /dev/null
@@ -0,0 +1,49 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sat, 13 Jun 2020 17:59:34 +0200
+Subject: batctl: Only remove batadv interface on hardif reduction
+
+A deletion of a hardif from a batadv meshif will also get a success reply
+from the kernel when the hardif was never part of the batadv meshif. If the
+batadv meshif had no attached hardifs before the removal was started, then
+users are then not expecting that the batadv meshif is removed at all.
+
+Since the delete operation is not an atomic compare-and-swap operation,
+just check first the number of attached interfaces and only start the
+removal of the batadv meshif when the number attached hardifs was reduced.
+
+Fixes: 25022e0b154d ("batctl: Use rtnl to add/remove interfaces")
+Reported-by: Matthias Schiffer <mschiffer@universe-factory.net>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batctl.git/commit/6d49a82cf58ee5ebd6235b6ddaca46febd42f876
+
+diff --git a/interface.c b/interface.c
+index 5951b471c6477e78ff557e97a7478ba774a0aa20..1ad36826fdb91a3e0254ed4dec758e7c383596e9 100644
+--- a/interface.c
++++ b/interface.c
+@@ -305,6 +305,7 @@ int interface(char *mesh_iface, int argc, char **argv)
+       int ret;
+       unsigned int ifindex;
+       unsigned int ifmaster;
++      unsigned int pre_cnt;
+       const char *long_op;
+       unsigned int cnt;
+       int rest_argc;
+@@ -421,6 +422,8 @@ int interface(char *mesh_iface, int argc, char **argv)
+               goto err;
+       }
++      pre_cnt = count_interfaces(mesh_iface);
++
+       for (i = 1; i < rest_argc; i++) {
+               ifindex = if_nametoindex(rest_argv[i]);
+@@ -450,7 +453,7 @@ int interface(char *mesh_iface, int argc, char **argv)
+       /* check if there is no interface left and then destroy mesh_iface */
+       if (!manual_mode && rest_argv[0][0] == 'd') {
+               cnt = count_interfaces(mesh_iface);
+-              if (cnt == 0)
++              if (cnt == 0 && pre_cnt > 0)
+                       destroy_interface(mesh_iface);
+       }
diff --git a/batctl/patches/0004-batctl-tcpdump-Fix-endianness-in-ICMPv6-Echo-Request.patch b/batctl/patches/0004-batctl-tcpdump-Fix-endianness-in-ICMPv6-Echo-Request.patch
new file mode 100644 (file)
index 0000000..b7250af
--- /dev/null
@@ -0,0 +1,39 @@
+From: Linus Lüssing <linus.luessing@c0d3.blue>
+Date: Sun, 13 Sep 2020 23:30:19 +0200
+Subject: batctl: tcpdump: Fix endianness in ICMPv6 Echo Request/Reply parsing
+
+The ICMPv6 Echo Request/Reply sequence number and id as well as the
+IPv6 header length are two byte long fields and therefore might need a
+conversion on a little endian system. Otherwise the output will be
+broken on such a machine.
+
+Fixes: 35b37756f4a3 ("add IPv6 support to tcpdump parser")
+Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batctl.git/commit/e42f73d0d2a04edfbed1b9d0ad9fd57af9e90faf
+
+diff --git a/tcpdump.c b/tcpdump.c
+index c41500e21eda0abc1f024a3265c23fc3a4802d17..22847aecf887566ac62ff2084079683d0acf83aa 100644
+--- a/tcpdump.c
++++ b/tcpdump.c
+@@ -551,13 +551,15 @@ static void dump_ipv6(unsigned char *packet_buff, ssize_t buff_len,
+                       break;
+               case ICMP6_ECHO_REQUEST:
+                       printf(" echo request, id: %d, seq: %d, length: %hu\n",
+-                             icmphdr->icmp6_id, icmphdr->icmp6_seq,
+-                             iphdr->ip6_plen);
++                             ntohs(icmphdr->icmp6_id),
++                             ntohs(icmphdr->icmp6_seq),
++                             ntohs(iphdr->ip6_plen));
+                       break;
+               case ICMP6_ECHO_REPLY:
+                       printf(" echo reply, id: %d, seq: %d, length: %hu\n",
+-                             icmphdr->icmp6_id, icmphdr->icmp6_seq,
+-                             iphdr->ip6_plen);
++                             ntohs(icmphdr->icmp6_id),
++                             ntohs(icmphdr->icmp6_seq),
++                             ntohs(iphdr->ip6_plen));
+                       break;
+               case ICMP6_TIME_EXCEEDED:
+                       printf(" time exceeded in-transit, length %zu\n",
index f987b9839fbf802fb0ece0853a3d50751ec4e75a..9df29a7feeaddca3a7b0fc247f58cde0ccd1396f 100644 (file)
@@ -10,7 +10,7 @@ include $(TOPDIR)/rules.mk
 PKG_NAME:=batman-adv
 
 PKG_VERSION:=2018.1
-PKG_RELEASE:=7
+PKG_RELEASE:=13
 PKG_HASH:=b866b28dbbe5c9238abbdf5abbc30fc526dea56898ce4c1bd76d5c017843048b
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
diff --git a/batman-adv/patches/0032-batman-adv-Fix-duplicated-OGMs-on-NETDEV_UP.patch b/batman-adv/patches/0032-batman-adv-Fix-duplicated-OGMs-on-NETDEV_UP.patch
new file mode 100644 (file)
index 0000000..e8902cd
--- /dev/null
@@ -0,0 +1,77 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sun, 2 Jun 2019 10:57:31 +0200
+Subject: batman-adv: Fix duplicated OGMs on NETDEV_UP
+
+The state of slave interfaces are handled differently depending on whether
+the interface is up or not. All active interfaces (IFF_UP) will transmit
+OGMs. But for B.A.T.M.A.N. IV, also non-active interfaces are scheduling
+(low TTL) OGMs on active interfaces. The code which setups and schedules
+the OGMs must therefore already be called when the interfaces gets added as
+slave interface and the transmit function must then check whether it has to
+send out the OGM or not on the specific slave interface.
+
+But the commit 0d8468553c3c ("batman-adv: remove ogm_emit and ogm_schedule
+API calls") moved the setup code from the enable function to the activate
+function. The latter is called either when the added slave was already up
+when batadv_hardif_enable_interface processed the new interface or when a
+NETDEV_UP event was received for this slave interfac. As result, each
+NETDEV_UP would schedule a new OGM worker for the interface and thus OGMs
+would be send a lot more than expected.
+
+Fixes: 0d8468553c3c ("batman-adv: remove ogm_emit and ogm_schedule API calls")
+Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/c92331e0df3c0c5645ee5a897eb018c5da5e4aa5
+
+diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
+index 73bf6a93a3cf1141a34657bf1284893199e04db9..0b7b36fa0d5cd440ddef141ad27acfe7b20aee43 100644
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -2485,7 +2485,7 @@ batadv_iv_ogm_neigh_is_sob(struct batadv_neigh_node *neigh1,
+       return ret;
+ }
+-static void batadv_iv_iface_activate(struct batadv_hard_iface *hard_iface)
++static void batadv_iv_iface_enabled(struct batadv_hard_iface *hard_iface)
+ {
+       /* begin scheduling originator messages on that interface */
+       batadv_iv_ogm_schedule(hard_iface);
+@@ -2825,8 +2825,8 @@ static void batadv_iv_gw_dump(struct sk_buff *msg, struct netlink_callback *cb,
+ static struct batadv_algo_ops batadv_batman_iv __read_mostly = {
+       .name = "BATMAN_IV",
+       .iface = {
+-              .activate = batadv_iv_iface_activate,
+               .enable = batadv_iv_ogm_iface_enable,
++              .enabled = batadv_iv_iface_enabled,
+               .disable = batadv_iv_ogm_iface_disable,
+               .update_mac = batadv_iv_ogm_iface_update_mac,
+               .primary_set = batadv_iv_ogm_primary_iface_set,
+diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
+index 08690d06b7be2b25ca3f009394763c7083c70644..36f0962040d16af4f9ed82629ff03ce85c83ed57 100644
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -821,6 +821,9 @@ int batadv_hardif_enable_interface(struct batadv_hard_iface *hard_iface,
+       batadv_hardif_recalc_extra_skbroom(soft_iface);
++      if (bat_priv->algo_ops->iface.enabled)
++              bat_priv->algo_ops->iface.enabled(hard_iface);
++
+ out:
+       return 0;
+diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
+index 6d07898d8d1a21007b3e68d5d2511b478110f659..86f37db7dd01592aff95ada5ba5441667971e1bc 100644
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -2126,6 +2126,9 @@ struct batadv_algo_iface_ops {
+       /** @enable: init routing info when hard-interface is enabled */
+       int (*enable)(struct batadv_hard_iface *hard_iface);
++      /** @enabled: notification when hard-interface was enabled (optional) */
++      void (*enabled)(struct batadv_hard_iface *hard_iface);
++
+       /** @disable: de-init routing info when hard-interface is disabled */
+       void (*disable)(struct batadv_hard_iface *hard_iface);
diff --git a/batman-adv/patches/0033-batman-adv-fix-uninit-value-in-batadv_netlink_get_if.patch b/batman-adv/patches/0033-batman-adv-fix-uninit-value-in-batadv_netlink_get_if.patch
new file mode 100644 (file)
index 0000000..3b49860
--- /dev/null
@@ -0,0 +1,58 @@
+From: Eric Dumazet <edumazet@google.com>
+Date: Mon, 12 Aug 2019 04:57:27 -0700
+Subject: batman-adv: fix uninit-value in batadv_netlink_get_ifindex()
+
+batadv_netlink_get_ifindex() needs to make sure user passed
+a correct u32 attribute.
+
+syzbot reported :
+BUG: KMSAN: uninit-value in batadv_netlink_dump_hardif+0x70d/0x880 net/batman-adv/netlink.c:968
+CPU: 1 PID: 11705 Comm: syz-executor888 Not tainted 5.1.0+ #1
+Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
+Call Trace:
+ __dump_stack lib/dump_stack.c:77 [inline]
+ dump_stack+0x191/0x1f0 lib/dump_stack.c:113
+ kmsan_report+0x130/0x2a0 mm/kmsan/kmsan.c:622
+ __msan_warning+0x75/0xe0 mm/kmsan/kmsan_instr.c:310
+ batadv_netlink_dump_hardif+0x70d/0x880 net/batman-adv/netlink.c:968
+ genl_lock_dumpit+0xc6/0x130 net/netlink/genetlink.c:482
+ netlink_dump+0xa84/0x1ab0 net/netlink/af_netlink.c:2253
+ __netlink_dump_start+0xa3a/0xb30 net/netlink/af_netlink.c:2361
+ genl_family_rcv_msg net/netlink/genetlink.c:550 [inline]
+ genl_rcv_msg+0xfc1/0x1a40 net/netlink/genetlink.c:627
+ netlink_rcv_skb+0x431/0x620 net/netlink/af_netlink.c:2486
+ genl_rcv+0x63/0x80 net/netlink/genetlink.c:638
+ netlink_unicast_kernel net/netlink/af_netlink.c:1311 [inline]
+ netlink_unicast+0xf3e/0x1020 net/netlink/af_netlink.c:1337
+ netlink_sendmsg+0x127e/0x12f0 net/netlink/af_netlink.c:1926
+ sock_sendmsg_nosec net/socket.c:651 [inline]
+ sock_sendmsg net/socket.c:661 [inline]
+ ___sys_sendmsg+0xcc6/0x1200 net/socket.c:2260
+ __sys_sendmsg net/socket.c:2298 [inline]
+ __do_sys_sendmsg net/socket.c:2307 [inline]
+ __se_sys_sendmsg+0x305/0x460 net/socket.c:2305
+ __x64_sys_sendmsg+0x4a/0x70 net/socket.c:2305
+ do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:291
+ entry_SYSCALL_64_after_hwframe+0x63/0xe7
+RIP: 0033:0x440209
+
+Fixes: 55d368c3a57e ("batman-adv: netlink: hardif query")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/9b470b8a2b9ef4ce68d6e95febd3a0574be1ac14
+
+diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
+index 0d9459b69bdb812b1b68e28e6b68fec8ec95df2d..c32820963b8e706b4cdde10d46ec582bc51ec4eb 100644
+--- a/net/batman-adv/netlink.c
++++ b/net/batman-adv/netlink.c
+@@ -118,7 +118,7 @@ batadv_netlink_get_ifindex(const struct nlmsghdr *nlh, int attrtype)
+ {
+       struct nlattr *attr = nlmsg_find_attr(nlh, GENL_HDRLEN, attrtype);
+-      return attr ? nla_get_u32(attr) : 0;
++      return (attr && nla_len(attr) == sizeof(u32)) ? nla_get_u32(attr) : 0;
+ }
+ /**
diff --git a/batman-adv/patches/0034-batman-adv-Only-read-OGM-tvlv_len-after-buffer-len-c.patch b/batman-adv/patches/0034-batman-adv-Only-read-OGM-tvlv_len-after-buffer-len-c.patch
new file mode 100644 (file)
index 0000000..a6fc524
--- /dev/null
@@ -0,0 +1,74 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Fri, 23 Aug 2019 14:34:27 +0200
+Subject: batman-adv: Only read OGM tvlv_len after buffer len check
+
+Multiple batadv_ogm_packet can be stored in an skbuff. The functions
+batadv_iv_ogm_send_to_if()/batadv_iv_ogm_receive() use
+batadv_iv_ogm_aggr_packet() to check if there is another additional
+batadv_ogm_packet in the skb or not before they continue processing the
+packet.
+
+The length for such an OGM is BATADV_OGM_HLEN +
+batadv_ogm_packet->tvlv_len. The check must first check that at least
+BATADV_OGM_HLEN bytes are available before it accesses tvlv_len (which is
+part of the header. Otherwise it might try read outside of the currently
+available skbuff to get the content of tvlv_len.
+
+Fixes: 0b6aa0d43767 ("batman-adv: tvlv - basic infrastructure")
+Reported-by: syzbot+355cab184197dbbfa384@syzkaller.appspotmail.com
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Acked-by: Antonio Quartulli <a@unstable.cc>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/07b6051ebcfaa7ea89b4f278eca2ff4070d29e56
+
+diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
+index 0b7b36fa0d5cd440ddef141ad27acfe7b20aee43..36f244125d24c800d35249af7639d39a516588d4 100644
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -463,17 +463,23 @@ static u8 batadv_hop_penalty(u8 tq, const struct batadv_priv *bat_priv)
+  * batadv_iv_ogm_aggr_packet() - checks if there is another OGM attached
+  * @buff_pos: current position in the skb
+  * @packet_len: total length of the skb
+- * @tvlv_len: tvlv length of the previously considered OGM
++ * @ogm_packet: potential OGM in buffer
+  *
+  * Return: true if there is enough space for another OGM, false otherwise.
+  */
+-static bool batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
+-                                    __be16 tvlv_len)
++static bool
++batadv_iv_ogm_aggr_packet(int buff_pos, int packet_len,
++                        const struct batadv_ogm_packet *ogm_packet)
+ {
+       int next_buff_pos = 0;
+-      next_buff_pos += buff_pos + BATADV_OGM_HLEN;
+-      next_buff_pos += ntohs(tvlv_len);
++      /* check if there is enough space for the header */
++      next_buff_pos += buff_pos + sizeof(*ogm_packet);
++      if (next_buff_pos > packet_len)
++              return false;
++
++      /* check if there is enough space for the optional TVLV */
++      next_buff_pos += ntohs(ogm_packet->tvlv_len);
+       return (next_buff_pos <= packet_len) &&
+              (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
+@@ -501,7 +507,7 @@ static void batadv_iv_ogm_send_to_if(struct batadv_forw_packet *forw_packet,
+       /* adjust all flags and log packets */
+       while (batadv_iv_ogm_aggr_packet(buff_pos, forw_packet->packet_len,
+-                                       batadv_ogm_packet->tvlv_len)) {
++                                       batadv_ogm_packet)) {
+               /* we might have aggregated direct link packets with an
+                * ordinary base packet
+                */
+@@ -1852,7 +1858,7 @@ static int batadv_iv_ogm_receive(struct sk_buff *skb,
+       /* unpack the aggregated packets and process them one by one */
+       while (batadv_iv_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
+-                                       ogm_packet->tvlv_len)) {
++                                       ogm_packet)) {
+               batadv_iv_ogm_process(skb, ogm_offset, if_incoming);
+               ogm_offset += BATADV_OGM_HLEN;
diff --git a/batman-adv/patches/0035-batman-adv-Only-read-OGM2-tvlv_len-after-buffer-len-.patch b/batman-adv/patches/0035-batman-adv-Only-read-OGM2-tvlv_len-after-buffer-len-.patch
new file mode 100644 (file)
index 0000000..81c0fef
--- /dev/null
@@ -0,0 +1,62 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Fri, 23 Aug 2019 14:34:28 +0200
+Subject: batman-adv: Only read OGM2 tvlv_len after buffer len check
+
+Multiple batadv_ogm2_packet can be stored in an skbuff. The functions
+batadv_v_ogm_send_to_if() uses batadv_v_ogm_aggr_packet() to check if there
+is another additional batadv_ogm2_packet in the skb or not before they
+continue processing the packet.
+
+The length for such an OGM2 is BATADV_OGM2_HLEN +
+batadv_ogm2_packet->tvlv_len. The check must first check that at least
+BATADV_OGM2_HLEN bytes are available before it accesses tvlv_len (which is
+part of the header. Otherwise it might try read outside of the currently
+available skbuff to get the content of tvlv_len.
+
+Fixes: 667996ebeab4 ("batman-adv: OGMv2 - implement originators logic")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/18f77da3761c5550f42a2d131f0fe5cac62e022d
+
+diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
+index 2948b41b06d47c0ee32649fa410b323f39c36151..d241ccc0ca0278173853512c8aa4bfb8b041f996 100644
+--- a/net/batman-adv/bat_v_ogm.c
++++ b/net/batman-adv/bat_v_ogm.c
+@@ -643,17 +643,23 @@ batadv_v_ogm_process_per_outif(struct batadv_priv *bat_priv,
+  * batadv_v_ogm_aggr_packet() - checks if there is another OGM aggregated
+  * @buff_pos: current position in the skb
+  * @packet_len: total length of the skb
+- * @tvlv_len: tvlv length of the previously considered OGM
++ * @ogm2_packet: potential OGM2 in buffer
+  *
+  * Return: true if there is enough space for another OGM, false otherwise.
+  */
+-static bool batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
+-                                   __be16 tvlv_len)
++static bool
++batadv_v_ogm_aggr_packet(int buff_pos, int packet_len,
++                       const struct batadv_ogm2_packet *ogm2_packet)
+ {
+       int next_buff_pos = 0;
+-      next_buff_pos += buff_pos + BATADV_OGM2_HLEN;
+-      next_buff_pos += ntohs(tvlv_len);
++      /* check if there is enough space for the header */
++      next_buff_pos += buff_pos + sizeof(*ogm2_packet);
++      if (next_buff_pos > packet_len)
++              return false;
++
++      /* check if there is enough space for the optional TVLV */
++      next_buff_pos += ntohs(ogm2_packet->tvlv_len);
+       return (next_buff_pos <= packet_len) &&
+              (next_buff_pos <= BATADV_MAX_AGGREGATION_BYTES);
+@@ -830,7 +836,7 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb,
+       ogm_packet = (struct batadv_ogm2_packet *)skb->data;
+       while (batadv_v_ogm_aggr_packet(ogm_offset, skb_headlen(skb),
+-                                      ogm_packet->tvlv_len)) {
++                                      ogm_packet)) {
+               batadv_v_ogm_process(skb, ogm_offset, if_incoming);
+               ogm_offset += BATADV_OGM2_HLEN;
diff --git a/batman-adv/patches/0036-batman-adv-Avoid-free-alloc-race-when-handling-OGM2-.patch b/batman-adv/patches/0036-batman-adv-Avoid-free-alloc-race-when-handling-OGM2-.patch
new file mode 100644 (file)
index 0000000..b4afbf3
--- /dev/null
@@ -0,0 +1,119 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Thu, 3 Oct 2019 17:02:01 +0200
+Subject: batman-adv: Avoid free/alloc race when handling OGM2 buffer
+
+A B.A.T.M.A.N. V virtual interface has an OGM2 packet buffer which is
+initialized using data from the RTNL lock protected netdevice notifier and
+other rtnetlink related hooks. It is sent regularly via various slave
+interfaces of the batadv virtual interface and in this process also
+modified (realloced) to integrate additional state information via TVLV
+containers.
+
+It must be avoided that the worker item is executed without a common lock
+with the netdevice notifier/rtnetlink helpers. Otherwise it can either
+happen that half modified data is sent out or the functions modifying the
+OGM2 buffer try to access already freed memory regions.
+
+Fixes: 632835348e65 ("batman-adv: OGMv2 - add basic infrastructure")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/14ee24576213ff02272b7f8d975c7c61d5448aa2
+
+diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
+index d241ccc0ca0278173853512c8aa4bfb8b041f996..a9f949501ff3c354d38e3ad333901310391f27d8 100644
+--- a/net/batman-adv/bat_v_ogm.c
++++ b/net/batman-adv/bat_v_ogm.c
+@@ -33,6 +33,7 @@
+ #include <linux/random.h>
+ #include <linux/rculist.h>
+ #include <linux/rcupdate.h>
++#include <linux/rtnetlink.h>
+ #include <linux/skbuff.h>
+ #include <linux/slab.h>
+ #include <linux/stddef.h>
+@@ -128,14 +129,12 @@ static void batadv_v_ogm_send_to_if(struct sk_buff *skb,
+ }
+ /**
+- * batadv_v_ogm_send() - periodic worker broadcasting the own OGM
+- * @work: work queue item
++ * batadv_v_ogm_send_softif() - periodic worker broadcasting the own OGM
++ * @bat_priv: the bat priv with all the soft interface information
+  */
+-static void batadv_v_ogm_send(struct work_struct *work)
++static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv)
+ {
+       struct batadv_hard_iface *hard_iface;
+-      struct batadv_priv_bat_v *bat_v;
+-      struct batadv_priv *bat_priv;
+       struct batadv_ogm2_packet *ogm_packet;
+       struct sk_buff *skb, *skb_tmp;
+       unsigned char *ogm_buff;
+@@ -143,8 +142,7 @@ static void batadv_v_ogm_send(struct work_struct *work)
+       u16 tvlv_len = 0;
+       int ret;
+-      bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
+-      bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
++      ASSERT_RTNL();
+       if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
+               goto out;
+@@ -235,6 +233,22 @@ static void batadv_v_ogm_send(struct work_struct *work)
+       return;
+ }
++/**
++ * batadv_v_ogm_send() - periodic worker broadcasting the own OGM
++ * @work: work queue item
++ */
++static void batadv_v_ogm_send(struct work_struct *work)
++{
++      struct batadv_priv_bat_v *bat_v;
++      struct batadv_priv *bat_priv;
++
++      rtnl_lock();
++      bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
++      bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
++      batadv_v_ogm_send_softif(bat_priv);
++      rtnl_unlock();
++}
++
+ /**
+  * batadv_v_ogm_iface_enable() - prepare an interface for B.A.T.M.A.N. V
+  * @hard_iface: the interface to prepare
+@@ -261,6 +275,8 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface)
+       struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface);
+       struct batadv_ogm2_packet *ogm_packet;
++      ASSERT_RTNL();
++
+       if (!bat_priv->bat_v.ogm_buff)
+               return;
+@@ -869,6 +885,8 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv)
+       unsigned char *ogm_buff;
+       u32 random_seqno;
++      ASSERT_RTNL();
++
+       bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN;
+       ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC);
+       if (!ogm_buff)
+diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
+index 86f37db7dd01592aff95ada5ba5441667971e1bc..3392198ff146ba77d320104663e97ab21559d556 100644
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -1479,10 +1479,10 @@ struct batadv_softif_vlan {
+  * struct batadv_priv_bat_v - B.A.T.M.A.N. V per soft-interface private data
+  */
+ struct batadv_priv_bat_v {
+-      /** @ogm_buff: buffer holding the OGM packet */
++      /** @ogm_buff: buffer holding the OGM packet. rtnl protected */
+       unsigned char *ogm_buff;
+-      /** @ogm_buff_len: length of the OGM packet buffer */
++      /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */
+       int ogm_buff_len;
+       /** @ogm_seqno: OGM sequence number - used to identify each OGM */
diff --git a/batman-adv/patches/0037-batman-adv-Avoid-free-alloc-race-when-handling-OGM-b.patch b/batman-adv/patches/0037-batman-adv-Avoid-free-alloc-race-when-handling-OGM-b.patch
new file mode 100644 (file)
index 0000000..67f635c
--- /dev/null
@@ -0,0 +1,136 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Thu, 3 Oct 2019 17:02:01 +0200
+Subject: batman-adv: Avoid free/alloc race when handling OGM buffer
+
+Each slave interface of an B.A.T.M.A.N. IV virtual interface has an OGM
+packet buffer which is initialized using data from the RTNL lock protected
+netdevice notifier and other rtnetlink related hooks. It is sent regularly
+via various slave interfaces of the batadv virtual interface and in this
+process also modified (realloced) to integrate additional state information
+via TVLV containers.
+
+It must be avoided that the worker item is executed without a common lock
+with the netdevice notifier/rtnetlink helpers. Otherwise it can either
+happen that half modified/freed data is sent out or functions modifying the
+OGM buffer try to access already freed memory regions.
+
+Reported-by: syzbot+0cc629f19ccb8534935b@syzkaller.appspotmail.com
+Fixes: ea6f8d42a595 ("batman-adv: move /proc interface handling to /sys")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/9b8ceef26c697d0c8319748428944c3339a498dc
+
+diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
+index 36f244125d24c800d35249af7639d39a516588d4..5b2ef12cfabb24ccbe2c1848cfff4d1ded9bd0b0 100644
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -42,6 +42,7 @@
+ #include <linux/random.h>
+ #include <linux/rculist.h>
+ #include <linux/rcupdate.h>
++#include <linux/rtnetlink.h>
+ #include <linux/seq_file.h>
+ #include <linux/skbuff.h>
+ #include <linux/slab.h>
+@@ -379,6 +380,8 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
+       unsigned char *ogm_buff;
+       u32 random_seqno;
++      ASSERT_RTNL();
++
+       /* randomize initial seqno to avoid collision */
+       get_random_bytes(&random_seqno, sizeof(random_seqno));
+       atomic_set(&hard_iface->bat_iv.ogm_seqno, random_seqno);
+@@ -403,6 +406,8 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
+ static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
+ {
++      ASSERT_RTNL();
++
+       kfree(hard_iface->bat_iv.ogm_buff);
+       hard_iface->bat_iv.ogm_buff = NULL;
+ }
+@@ -412,6 +417,8 @@ static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
+       struct batadv_ogm_packet *batadv_ogm_packet;
+       unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
++      ASSERT_RTNL();
++
+       batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
+       ether_addr_copy(batadv_ogm_packet->orig,
+                       hard_iface->net_dev->dev_addr);
+@@ -425,6 +432,8 @@ batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
+       struct batadv_ogm_packet *batadv_ogm_packet;
+       unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
++      ASSERT_RTNL();
++
+       batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
+       batadv_ogm_packet->ttl = BATADV_TTL;
+ }
+@@ -935,6 +944,8 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
+       u16 tvlv_len = 0;
+       unsigned long send_time;
++      ASSERT_RTNL();
++
+       if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
+           hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
+               return;
+@@ -1791,16 +1802,12 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
+       batadv_orig_node_put(orig_node);
+ }
+-static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
++static void
++batadv_iv_send_outstanding_forw_packet(struct batadv_forw_packet *forw_packet)
+ {
+-      struct delayed_work *delayed_work;
+-      struct batadv_forw_packet *forw_packet;
+       struct batadv_priv *bat_priv;
+       bool dropped = false;
+-      delayed_work = to_delayed_work(work);
+-      forw_packet = container_of(delayed_work, struct batadv_forw_packet,
+-                                 delayed_work);
+       bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
+       if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
+@@ -1829,6 +1836,20 @@ static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
+               batadv_forw_packet_free(forw_packet, dropped);
+ }
++static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
++{
++      struct delayed_work *delayed_work;
++      struct batadv_forw_packet *forw_packet;
++
++      delayed_work = to_delayed_work(work);
++      forw_packet = container_of(delayed_work, struct batadv_forw_packet,
++                                 delayed_work);
++
++      rtnl_lock();
++      batadv_iv_send_outstanding_forw_packet(forw_packet);
++      rtnl_unlock();
++}
++
+ static int batadv_iv_ogm_receive(struct sk_buff *skb,
+                                struct batadv_hard_iface *if_incoming)
+ {
+diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
+index 3392198ff146ba77d320104663e97ab21559d556..49e4e6cb506f192e85e96e8b3e68be3fdc2dca57 100644
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -82,10 +82,10 @@ enum batadv_dhcp_recipient {
+  * struct batadv_hard_iface_bat_iv - per hard-interface B.A.T.M.A.N. IV data
+  */
+ struct batadv_hard_iface_bat_iv {
+-      /** @ogm_buff: buffer holding the OGM packet */
++      /** @ogm_buff: buffer holding the OGM packet. rtnl protected */
+       unsigned char *ogm_buff;
+-      /** @ogm_buff_len: length of the OGM packet buffer */
++      /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */
+       int ogm_buff_len;
+       /** @ogm_seqno: OGM sequence number - used to identify each OGM */
diff --git a/batman-adv/patches/0038-batman-adv-Introduce-own-OGM2-buffer-mutex.patch b/batman-adv/patches/0038-batman-adv-Introduce-own-OGM2-buffer-mutex.patch
new file mode 100644 (file)
index 0000000..0a0d32e
--- /dev/null
@@ -0,0 +1,138 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sun, 13 Oct 2019 21:03:06 +0200
+Subject: batman-adv: Introduce own OGM2 buffer mutex
+
+Only a single function is currently automatically locked by the rtnl_lock
+because (unlike B.A.T.M.A.N. IV) the OGM2 buffer is independent of the hard
+interfaces on which it will be transmitted. A private mutex can be used
+instead to avoid unnecessary delays which would have been introduced by the
+global lock.
+
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/8069c581f9097f1f9398f2d49047a1dab8093821
+
+diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
+index a9f949501ff3c354d38e3ad333901310391f27d8..bf9ea404abe7cbe1dd2113881856cd35b718b7d1 100644
+--- a/net/batman-adv/bat_v_ogm.c
++++ b/net/batman-adv/bat_v_ogm.c
+@@ -29,11 +29,12 @@
+ #include <linux/kernel.h>
+ #include <linux/kref.h>
+ #include <linux/list.h>
++#include <linux/lockdep.h>
++#include <linux/mutex.h>
+ #include <linux/netdevice.h>
+ #include <linux/random.h>
+ #include <linux/rculist.h>
+ #include <linux/rcupdate.h>
+-#include <linux/rtnetlink.h>
+ #include <linux/skbuff.h>
+ #include <linux/slab.h>
+ #include <linux/stddef.h>
+@@ -142,7 +143,7 @@ static void batadv_v_ogm_send_softif(struct batadv_priv *bat_priv)
+       u16 tvlv_len = 0;
+       int ret;
+-      ASSERT_RTNL();
++      lockdep_assert_held(&bat_priv->bat_v.ogm_buff_mutex);
+       if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING)
+               goto out;
+@@ -242,11 +243,12 @@ static void batadv_v_ogm_send(struct work_struct *work)
+       struct batadv_priv_bat_v *bat_v;
+       struct batadv_priv *bat_priv;
+-      rtnl_lock();
+       bat_v = container_of(work, struct batadv_priv_bat_v, ogm_wq.work);
+       bat_priv = container_of(bat_v, struct batadv_priv, bat_v);
++
++      mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
+       batadv_v_ogm_send_softif(bat_priv);
+-      rtnl_unlock();
++      mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
+ }
+ /**
+@@ -275,13 +277,15 @@ void batadv_v_ogm_primary_iface_set(struct batadv_hard_iface *primary_iface)
+       struct batadv_priv *bat_priv = netdev_priv(primary_iface->soft_iface);
+       struct batadv_ogm2_packet *ogm_packet;
+-      ASSERT_RTNL();
+-
++      mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
+       if (!bat_priv->bat_v.ogm_buff)
+-              return;
++              goto unlock;
+       ogm_packet = (struct batadv_ogm2_packet *)bat_priv->bat_v.ogm_buff;
+       ether_addr_copy(ogm_packet->orig, primary_iface->net_dev->dev_addr);
++
++unlock:
++      mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
+ }
+ /**
+@@ -885,8 +889,6 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv)
+       unsigned char *ogm_buff;
+       u32 random_seqno;
+-      ASSERT_RTNL();
+-
+       bat_priv->bat_v.ogm_buff_len = BATADV_OGM2_HLEN;
+       ogm_buff = kzalloc(bat_priv->bat_v.ogm_buff_len, GFP_ATOMIC);
+       if (!ogm_buff)
+@@ -905,6 +907,8 @@ int batadv_v_ogm_init(struct batadv_priv *bat_priv)
+       atomic_set(&bat_priv->bat_v.ogm_seqno, random_seqno);
+       INIT_DELAYED_WORK(&bat_priv->bat_v.ogm_wq, batadv_v_ogm_send);
++      mutex_init(&bat_priv->bat_v.ogm_buff_mutex);
++
+       return 0;
+ }
+@@ -916,7 +920,11 @@ void batadv_v_ogm_free(struct batadv_priv *bat_priv)
+ {
+       cancel_delayed_work_sync(&bat_priv->bat_v.ogm_wq);
++      mutex_lock(&bat_priv->bat_v.ogm_buff_mutex);
++
+       kfree(bat_priv->bat_v.ogm_buff);
+       bat_priv->bat_v.ogm_buff = NULL;
+       bat_priv->bat_v.ogm_buff_len = 0;
++
++      mutex_unlock(&bat_priv->bat_v.ogm_buff_mutex);
+ }
+diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
+index 49e4e6cb506f192e85e96e8b3e68be3fdc2dca57..44c423447fe163eb3b9df5ec5cf229bed6b8d65b 100644
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -28,6 +28,7 @@
+ #include <linux/compiler.h>
+ #include <linux/if_ether.h>
+ #include <linux/kref.h>
++#include <linux/mutex.h>
+ #include <linux/netdevice.h>
+ #include <linux/netlink.h>
+ #include <linux/sched.h> /* for linux/wait.h */
+@@ -1479,15 +1480,18 @@ struct batadv_softif_vlan {
+  * struct batadv_priv_bat_v - B.A.T.M.A.N. V per soft-interface private data
+  */
+ struct batadv_priv_bat_v {
+-      /** @ogm_buff: buffer holding the OGM packet. rtnl protected */
++      /** @ogm_buff: buffer holding the OGM packet */
+       unsigned char *ogm_buff;
+-      /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */
++      /** @ogm_buff_len: length of the OGM packet buffer */
+       int ogm_buff_len;
+       /** @ogm_seqno: OGM sequence number - used to identify each OGM */
+       atomic_t ogm_seqno;
++      /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */
++      struct mutex ogm_buff_mutex;
++
+       /** @ogm_wq: workqueue used to schedule OGM transmissions */
+       struct delayed_work ogm_wq;
+ };
diff --git a/batman-adv/patches/0039-batman-adv-Avoid-OGM-workqueue-synchronous-cancel-de.patch b/batman-adv/patches/0039-batman-adv-Avoid-OGM-workqueue-synchronous-cancel-de.patch
new file mode 100644 (file)
index 0000000..1b0a1de
--- /dev/null
@@ -0,0 +1,262 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sun, 13 Oct 2019 21:03:07 +0200
+Subject: batman-adv: Avoid OGM workqueue synchronous cancel deadlock
+
+batadv_forw_packet_list_free can be called when an interface is being
+disabled. Under this circumstance, the rntl_lock will be held and while it
+calls cancel_delayed_work_sync.
+
+cancel_delayed_work_sync will stop the execution of the current context
+when the work item is currently processed. It can now happen that the
+cancel_delayed_work_sync was called when rtnl_lock was already called in
+batadv_iv_send_outstanding_bat_ogm_packet or when it was in the process of
+calling it. In this case, batadv_iv_send_outstanding_bat_ogm_packet waits
+for the lock and cancel_delayed_work_sync (which holds the rtnl_lock) is
+waiting for batadv_iv_send_outstanding_bat_ogm_packet to finish.
+
+This can only be avoided by not using (conflicting) blocking locks while
+cancel_delayed_work_sync is called. It also has the benefit that the
+ogm scheduling functionality can avoid unnecessary delays which can be
+introduced by a global lock.
+
+Fixes: 9b8ceef26c69 ("batman-adv: Avoid free/alloc race when handling OGM buffer")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d3be478f1aa27b47f61c4a62e18eb063d47c9168
+
+diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
+index 5b2ef12cfabb24ccbe2c1848cfff4d1ded9bd0b0..f5941837c3ad463f276cffdb25f9b6cd87af0e92 100644
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -35,6 +35,7 @@
+ #include <linux/kref.h>
+ #include <linux/list.h>
+ #include <linux/lockdep.h>
++#include <linux/mutex.h>
+ #include <linux/netdevice.h>
+ #include <linux/netlink.h>
+ #include <linux/pkt_sched.h>
+@@ -42,7 +43,6 @@
+ #include <linux/random.h>
+ #include <linux/rculist.h>
+ #include <linux/rcupdate.h>
+-#include <linux/rtnetlink.h>
+ #include <linux/seq_file.h>
+ #include <linux/skbuff.h>
+ #include <linux/slab.h>
+@@ -380,7 +380,7 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
+       unsigned char *ogm_buff;
+       u32 random_seqno;
+-      ASSERT_RTNL();
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
+       /* randomize initial seqno to avoid collision */
+       get_random_bytes(&random_seqno, sizeof(random_seqno));
+@@ -388,8 +388,10 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
+       hard_iface->bat_iv.ogm_buff_len = BATADV_OGM_HLEN;
+       ogm_buff = kmalloc(hard_iface->bat_iv.ogm_buff_len, GFP_ATOMIC);
+-      if (!ogm_buff)
++      if (!ogm_buff) {
++              mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+               return -ENOMEM;
++      }
+       hard_iface->bat_iv.ogm_buff = ogm_buff;
+@@ -401,41 +403,59 @@ static int batadv_iv_ogm_iface_enable(struct batadv_hard_iface *hard_iface)
+       batadv_ogm_packet->reserved = 0;
+       batadv_ogm_packet->tq = BATADV_TQ_MAX_VALUE;
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
++
+       return 0;
+ }
+ static void batadv_iv_ogm_iface_disable(struct batadv_hard_iface *hard_iface)
+ {
+-      ASSERT_RTNL();
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
+       kfree(hard_iface->bat_iv.ogm_buff);
+       hard_iface->bat_iv.ogm_buff = NULL;
++
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+ }
+ static void batadv_iv_ogm_iface_update_mac(struct batadv_hard_iface *hard_iface)
+ {
+       struct batadv_ogm_packet *batadv_ogm_packet;
+-      unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
++      void *ogm_buff;
+-      ASSERT_RTNL();
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
+-      batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
++      ogm_buff = hard_iface->bat_iv.ogm_buff;
++      if (!ogm_buff)
++              goto unlock;
++
++      batadv_ogm_packet = ogm_buff;
+       ether_addr_copy(batadv_ogm_packet->orig,
+                       hard_iface->net_dev->dev_addr);
+       ether_addr_copy(batadv_ogm_packet->prev_sender,
+                       hard_iface->net_dev->dev_addr);
++
++unlock:
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+ }
+ static void
+ batadv_iv_ogm_primary_iface_set(struct batadv_hard_iface *hard_iface)
+ {
+       struct batadv_ogm_packet *batadv_ogm_packet;
+-      unsigned char *ogm_buff = hard_iface->bat_iv.ogm_buff;
++      void *ogm_buff;
+-      ASSERT_RTNL();
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
+-      batadv_ogm_packet = (struct batadv_ogm_packet *)ogm_buff;
++      ogm_buff = hard_iface->bat_iv.ogm_buff;
++      if (!ogm_buff)
++              goto unlock;
++
++      batadv_ogm_packet = ogm_buff;
+       batadv_ogm_packet->ttl = BATADV_TTL;
++
++unlock:
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
+ }
+ /* when do we schedule our own ogm to be sent */
+@@ -933,7 +953,11 @@ batadv_iv_ogm_slide_own_bcast_window(struct batadv_hard_iface *hard_iface)
+       }
+ }
+-static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
++/**
++ * batadv_iv_ogm_schedule_buff() - schedule submission of hardif ogm buffer
++ * @hard_iface: interface whose ogm buffer should be transmitted
++ */
++static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
+ {
+       struct batadv_priv *bat_priv = netdev_priv(hard_iface->soft_iface);
+       unsigned char **ogm_buff = &hard_iface->bat_iv.ogm_buff;
+@@ -944,11 +968,7 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
+       u16 tvlv_len = 0;
+       unsigned long send_time;
+-      ASSERT_RTNL();
+-
+-      if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
+-          hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
+-              return;
++      lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
+       /* the interface gets activated here to avoid race conditions between
+        * the moment of activating the interface in
+@@ -1016,6 +1036,17 @@ static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
+               batadv_hardif_put(primary_if);
+ }
++static void batadv_iv_ogm_schedule(struct batadv_hard_iface *hard_iface)
++{
++      if (hard_iface->if_status == BATADV_IF_NOT_IN_USE ||
++          hard_iface->if_status == BATADV_IF_TO_BE_REMOVED)
++              return;
++
++      mutex_lock(&hard_iface->bat_iv.ogm_buff_mutex);
++      batadv_iv_ogm_schedule_buff(hard_iface);
++      mutex_unlock(&hard_iface->bat_iv.ogm_buff_mutex);
++}
++
+ /**
+  * batadv_iv_ogm_orig_update() - use OGM to update corresponding data in an
+  *  originator
+@@ -1802,12 +1833,16 @@ static void batadv_iv_ogm_process(const struct sk_buff *skb, int ogm_offset,
+       batadv_orig_node_put(orig_node);
+ }
+-static void
+-batadv_iv_send_outstanding_forw_packet(struct batadv_forw_packet *forw_packet)
++static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
+ {
++      struct delayed_work *delayed_work;
++      struct batadv_forw_packet *forw_packet;
+       struct batadv_priv *bat_priv;
+       bool dropped = false;
++      delayed_work = to_delayed_work(work);
++      forw_packet = container_of(delayed_work, struct batadv_forw_packet,
++                                 delayed_work);
+       bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface);
+       if (atomic_read(&bat_priv->mesh_state) == BATADV_MESH_DEACTIVATING) {
+@@ -1836,20 +1871,6 @@ batadv_iv_send_outstanding_forw_packet(struct batadv_forw_packet *forw_packet)
+               batadv_forw_packet_free(forw_packet, dropped);
+ }
+-static void batadv_iv_send_outstanding_bat_ogm_packet(struct work_struct *work)
+-{
+-      struct delayed_work *delayed_work;
+-      struct batadv_forw_packet *forw_packet;
+-
+-      delayed_work = to_delayed_work(work);
+-      forw_packet = container_of(delayed_work, struct batadv_forw_packet,
+-                                 delayed_work);
+-
+-      rtnl_lock();
+-      batadv_iv_send_outstanding_forw_packet(forw_packet);
+-      rtnl_unlock();
+-}
+-
+ static int batadv_iv_ogm_receive(struct sk_buff *skb,
+                                struct batadv_hard_iface *if_incoming)
+ {
+diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
+index 36f0962040d16af4f9ed82629ff03ce85c83ed57..c4e0435c952db87c89727633c184320820812cda 100644
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -29,6 +29,7 @@
+ #include <linux/kernel.h>
+ #include <linux/kref.h>
+ #include <linux/list.h>
++#include <linux/mutex.h>
+ #include <linux/netdevice.h>
+ #include <linux/printk.h>
+ #include <linux/rculist.h>
+@@ -933,6 +934,7 @@ batadv_hardif_add_interface(struct net_device *net_dev)
+       INIT_LIST_HEAD(&hard_iface->list);
+       INIT_HLIST_HEAD(&hard_iface->neigh_list);
++      mutex_init(&hard_iface->bat_iv.ogm_buff_mutex);
+       spin_lock_init(&hard_iface->neigh_list_lock);
+       kref_init(&hard_iface->refcount);
+diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
+index 44c423447fe163eb3b9df5ec5cf229bed6b8d65b..85f52dc42e17f7ed550f13048a2e2bd9d372196b 100644
+--- a/net/batman-adv/types.h
++++ b/net/batman-adv/types.h
+@@ -83,14 +83,17 @@ enum batadv_dhcp_recipient {
+  * struct batadv_hard_iface_bat_iv - per hard-interface B.A.T.M.A.N. IV data
+  */
+ struct batadv_hard_iface_bat_iv {
+-      /** @ogm_buff: buffer holding the OGM packet. rtnl protected */
++      /** @ogm_buff: buffer holding the OGM packet */
+       unsigned char *ogm_buff;
+-      /** @ogm_buff_len: length of the OGM packet buffer. rtnl protected */
++      /** @ogm_buff_len: length of the OGM packet buffer */
+       int ogm_buff_len;
+       /** @ogm_seqno: OGM sequence number - used to identify each OGM */
+       atomic_t ogm_seqno;
++
++      /** @ogm_buff_mutex: lock protecting ogm_buff and ogm_buff_len */
++      struct mutex ogm_buff_mutex;
+ };
+ /**
diff --git a/batman-adv/patches/0040-batman-adv-Fix-DAT-candidate-selection-on-little-end.patch b/batman-adv/patches/0040-batman-adv-Fix-DAT-candidate-selection-on-little-end.patch
new file mode 100644 (file)
index 0000000..05b0636
--- /dev/null
@@ -0,0 +1,43 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Thu, 28 Nov 2019 12:43:49 +0100
+Subject: batman-adv: Fix DAT candidate selection on little endian systems
+
+The distributed arp table is using a DHT to store and retrieve MAC address
+information for an IP address. This is done using unicast messages to
+selected peers. The potential peers are looked up using the IP address and
+the VID.
+
+While the IP address is always stored in big endian byte order, it is not
+the case of the VID. It can (depending on the host system) either be big
+endian or little endian. The host must therefore always convert it to big
+endian to ensure that all devices calculate the same peers for the same
+lookup data.
+
+Fixes: 3e26722bc9f2 ("batman-adv: make the Distributed ARP Table vlan aware")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Acked-by: Antonio Quartulli <a@unstable.cc>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/728aea06f38e0e4d70f4f7d43698187f7f7055c5
+
+diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c
+index a60bacf7120be88ba7626cf0a87dd34eef0a2eec..21783805a3afd974cebc7e640249402d637d731a 100644
+--- a/net/batman-adv/distributed-arp-table.c
++++ b/net/batman-adv/distributed-arp-table.c
+@@ -251,6 +251,7 @@ static u32 batadv_hash_dat(const void *data, u32 size)
+       u32 hash = 0;
+       const struct batadv_dat_entry *dat = data;
+       const unsigned char *key;
++      __be16 vid;
+       u32 i;
+       key = (const unsigned char *)&dat->ip;
+@@ -260,7 +261,8 @@ static u32 batadv_hash_dat(const void *data, u32 size)
+               hash ^= (hash >> 6);
+       }
+-      key = (const unsigned char *)&dat->vid;
++      vid = htons(dat->vid);
++      key = (__force const unsigned char *)&vid;
+       for (i = 0; i < sizeof(dat->vid); i++) {
+               hash += key[i];
+               hash += (hash << 10);
diff --git a/batman-adv/patches/0041-batman-adv-Don-t-schedule-OGM-for-disabled-interface.patch b/batman-adv/patches/0041-batman-adv-Don-t-schedule-OGM-for-disabled-interface.patch
new file mode 100644 (file)
index 0000000..a039a22
--- /dev/null
@@ -0,0 +1,37 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sun, 16 Feb 2020 13:02:06 +0100
+Subject: batman-adv: Don't schedule OGM for disabled interface
+
+A transmission scheduling for an interface which is currently dropped by
+batadv_iv_ogm_iface_disable could still be in progress. The B.A.T.M.A.N. V
+is simply cancelling the workqueue item in an synchronous way but this is
+not possible with B.A.T.M.A.N. IV because the OGM submissions are
+intertwined.
+
+Instead it has to stop submitting the OGM when it detect that the buffer
+pointer is set to NULL.
+
+Reported-by: syzbot+a98f2016f40b9cd3818a@syzkaller.appspotmail.com
+Reported-by: syzbot+ac36b6a33c28a491e929@syzkaller.appspotmail.com
+Fixes: c6c8fea29769 ("net: Add batman-adv meshing protocol")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Cc: Hillf Danton <hdanton@sina.com>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/a089c55ca004b396d340baae58abe9a79f32cc0f
+
+diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
+index f5941837c3ad463f276cffdb25f9b6cd87af0e92..0b052ff51bdeb36f7eac9abca927e267533d2930 100644
+--- a/net/batman-adv/bat_iv_ogm.c
++++ b/net/batman-adv/bat_iv_ogm.c
+@@ -970,6 +970,10 @@ static void batadv_iv_ogm_schedule_buff(struct batadv_hard_iface *hard_iface)
+       lockdep_assert_held(&hard_iface->bat_iv.ogm_buff_mutex);
++      /* interface already disabled by batadv_iv_ogm_iface_disable */
++      if (!*ogm_buff)
++              return;
++
+       /* the interface gets activated here to avoid race conditions between
+        * the moment of activating the interface in
+        * hardif_activate_interface() where the originator mac is set and
diff --git a/batman-adv/patches/0042-batman-adv-fix-batadv_nc_random_weight_tq.patch b/batman-adv/patches/0042-batman-adv-fix-batadv_nc_random_weight_tq.patch
new file mode 100644 (file)
index 0000000..d3f356b
--- /dev/null
@@ -0,0 +1,59 @@
+From: George Spelvin <lkml@sdf.org>
+Date: Sun, 8 Mar 2020 09:44:59 -0400
+Subject: batman-adv: fix batadv_nc_random_weight_tq
+
+and change to pseudorandom numbers, as this is a traffic dithering
+operation that doesn't need crypto-grade.
+
+The previous code operated in 4 steps:
+
+1. Generate a random byte 0 <= rand_tq <= 255
+2. Multiply it by BATADV_TQ_MAX_VALUE - tq
+3. Divide by 255 (= BATADV_TQ_MAX_VALUE)
+4. Return BATADV_TQ_MAX_VALUE - rand_tq
+
+This would apperar to scale (BATADV_TQ_MAX_VALUE - tq) by a random
+value between 0/255 and 255/255.
+
+But!  The intermediate value between steps 3 and 4 is stored in a u8
+variable.  So it's truncated, and most of the time, is less than 255, after
+which the division produces 0.  Specifically, if tq is odd, the product is
+always even, and can never be 255.  If tq is even, there's exactly one
+random byte value that will produce a product byte of 255.
+
+Thus, the return value is 255 (511/512 of the time) or 254 (1/512
+of the time).
+
+If we assume that the truncation is a bug, and the code is meant to scale
+the input, a simpler way of looking at it is that it's returning a random
+value between tq and BATADV_TQ_MAX_VALUE, inclusive.
+
+Well, we have an optimized function for doing just that.
+
+Fixes: c3289f3650d3 ("batman-adv: network coding - code and transmit packets if possible")
+Signed-off-by: George Spelvin <lkml@sdf.org>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/db48c60b0edb995450ee846157364bd09bb23762
+
+diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
+index 34caf129a9bf5531360f798be6a7059bad26a50f..7f1be5a287575d51ffd5b4e7ecf540b8fd7de700 100644
+--- a/net/batman-adv/network-coding.c
++++ b/net/batman-adv/network-coding.c
+@@ -1021,15 +1021,8 @@ static struct batadv_nc_path *batadv_nc_get_path(struct batadv_priv *bat_priv,
+  */
+ static u8 batadv_nc_random_weight_tq(u8 tq)
+ {
+-      u8 rand_val, rand_tq;
+-
+-      get_random_bytes(&rand_val, sizeof(rand_val));
+-
+       /* randomize the estimated packet loss (max TQ - estimated TQ) */
+-      rand_tq = rand_val * (BATADV_TQ_MAX_VALUE - tq);
+-
+-      /* normalize the randomized packet loss */
+-      rand_tq /= BATADV_TQ_MAX_VALUE;
++      u8 rand_tq = prandom_u32_max(BATADV_TQ_MAX_VALUE + 1 - tq);
+       /* convert to (randomized) estimated tq again */
+       return BATADV_TQ_MAX_VALUE - rand_tq;
diff --git a/batman-adv/patches/0043-batman-adv-Fix-refcnt-leak-in-batadv_show_throughput.patch b/batman-adv/patches/0043-batman-adv-Fix-refcnt-leak-in-batadv_show_throughput.patch
new file mode 100644 (file)
index 0000000..f6c45df
--- /dev/null
@@ -0,0 +1,38 @@
+From: Xiyu Yang <xiyuyang19@fudan.edu.cn>
+Date: Wed, 15 Apr 2020 16:31:50 +0800
+Subject: batman-adv: Fix refcnt leak in batadv_show_throughput_override
+
+batadv_show_throughput_override() invokes batadv_hardif_get_by_netdev(),
+which gets a batadv_hard_iface object from net_dev with increased refcnt
+and its reference is assigned to a local pointer 'hard_iface'.
+
+When batadv_show_throughput_override() returns, "hard_iface" becomes
+invalid, so the refcount should be decreased to keep refcount balanced.
+
+The issue happens in the normal path of
+batadv_show_throughput_override(), which forgets to decrease the refcnt
+increased by batadv_hardif_get_by_netdev() before the function returns,
+causing a refcnt leak.
+
+Fix this issue by calling batadv_hardif_put() before the
+batadv_show_throughput_override() returns in the normal path.
+
+Fixes: c513176e4b7a ("batman-adv: add throughput override attribute to hard_ifaces")
+Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
+Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/f301bfed59b146a63471d0f147b767d7cafede6f
+
+diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
+index 09427fc6494a157554d8b19f3481a878a9f97bba..7f7de0b16aa7ab70986735fbd9b42fd02de8a924 100644
+--- a/net/batman-adv/sysfs.c
++++ b/net/batman-adv/sysfs.c
+@@ -1126,6 +1126,7 @@ static ssize_t batadv_show_throughput_override(struct kobject *kobj,
+       tp_override = atomic_read(&hard_iface->bat_v.throughput_override);
++      batadv_hardif_put(hard_iface);
+       return sprintf(buff, "%u.%u MBit\n", tp_override / 10,
+                      tp_override % 10);
+ }
diff --git a/batman-adv/patches/0044-batman-adv-Fix-refcnt-leak-in-batadv_store_throughpu.patch b/batman-adv/patches/0044-batman-adv-Fix-refcnt-leak-in-batadv_store_throughpu.patch
new file mode 100644 (file)
index 0000000..bf93520
--- /dev/null
@@ -0,0 +1,39 @@
+From: Xiyu Yang <xiyuyang19@fudan.edu.cn>
+Date: Wed, 15 Apr 2020 16:35:21 +0800
+Subject: batman-adv: Fix refcnt leak in batadv_store_throughput_override
+
+batadv_show_throughput_override() invokes batadv_hardif_get_by_netdev(),
+which gets a batadv_hard_iface object from net_dev with increased refcnt
+and its reference is assigned to a local pointer 'hard_iface'.
+
+When batadv_store_throughput_override() returns, "hard_iface" becomes
+invalid, so the refcount should be decreased to keep refcount balanced.
+
+The issue happens in one error path of
+batadv_store_throughput_override(). When batadv_parse_throughput()
+returns NULL, the refcnt increased by batadv_hardif_get_by_netdev() is
+not decreased, causing a refcnt leak.
+
+Fix this issue by jumping to "out" label when batadv_parse_throughput()
+returns NULL.
+
+Fixes: c513176e4b7a ("batman-adv: add throughput override attribute to hard_ifaces")
+Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
+Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/b69cd8bdbfd6fa7e61878c2fa9e6637406f40dd9
+
+diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
+index 7f7de0b16aa7ab70986735fbd9b42fd02de8a924..976b038e53bf934332a39bad8a5509ca1aac0add 100644
+--- a/net/batman-adv/sysfs.c
++++ b/net/batman-adv/sysfs.c
+@@ -1093,7 +1093,7 @@ static ssize_t batadv_store_throughput_override(struct kobject *kobj,
+       ret = batadv_parse_throughput(net_dev, buff, "throughput_override",
+                                     &tp_override);
+       if (!ret)
+-              return count;
++              goto out;
+       old_tp_override = atomic_read(&hard_iface->bat_v.throughput_override);
+       if (old_tp_override == tp_override)
diff --git a/batman-adv/patches/0045-batman-adv-Fix-refcnt-leak-in-batadv_v_ogm_process.patch b/batman-adv/patches/0045-batman-adv-Fix-refcnt-leak-in-batadv_v_ogm_process.patch
new file mode 100644 (file)
index 0000000..cf16c46
--- /dev/null
@@ -0,0 +1,39 @@
+From: Xiyu Yang <xiyuyang19@fudan.edu.cn>
+Date: Mon, 20 Apr 2020 13:37:20 +0800
+Subject: batman-adv: Fix refcnt leak in batadv_v_ogm_process
+
+batadv_v_ogm_process() invokes batadv_hardif_neigh_get(), which returns
+a reference of the neighbor object to "hardif_neigh" with increased
+refcount.
+
+When batadv_v_ogm_process() returns, "hardif_neigh" becomes invalid, so
+the refcount should be decreased to keep refcount balanced.
+
+The reference counting issue happens in one exception handling paths of
+batadv_v_ogm_process(). When batadv_v_ogm_orig_get() fails to get the
+orig node and returns NULL, the refcnt increased by
+batadv_hardif_neigh_get() is not decreased, causing a refcnt leak.
+
+Fix this issue by jumping to "out" label when batadv_v_ogm_orig_get()
+fails to get the orig node.
+
+Fixes: 667996ebeab4 ("batman-adv: OGMv2 - implement originators logic")
+Signed-off-by: Xiyu Yang <xiyuyang19@fudan.edu.cn>
+Signed-off-by: Xin Tan <tanxin.ctf@gmail.com>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/4515f5e6a4ccbe1c563b05f2d487eb9eef3c9740
+
+diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
+index bf9ea404abe7cbe1dd2113881856cd35b718b7d1..0458de53cb64b2da51de492ffa27f33068351cc8 100644
+--- a/net/batman-adv/bat_v_ogm.c
++++ b/net/batman-adv/bat_v_ogm.c
+@@ -735,7 +735,7 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset,
+       orig_node = batadv_v_ogm_orig_get(bat_priv, ogm_packet->orig);
+       if (!orig_node)
+-              return;
++              goto out;
+       neigh_node = batadv_neigh_node_get_or_create(orig_node, if_incoming,
+                                                    ethhdr->h_source);
diff --git a/batman-adv/patches/0046-batman-adv-Avoid-uninitialized-chaddr-when-handling-.patch b/batman-adv/patches/0046-batman-adv-Avoid-uninitialized-chaddr-when-handling-.patch
new file mode 100644 (file)
index 0000000..43a4150
--- /dev/null
@@ -0,0 +1,42 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Wed, 22 Jul 2020 20:49:23 +0200
+Subject: batman-adv: Avoid uninitialized chaddr when handling DHCP
+
+The gateway client code can try to optimize the delivery of DHCP packets to
+avoid broadcasting them through the whole mesh. But also transmissions to
+the client can be optimized by looking up the destination via the chaddr of
+the DHCP packet.
+
+But the chaddr is currently only done when chaddr is fully inside the
+non-paged area of the skbuff. Otherwise it will not be initialized and the
+unoptimized path should have been taken.
+
+But the implementation didn't handle this correctly. It didn't retrieve the
+correct chaddr but still tried to perform the TT lookup with this
+uninitialized memory.
+
+Reported-by: syzbot+ab16e463b903f5a37036@syzkaller.appspotmail.com
+Fixes: 2d5b555644b2 ("batman-adv: send every DHCP packet as bat-unicast")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Acked-by: Antonio Quartulli <a@unstable.cc>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/fcdf008ffd749246632d1f9423163af5dc3f8c7f
+
+diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
+index 140c61a3f1ecfec4fe23c5ddca19e18e2e86fd56..0c59fefc137196899f97e0fa7882cf55ceebe34c 100644
+--- a/net/batman-adv/gateway_client.c
++++ b/net/batman-adv/gateway_client.c
+@@ -714,8 +714,10 @@ batadv_gw_dhcp_recipient_get(struct sk_buff *skb, unsigned int *header_len,
+       chaddr_offset = *header_len + BATADV_DHCP_CHADDR_OFFSET;
+       /* store the client address if the message is going to a client */
+-      if (ret == BATADV_DHCP_TO_CLIENT &&
+-          pskb_may_pull(skb, chaddr_offset + ETH_ALEN)) {
++      if (ret == BATADV_DHCP_TO_CLIENT) {
++              if (!pskb_may_pull(skb, chaddr_offset + ETH_ALEN))
++                      return BATADV_DHCP_NO;
++
+               /* check if the DHCP packet carries an Ethernet DHCP */
+               p = skb->data + *header_len + BATADV_DHCP_HTYPE_OFFSET;
+               if (*p != BATADV_DHCP_HTYPE_ETHERNET)
diff --git a/batman-adv/patches/0047-batman-adv-Fix-own-OGM-check-in-aggregated-OGMs.patch b/batman-adv/patches/0047-batman-adv-Fix-own-OGM-check-in-aggregated-OGMs.patch
new file mode 100644 (file)
index 0000000..1b6f152
--- /dev/null
@@ -0,0 +1,59 @@
+From: Linus Lüssing <linus.luessing@c0d3.blue>
+Date: Fri, 31 Jul 2020 00:22:55 +0200
+Subject: batman-adv: Fix own OGM check in aggregated OGMs
+
+The own OGM check is currently misplaced and can lead to the following
+issues:
+
+For one thing we might receive an aggregated OGM from a neighbor node
+which has our own OGM in the first place. We would then not only skip
+our own OGM but erroneously also any other, following OGM in the
+aggregate.
+
+For another, we might receive an OGM aggregate which has our own OGM in
+a place other then the first one. Then we would wrongly not skip this
+OGM, leading to populating the orginator and gateway table with ourself.
+
+The latter seems to not only be a cosmetic issue, but there were reports
+that this causes issues with various subsystems of batman-adv, too. For
+instance there were reports about issues with DAT and either disabling
+DAT or aggregation seemed to solve it.
+
+Fixing these issues by applying the own OGM check not on the first OGM
+in an aggregate but for each OGM in an aggregate instead.
+
+Fixes: 667996ebeab ("batman-adv: OGMv2 - implement originators logic")
+Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d41cc7cb62c184b2fb8ab97fda45815918200001
+
+diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
+index 0458de53cb64b2da51de492ffa27f33068351cc8..04a620fd13014463ed0c7c047f3a61a05d862e39 100644
+--- a/net/batman-adv/bat_v_ogm.c
++++ b/net/batman-adv/bat_v_ogm.c
+@@ -716,6 +716,12 @@ static void batadv_v_ogm_process(const struct sk_buff *skb, int ogm_offset,
+                  ntohl(ogm_packet->seqno), ogm_throughput, ogm_packet->ttl,
+                  ogm_packet->version, ntohs(ogm_packet->tvlv_len));
++      if (batadv_is_my_mac(bat_priv, ogm_packet->orig)) {
++              batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
++                         "Drop packet: originator packet from ourself\n");
++              return;
++      }
++
+       /* If the throughput metric is 0, immediately drop the packet. No need
+        * to create orig_node / neigh_node for an unusable route.
+        */
+@@ -843,11 +849,6 @@ int batadv_v_ogm_packet_recv(struct sk_buff *skb,
+       if (batadv_is_my_mac(bat_priv, ethhdr->h_source))
+               goto free_skb;
+-      ogm_packet = (struct batadv_ogm2_packet *)skb->data;
+-
+-      if (batadv_is_my_mac(bat_priv, ogm_packet->orig))
+-              goto free_skb;
+-
+       batadv_inc_counter(bat_priv, BATADV_CNT_MGMT_RX);
+       batadv_add_counter(bat_priv, BATADV_CNT_MGMT_RX_BYTES,
+                          skb->len + ETH_HLEN);
diff --git a/batman-adv/patches/0048-batman-adv-bla-use-netif_rx_ni-when-not-in-interrupt.patch b/batman-adv/patches/0048-batman-adv-bla-use-netif_rx_ni-when-not-in-interrupt.patch
new file mode 100644 (file)
index 0000000..2705afa
--- /dev/null
@@ -0,0 +1,31 @@
+From: Jussi Kivilinna <jussi.kivilinna@haltian.com>
+Date: Tue, 18 Aug 2020 17:46:10 +0300
+Subject: batman-adv: bla: use netif_rx_ni when not in interrupt context
+
+batadv_bla_send_claim() gets called from worker thread context through
+batadv_bla_periodic_work(), thus netif_rx_ni needs to be used in that
+case. This fixes "NOHZ: local_softirq_pending 08" log messages seen
+when batman-adv is enabled.
+
+Fixes: a9ce0dc43e2c ("batman-adv: add basic bridge loop avoidance code")
+Signed-off-by: Jussi Kivilinna <jussi.kivilinna@haltian.com>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/3747f81a1380b65740fc52fc71c7a3af4c6e49de
+
+diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
+index 0842080a71f4ac89b3fbebc4b95c6c27d1cc4254..ed8259ff0dc7ba129825a369a757b37cc62ce829 100644
+--- a/net/batman-adv/bridge_loop_avoidance.c
++++ b/net/batman-adv/bridge_loop_avoidance.c
+@@ -450,7 +450,10 @@ static void batadv_bla_send_claim(struct batadv_priv *bat_priv, u8 *mac,
+       batadv_add_counter(bat_priv, BATADV_CNT_RX_BYTES,
+                          skb->len + ETH_HLEN);
+-      netif_rx(skb);
++      if (in_interrupt())
++              netif_rx(skb);
++      else
++              netif_rx_ni(skb);
+ out:
+       if (primary_if)
+               batadv_hardif_put(primary_if);
diff --git a/batman-adv/patches/0049-batman-adv-bla-fix-type-misuse-for-backbone_gw-hash-.patch b/batman-adv/patches/0049-batman-adv-bla-fix-type-misuse-for-backbone_gw-hash-.patch
new file mode 100644 (file)
index 0000000..9a98294
--- /dev/null
@@ -0,0 +1,41 @@
+From: Linus Lüssing <ll@simonwunderlich.de>
+Date: Thu, 27 Aug 2020 17:34:48 +0200
+Subject: batman-adv: bla: fix type misuse for backbone_gw hash indexing
+
+It seems that due to a copy & paste error the void pointer
+in batadv_choose_backbone_gw() is cast to the wrong type.
+
+Fixing this by using "struct batadv_bla_backbone_gw" instead of "struct
+batadv_bla_claim" which better matches the caller's side.
+
+For now it seems that we were lucky because the two structs both have
+their orig/vid and addr/vid in the beginning. However I stumbled over
+this issue when I was trying to add some debug variables in front of
+"orig" in batadv_backbone_gw, which caused hash lookups to fail.
+
+Fixes: 7e15c9305ce0 ("batman-adv: don't rely on positions in struct for hashing")
+Signed-off-by: Linus Lüssing <ll@simonwunderlich.de>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/398a706cd46c1fc085aef56ae8ed11f76e182bd1
+
+diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
+index ed8259ff0dc7ba129825a369a757b37cc62ce829..9dc574f5659e2bce97bd7e0f3793f8c1edf1fbd5 100644
+--- a/net/batman-adv/bridge_loop_avoidance.c
++++ b/net/batman-adv/bridge_loop_avoidance.c
+@@ -96,11 +96,12 @@ static inline u32 batadv_choose_claim(const void *data, u32 size)
+  */
+ static inline u32 batadv_choose_backbone_gw(const void *data, u32 size)
+ {
+-      const struct batadv_bla_claim *claim = (struct batadv_bla_claim *)data;
++      const struct batadv_bla_backbone_gw *gw;
+       u32 hash = 0;
+-      hash = jhash(&claim->addr, sizeof(claim->addr), hash);
+-      hash = jhash(&claim->vid, sizeof(claim->vid), hash);
++      gw = (struct batadv_bla_backbone_gw *)data;
++      hash = jhash(&gw->orig, sizeof(gw->orig), hash);
++      hash = jhash(&gw->vid, sizeof(gw->vid), hash);
+       return hash % size;
+ }
diff --git a/batman-adv/patches/0050-batman-adv-mcast-TT-fix-wrongly-dropped-or-rerouted-.patch b/batman-adv/patches/0050-batman-adv-mcast-TT-fix-wrongly-dropped-or-rerouted-.patch
new file mode 100644 (file)
index 0000000..0e121df
--- /dev/null
@@ -0,0 +1,45 @@
+From: Linus Lüssing <linus.luessing@c0d3.blue>
+Date: Fri, 4 Sep 2020 20:28:00 +0200
+Subject: batman-adv: mcast/TT: fix wrongly dropped or rerouted packets
+
+The unicast packet rerouting code makes several assumptions. For
+instance it assumes that there is always exactly one destination in the
+TT. This breaks for multicast frames in a unicast packets in several ways:
+
+For one thing if there is actually no TT entry and the destination node
+was selected due to the multicast tvlv flags it announced. Then an
+intermediate node will wrongly drop the packet.
+
+For another thing if there is a TT entry but the TTVN of this entry is
+newer than the originally addressed destination node: Then the
+intermediate node will wrongly redirect the packet, leading to
+duplicated multicast packets at a multicast listener and missing
+packets at other multicast listeners or multicast routers.
+
+Fixing this by not applying the unicast packet rerouting to batman-adv
+unicast packets with a multicast payload. We are not able to detect a
+roaming multicast listener at the moment and will just continue to send
+the multicast frame to both the new and old destination for a while in
+case of such a roaming multicast listener.
+
+Fixes: cea194d90b11 ("batman-adv: improved client announcement mechanism")
+Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/22e740c5e6c9342e0f5028beb3d14b84a018d113
+
+diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c
+index cc3ed93a6d513dffd4711cac50545d65ef7d640e..98af41e3810dcdf96edad8dff89d4d2b624c5d7f 100644
+--- a/net/batman-adv/routing.c
++++ b/net/batman-adv/routing.c
+@@ -838,6 +838,10 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
+       vid = batadv_get_vid(skb, hdr_len);
+       ethhdr = (struct ethhdr *)(skb->data + hdr_len);
++      /* do not reroute multicast frames in a unicast header */
++      if (is_multicast_ether_addr(ethhdr->h_dest))
++              return true;
++
+       /* check if the destination client was served by this node and it is now
+        * roaming. In this case, it means that the node has got a ROAM_ADV
+        * message and that it knows the new destination in the mesh to re-route
diff --git a/batman-adv/patches/0051-batman-adv-Add-missing-include-for-in_interrupt.patch b/batman-adv/patches/0051-batman-adv-Add-missing-include-for-in_interrupt.patch
new file mode 100644 (file)
index 0000000..abadd1b
--- /dev/null
@@ -0,0 +1,26 @@
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 14 Sep 2020 13:58:16 +0200
+Subject: batman-adv: Add missing include for in_interrupt()
+
+The fix for receiving (internally generated) bla packets outside the
+interrupt context introduced the usage of in_interrupt(). But this
+functionality is only defined in linux/preempt.h which was not included
+with the same patch.
+
+Fixes: 3747f81a1380 ("batman-adv: bla: use netif_rx_ni when not in interrupt context")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/6ea99cd9c82b2d1bc4a313fe9006bcf5d956380e
+
+diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
+index 9dc574f5659e2bce97bd7e0f3793f8c1edf1fbd5..26f590ba31d49a85143f67f1c002a25dc007b594 100644
+--- a/net/batman-adv/bridge_loop_avoidance.c
++++ b/net/batman-adv/bridge_loop_avoidance.c
+@@ -37,6 +37,7 @@
+ #include <linux/lockdep.h>
+ #include <linux/netdevice.h>
+ #include <linux/netlink.h>
++#include <linux/preempt.h>
+ #include <linux/rculist.h>
+ #include <linux/rcupdate.h>
+ #include <linux/seq_file.h>
diff --git a/batman-adv/patches/0052-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch b/batman-adv/patches/0052-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch
new file mode 100644 (file)
index 0000000..07e7d27
--- /dev/null
@@ -0,0 +1,144 @@
+From: Linus Lüssing <linus.luessing@c0d3.blue>
+Date: Tue, 15 Sep 2020 09:54:08 +0200
+Subject: batman-adv: mcast: fix duplicate mcast packets in BLA backbone from LAN
+
+Scenario:
+* Multicast frame send from a BLA backbone (multiple nodes with
+  their bat0 bridged together, with BLA enabled)
+
+Issue:
+* BLA backbone nodes receive the frame multiple times on bat0
+
+For multicast frames received via batman-adv broadcast packets the
+originator of the broadcast packet is checked before decapsulating and
+forwarding the frame to bat0 (batadv_bla_is_backbone_gw()->
+batadv_recv_bcast_packet()). If it came from a node which shares the
+same BLA backbone with us then it is not forwarded to bat0 to avoid a
+loop.
+
+When sending a multicast frame in a non-4-address batman-adv unicast
+packet we are currently missing this check - and cannot do so because
+the batman-adv unicast packet has no originator address field.
+
+However, we can simply fix this on the sender side by only sending the
+multicast frame via unicasts to interested nodes which do not share the
+same BLA backbone with us. This also nicely avoids some unnecessary
+transmissions on mesh side.
+
+Note that no infinite loop was observed, probably because of dropping
+via batadv_interface_tx()->batadv_bla_tx(). However the duplicates still
+utterly confuse switches/bridges, ICMPv6 duplicate address detection and
+neighbor discovery and therefore leads to long delays before being able
+to establish TCP connections, for instance. And it also leads to the Linux
+bridge printing messages like:
+"br-lan: received packet on eth1 with own address as source address ..."
+
+Fixes: 405cc1e5a81e ("batman-adv: Modified forwarding behaviour for multicast packets")
+Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Acked-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: backport, https://git.open-mesh.org/batman-adv.git/commit/3c39a2455a5be02ecceeaf1a15976bddd611392e
+
+diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c
+index 39640d3d6fbdf8244344db6e79f2d769eb0972d9..764c304ffa5f6dc976050fa6b6f6e0891981c4f4 100644
+--- a/net/batman-adv/multicast.c
++++ b/net/batman-adv/multicast.c
+@@ -62,10 +62,12 @@
+ #include <uapi/linux/batadv_packet.h>
+ #include <uapi/linux/batman_adv.h>
++#include "bridge_loop_avoidance.h"
+ #include "hard-interface.h"
+ #include "hash.h"
+ #include "log.h"
+ #include "netlink.h"
++#include "send.h"
+ #include "soft-interface.h"
+ #include "translation-table.h"
+ #include "tvlv.h"
+@@ -1027,6 +1029,35 @@ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
+       }
+ }
++/**
++ * batadv_mcast_forw_send_orig() - send a multicast packet to an originator
++ * @bat_priv: the bat priv with all the soft interface information
++ * @skb: the multicast packet to send
++ * @vid: the vlan identifier
++ * @orig_node: the originator to send the packet to
++ *
++ * Return: NET_XMIT_DROP in case of error or NET_XMIT_SUCCESS otherwise.
++ */
++int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
++                              struct sk_buff *skb,
++                              unsigned short vid,
++                              struct batadv_orig_node *orig_node)
++{
++      /* Avoid sending multicast-in-unicast packets to other BLA
++       * gateways - they already got the frame from the LAN side
++       * we share with them.
++       * TODO: Refactor to take BLA into account earlier, to avoid
++       * reducing the mcast_fanout count.
++       */
++      if (batadv_bla_is_backbone_gw_orig(bat_priv, orig_node->orig, vid)) {
++              dev_kfree_skb(skb);
++              return NET_XMIT_SUCCESS;
++      }
++
++      return batadv_send_skb_unicast(bat_priv, skb, BATADV_UNICAST, 0,
++                                     orig_node, vid);
++}
++
+ /**
+  * batadv_mcast_want_unsnoop_update() - update unsnoop counter and list
+  * @bat_priv: the bat priv with all the soft interface information
+diff --git a/net/batman-adv/multicast.h b/net/batman-adv/multicast.h
+index 3b04ab13f0eb1044454315c04e75a22ce4351afd..6f9f3813fc59a8e8798b71297c8d8f9ef50b5e72 100644
+--- a/net/batman-adv/multicast.h
++++ b/net/batman-adv/multicast.h
+@@ -51,6 +51,11 @@ enum batadv_forw_mode
+ batadv_mcast_forw_mode(struct batadv_priv *bat_priv, struct sk_buff *skb,
+                      struct batadv_orig_node **mcast_single_orig);
++int batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
++                              struct sk_buff *skb,
++                              unsigned short vid,
++                              struct batadv_orig_node *orig_node);
++
+ void batadv_mcast_init(struct batadv_priv *bat_priv);
+ int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset);
+@@ -78,6 +83,16 @@ static inline int batadv_mcast_init(struct batadv_priv *bat_priv)
+       return 0;
+ }
++static inline int
++batadv_mcast_forw_send_orig(struct batadv_priv *bat_priv,
++                          struct sk_buff *skb,
++                          unsigned short vid,
++                          struct batadv_orig_node *orig_node)
++{
++      kfree_skb(skb);
++      return NET_XMIT_DROP;
++}
++
+ static inline int
+ batadv_mcast_mesh_info_put(struct sk_buff *msg, struct batadv_priv *bat_priv)
+ {
+diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
+index 97e28907a0acbb3d64d8ceebf7b1df13dc396300..267f6e6c802f1a7d3eb41a0f3aa2142ca3b21414 100644
+--- a/net/batman-adv/soft-interface.c
++++ b/net/batman-adv/soft-interface.c
+@@ -367,9 +367,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
+                               goto dropped;
+                       ret = batadv_send_skb_via_gw(bat_priv, skb, vid);
+               } else if (mcast_single_orig) {
+-                      ret = batadv_send_skb_unicast(bat_priv, skb,
+-                                                    BATADV_UNICAST, 0,
+-                                                    mcast_single_orig, vid);
++                      ret = batadv_mcast_forw_send_orig(bat_priv, skb, vid,
++                                                        mcast_single_orig);
+               } else {
+                       if (batadv_dat_snoop_outgoing_arp_request(bat_priv,
+                                                                 skb))
diff --git a/batman-adv/patches/0053-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch b/batman-adv/patches/0053-batman-adv-mcast-fix-duplicate-mcast-packets-in-BLA-.patch
new file mode 100644 (file)
index 0000000..284e2da
--- /dev/null
@@ -0,0 +1,156 @@
+From: Linus Lüssing <linus.luessing@c0d3.blue>
+Date: Tue, 15 Sep 2020 09:54:09 +0200
+Subject: batman-adv: mcast: fix duplicate mcast packets in BLA backbone from mesh
+
+Scenario:
+* Multicast frame send from mesh to a BLA backbone (multiple nodes
+  with their bat0 bridged together, with BLA enabled)
+
+Issue:
+* BLA backbone nodes receive the frame multiple times on bat0,
+  once from mesh->bat0 and once from each backbone_gw from LAN
+
+For unicast, a node will send only to the best backbone gateway
+according to the TQ. However for multicast we currently cannot determine
+if multiple destination nodes share the same backbone if they don't share
+the same backbone with us. So we need to keep sending the unicasts to
+all backbone gateways and let the backbone gateways decide which one
+will forward the frame. We can use the CLAIM mechanism to make this
+decision.
+
+One catch: The batman-adv gateway feature for DHCP packets potentially
+sends multicast packets in the same batman-adv unicast header as the
+multicast optimizations code. And we are not allowed to drop those even
+if we did not claim the source address of the sender, as for such
+packets there is only this one multicast-in-unicast packet.
+
+How can we distinguish the two cases?
+
+The gateway feature uses a batman-adv unicast 4 address header. While
+the multicast-to-unicasts feature uses a simple, 3 address batman-adv
+unicast header. So let's use this to distinguish.
+
+Fixes: e32470167379 ("batman-adv: check incoming packet type for bla")
+Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Acked-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/d7665cf8a824c41c61c6e2110ab63d37eb7a8ef7
+
+diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
+index 26f590ba31d49a85143f67f1c002a25dc007b594..4dc67a0d081c06507aba87f7bec03488817791b2 100644
+--- a/net/batman-adv/bridge_loop_avoidance.c
++++ b/net/batman-adv/bridge_loop_avoidance.c
+@@ -1827,7 +1827,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
+  * @bat_priv: the bat priv with all the soft interface information
+  * @skb: the frame to be checked
+  * @vid: the VLAN ID of the frame
+- * @is_bcast: the packet came in a broadcast packet type.
++ * @packet_type: the batman packet type this frame came in
+  *
+  * batadv_bla_rx avoidance checks if:
+  *  * we have to race for a claim
+@@ -1839,7 +1839,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
+  * further process the skb.
+  */
+ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
+-                 unsigned short vid, bool is_bcast)
++                 unsigned short vid, int packet_type)
+ {
+       struct batadv_bla_backbone_gw *backbone_gw;
+       struct ethhdr *ethhdr;
+@@ -1861,9 +1861,24 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
+               goto handled;
+       if (unlikely(atomic_read(&bat_priv->bla.num_requests)))
+-              /* don't allow broadcasts while requests are in flight */
+-              if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast)
+-                      goto handled;
++              /* don't allow multicast packets while requests are in flight */
++              if (is_multicast_ether_addr(ethhdr->h_dest))
++                      /* Both broadcast flooding or multicast-via-unicasts
++                       * delivery might send to multiple backbone gateways
++                       * sharing the same LAN and therefore need to coordinate
++                       * which backbone gateway forwards into the LAN,
++                       * by claiming the payload source address.
++                       *
++                       * Broadcast flooding and multicast-via-unicasts
++                       * delivery use the following two batman packet types.
++                       * Note: explicitly exclude BATADV_UNICAST_4ADDR,
++                       * as the DHCP gateway feature will send explicitly
++                       * to only one BLA gateway, so the claiming process
++                       * should be avoided there.
++                       */
++                      if (packet_type == BATADV_BCAST ||
++                          packet_type == BATADV_UNICAST)
++                              goto handled;
+       ether_addr_copy(search_claim.addr, ethhdr->h_source);
+       search_claim.vid = vid;
+@@ -1898,13 +1913,14 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
+               goto allow;
+       }
+-      /* if it is a broadcast ... */
+-      if (is_multicast_ether_addr(ethhdr->h_dest) && is_bcast) {
++      /* if it is a multicast ... */
++      if (is_multicast_ether_addr(ethhdr->h_dest) &&
++          (packet_type == BATADV_BCAST || packet_type == BATADV_UNICAST)) {
+               /* ... drop it. the responsible gateway is in charge.
+                *
+-               * We need to check is_bcast because with the gateway
++               * We need to check packet type because with the gateway
+                * feature, broadcasts (like DHCP requests) may be sent
+-               * using a unicast packet type.
++               * using a unicast 4 address packet type. See comment above.
+                */
+               goto handled;
+       } else {
+diff --git a/net/batman-adv/bridge_loop_avoidance.h b/net/batman-adv/bridge_loop_avoidance.h
+index 71f95a3e4d3f335890408685432f18e5d7411a76..af28fdb01467ce290c2a00d0741f01a6e4f347ee 100644
+--- a/net/batman-adv/bridge_loop_avoidance.h
++++ b/net/batman-adv/bridge_loop_avoidance.h
+@@ -48,7 +48,7 @@ static inline bool batadv_bla_is_loopdetect_mac(const uint8_t *mac)
+ #ifdef CONFIG_BATMAN_ADV_BLA
+ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
+-                 unsigned short vid, bool is_bcast);
++                 unsigned short vid, int packet_type);
+ bool batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
+                  unsigned short vid);
+ bool batadv_bla_is_backbone_gw(struct sk_buff *skb,
+@@ -79,7 +79,7 @@ bool batadv_bla_check_claim(struct batadv_priv *bat_priv, u8 *addr,
+ static inline bool batadv_bla_rx(struct batadv_priv *bat_priv,
+                                struct sk_buff *skb, unsigned short vid,
+-                               bool is_bcast)
++                               int packet_type)
+ {
+       return false;
+ }
+diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
+index 267f6e6c802f1a7d3eb41a0f3aa2142ca3b21414..82582abd92485b68254789fb6e2108ae5e547dd6 100644
+--- a/net/batman-adv/soft-interface.c
++++ b/net/batman-adv/soft-interface.c
+@@ -425,10 +425,10 @@ void batadv_interface_rx(struct net_device *soft_iface,
+       struct vlan_ethhdr *vhdr;
+       struct ethhdr *ethhdr;
+       unsigned short vid;
+-      bool is_bcast;
++      int packet_type;
+       batadv_bcast_packet = (struct batadv_bcast_packet *)skb->data;
+-      is_bcast = (batadv_bcast_packet->packet_type == BATADV_BCAST);
++      packet_type = batadv_bcast_packet->packet_type;
+       skb_pull_rcsum(skb, hdr_size);
+       skb_reset_mac_header(skb);
+@@ -471,7 +471,7 @@ void batadv_interface_rx(struct net_device *soft_iface,
+       /* Let the bridge loop avoidance check the packet. If will
+        * not handle it, we can safely push it up.
+        */
+-      if (batadv_bla_rx(bat_priv, skb, vid, is_bcast))
++      if (batadv_bla_rx(bat_priv, skb, vid, packet_type))
+               goto out;
+       if (orig_node)
diff --git a/batman-adv/patches/0054-batman-adv-mcast-fix-duplicate-mcast-packets-from-BL.patch b/batman-adv/patches/0054-batman-adv-mcast-fix-duplicate-mcast-packets-from-BL.patch
new file mode 100644 (file)
index 0000000..598150d
--- /dev/null
@@ -0,0 +1,190 @@
+From: Linus Lüssing <linus.luessing@c0d3.blue>
+Date: Tue, 15 Sep 2020 09:54:10 +0200
+Subject: batman-adv: mcast: fix duplicate mcast packets from BLA backbone to mesh
+
+Scenario:
+* Multicast frame send from BLA backbone gateways (multiple nodes
+  with their bat0 bridged together, with BLA enabled) sharing the same
+  LAN to nodes in the mesh
+
+Issue:
+* Nodes receive the frame multiple times on bat0 from the mesh,
+  once from each foreign BLA backbone gateway which shares the same LAN
+  with another
+
+For multicast frames via batman-adv broadcast packets coming from the
+same BLA backbone but from different backbone gateways duplicates are
+currently detected via a CRC history of previously received packets.
+
+However this CRC so far was not performed for multicast frames received
+via batman-adv unicast packets. Fixing this by appyling the same check
+for such packets, too.
+
+Room for improvements in the future: Ideally we would introduce the
+possibility to not only claim a client, but a complete originator, too.
+This would allow us to only send a multicast-in-unicast packet from a BLA
+backbone gateway claiming the node and by that avoid potential redundant
+transmissions in the first place.
+
+Fixes: e5cf86d30a9b ("batman-adv: add broadcast duplicate check")
+Signed-off-by: Linus Lüssing <linus.luessing@c0d3.blue>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+
+Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/c5cb6a670cc3070d9d5c5562f95fa75faac767ba
+
+diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
+index 4dc67a0d081c06507aba87f7bec03488817791b2..4996bd7b8256557bddaf8ebe87cc606def588adf 100644
+--- a/net/batman-adv/bridge_loop_avoidance.c
++++ b/net/batman-adv/bridge_loop_avoidance.c
+@@ -1594,13 +1594,16 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
+ }
+ /**
+- * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
++ * batadv_bla_check_duplist() - Check if a frame is in the broadcast dup.
+  * @bat_priv: the bat priv with all the soft interface information
+- * @skb: contains the bcast_packet to be checked
++ * @skb: contains the multicast packet to be checked
++ * @payload_ptr: pointer to position inside the head buffer of the skb
++ *  marking the start of the data to be CRC'ed
++ * @orig: originator mac address, NULL if unknown
+  *
+- * check if it is on our broadcast list. Another gateway might
+- * have sent the same packet because it is connected to the same backbone,
+- * so we have to remove this duplicate.
++ * Check if it is on our broadcast list. Another gateway might have sent the
++ * same packet because it is connected to the same backbone, so we have to
++ * remove this duplicate.
+  *
+  * This is performed by checking the CRC, which will tell us
+  * with a good chance that it is the same packet. If it is furthermore
+@@ -1609,19 +1612,17 @@ int batadv_bla_init(struct batadv_priv *bat_priv)
+  *
+  * Return: true if a packet is in the duplicate list, false otherwise.
+  */
+-bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
+-                                  struct sk_buff *skb)
++static bool batadv_bla_check_duplist(struct batadv_priv *bat_priv,
++                                   struct sk_buff *skb, u8 *payload_ptr,
++                                   const u8 *orig)
+ {
+-      int i, curr;
+-      __be32 crc;
+-      struct batadv_bcast_packet *bcast_packet;
+       struct batadv_bcast_duplist_entry *entry;
+       bool ret = false;
+-
+-      bcast_packet = (struct batadv_bcast_packet *)skb->data;
++      int i, curr;
++      __be32 crc;
+       /* calculate the crc ... */
+-      crc = batadv_skb_crc32(skb, (u8 *)(bcast_packet + 1));
++      crc = batadv_skb_crc32(skb, payload_ptr);
+       spin_lock_bh(&bat_priv->bla.bcast_duplist_lock);
+@@ -1640,8 +1641,21 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
+               if (entry->crc != crc)
+                       continue;
+-              if (batadv_compare_eth(entry->orig, bcast_packet->orig))
+-                      continue;
++              /* are the originators both known and not anonymous? */
++              if (orig && !is_zero_ether_addr(orig) &&
++                  !is_zero_ether_addr(entry->orig)) {
++                      /* If known, check if the new frame came from
++                       * the same originator:
++                       * We are safe to take identical frames from the
++                       * same orig, if known, as multiplications in
++                       * the mesh are detected via the (orig, seqno) pair.
++                       * So we can be a bit more liberal here and allow
++                       * identical frames from the same orig which the source
++                       * host might have sent multiple times on purpose.
++                       */
++                      if (batadv_compare_eth(entry->orig, orig))
++                              continue;
++              }
+               /* this entry seems to match: same crc, not too old,
+                * and from another gw. therefore return true to forbid it.
+@@ -1657,7 +1671,14 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
+       entry = &bat_priv->bla.bcast_duplist[curr];
+       entry->crc = crc;
+       entry->entrytime = jiffies;
+-      ether_addr_copy(entry->orig, bcast_packet->orig);
++
++      /* known originator */
++      if (orig)
++              ether_addr_copy(entry->orig, orig);
++      /* anonymous originator */
++      else
++              eth_zero_addr(entry->orig);
++
+       bat_priv->bla.bcast_duplist_curr = curr;
+ out:
+@@ -1666,6 +1687,48 @@ bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
+       return ret;
+ }
++/**
++ * batadv_bla_check_ucast_duplist() - Check if a frame is in the broadcast dup.
++ * @bat_priv: the bat priv with all the soft interface information
++ * @skb: contains the multicast packet to be checked, decapsulated from a
++ *  unicast_packet
++ *
++ * Check if it is on our broadcast list. Another gateway might have sent the
++ * same packet because it is connected to the same backbone, so we have to
++ * remove this duplicate.
++ *
++ * Return: true if a packet is in the duplicate list, false otherwise.
++ */
++static bool batadv_bla_check_ucast_duplist(struct batadv_priv *bat_priv,
++                                         struct sk_buff *skb)
++{
++      return batadv_bla_check_duplist(bat_priv, skb, (u8 *)skb->data, NULL);
++}
++
++/**
++ * batadv_bla_check_bcast_duplist() - Check if a frame is in the broadcast dup.
++ * @bat_priv: the bat priv with all the soft interface information
++ * @skb: contains the bcast_packet to be checked
++ *
++ * Check if it is on our broadcast list. Another gateway might have sent the
++ * same packet because it is connected to the same backbone, so we have to
++ * remove this duplicate.
++ *
++ * Return: true if a packet is in the duplicate list, false otherwise.
++ */
++bool batadv_bla_check_bcast_duplist(struct batadv_priv *bat_priv,
++                                  struct sk_buff *skb)
++{
++      struct batadv_bcast_packet *bcast_packet;
++      u8 *payload_ptr;
++
++      bcast_packet = (struct batadv_bcast_packet *)skb->data;
++      payload_ptr = (u8 *)(bcast_packet + 1);
++
++      return batadv_bla_check_duplist(bat_priv, skb, payload_ptr,
++                                      bcast_packet->orig);
++}
++
+ /**
+  * batadv_bla_is_backbone_gw_orig() - Check if the originator is a gateway for
+  *  the VLAN identified by vid.
+@@ -1880,6 +1943,14 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
+                           packet_type == BATADV_UNICAST)
+                               goto handled;
++      /* potential duplicates from foreign BLA backbone gateways via
++       * multicast-in-unicast packets
++       */
++      if (is_multicast_ether_addr(ethhdr->h_dest) &&
++          packet_type == BATADV_UNICAST &&
++          batadv_bla_check_ucast_duplist(bat_priv, skb))
++              goto handled;
++
+       ether_addr_copy(search_claim.addr, ethhdr->h_source);
+       search_claim.vid = vid;
+       claim = batadv_claim_hash_find(bat_priv, &search_claim);
index b44114e9284f5b23c908c2a147c5959df8326f1a..37627c92e3f0438dc5b46f3c91bc0686c154eea6 100644 (file)
@@ -1,4 +1,4 @@
-# 
+#
 # Copyright (C) 2009-2016 OpenWrt.org
 #
 # This is free software, licensed under the GNU General Public License v2.
@@ -7,12 +7,12 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=bird
-PKG_VERSION:=1.6.3
+PKG_VERSION:=1.6.8
 PKG_RELEASE:=1
 
 PKG_SOURCE:=bird-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=ftp://bird.network.cz/pub/bird
-PKG_MD5SUM:=39c51cf57c3ba8b5978b2a657ffa2f647ec7f3ae643e91cf42ee5cb070cf7e7c
+PKG_HASH:=6c61ab5d2ef59d2559a8735b8252b5a0238013b43e5fb8a96c5d9d06e7bc00b2
 PKG_BUILD_DEPENDS:=ncurses readline
 PKG_MAINTAINER:=Álvaro Fernández Rojas <noltari@gmail.com>
 
@@ -22,19 +22,19 @@ include $(INCLUDE_DIR)/package.mk
 
 define Package/bird/Default
   TITLE:=The BIRD Internet Routing Daemon
-  URL:=http://bird.network.cz/
+  URL:=https://bird.network.cz/
   DEPENDS:=+libpthread
 endef
 
 define Package/birdc/Default
   TITLE:=The BIRD command-line client
-  URL:=http://bird.network.cz/
+  URL:=https://bird.network.cz/
   DEPENDS:= +libreadline +libncurses
 endef
 
 define Package/birdcl/Default
   TITLE:=The BIRD lightweight command-line client
-  URL:=http://bird.network.cz/
+  URL:=https://bird.network.cz/
 endef
 
 define Package/bird/Default/description1
index e6127ade321f2f85be582081d1171975ec421d07..3079fd464919cecf3f92ca20504e407ca251682d 100644 (file)
@@ -7,12 +7,12 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=nodogsplash
 PKG_FIXUP:=autoreconf
-PKG_VERSION:=3.2.1
-PKG_RELEASE:=2
+PKG_VERSION:=4.0.3
+PKG_RELEASE:=1
 
 PKG_SOURCE_URL:=https://codeload.github.com/nodogsplash/nodogsplash/tar.gz/v$(PKG_VERSION)?
 PKG_SOURCE:=nodogsplash-$(PKG_VERSION).tar.gz
-PKG_HASH:=16da76ecf7820cd8b32081237e05b24a7d2d8a9db8a47242badc7937d6cf1ae8
+PKG_HASH:=cae212fe7f3c1be8ff5a294a97ab414798f03425635407e18f069e7e4670b250
 PKG_BUILD_DIR:=$(BUILD_DIR)/nodogsplash-$(PKG_VERSION)
 
 PKG_MAINTAINER:=Moritz Warning <moritzwarning@web.de>
@@ -41,17 +41,26 @@ define Package/nodogsplash/description
 endef
 
 define Package/nodogsplash/install
-       $(CP) ./files/* $(1)/
 
        $(INSTALL_DIR) $(1)/usr/bin
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/nodogsplash $(1)/usr/bin/
        $(INSTALL_BIN) $(PKG_BUILD_DIR)/ndsctl $(1)/usr/bin/
 
        $(INSTALL_DIR) $(1)/etc/nodogsplash/htdocs/images
+       $(INSTALL_DIR) $(1)/etc/config
+       $(INSTALL_DIR) $(1)/etc/init.d
+       $(INSTALL_DIR) $(1)/etc/uci-defaults
+       $(INSTALL_DIR) $(1)/usr/lib/nodogsplash
        $(CP) $(PKG_BUILD_DIR)/resources/splash.html $(1)/etc/nodogsplash/htdocs/
        $(CP) $(PKG_BUILD_DIR)/resources/splash.css $(1)/etc/nodogsplash/htdocs/
        $(CP) $(PKG_BUILD_DIR)/resources/status.html $(1)/etc/nodogsplash/htdocs/
        $(CP) $(PKG_BUILD_DIR)/resources/splash.jpg $(1)/etc/nodogsplash/htdocs/images/
+       $(CP) $(PKG_BUILD_DIR)/openwrt/nodogsplash/files/etc/config/nodogsplash $(1)/etc/config/
+       $(CP) $(PKG_BUILD_DIR)/openwrt/nodogsplash/files/etc/init.d/nodogsplash $(1)/etc/init.d/
+       $(CP) $(PKG_BUILD_DIR)/openwrt/nodogsplash/files/etc/uci-defaults/40_nodogsplash $(1)/etc/uci-defaults/
+       $(CP) $(PKG_BUILD_DIR)/openwrt/nodogsplash/files/usr/lib/nodogsplash/restart.sh $(1)/usr/lib/nodogsplash/
+       $(CP) $(PKG_BUILD_DIR)/forward_authentication_service/PreAuth/demo-preauth.sh $(1)/usr/lib/nodogsplash/login.sh
+       $(CP) $(PKG_BUILD_DIR)/forward_authentication_service/fas-aes/fas-aes.php $(1)/etc/nodogsplash/
 endef
 
 define Package/nodogsplash/postrm
diff --git a/nodogsplash/files/etc/config/nodogsplash b/nodogsplash/files/etc/config/nodogsplash
deleted file mode 100644 (file)
index 714d9bf..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-
-# The options available here are an adaptation of the settings used in nodogsplash.conf.
-# See https://github.com/nodogsplash/nodogsplash/blob/master/resources/nodogsplash.conf
-
-config nodogsplash
-  # Set to 0 to disable nodogsplash
-  option enabled 1
-
-  # Set to 0 to disable hook that makes nodogsplash restart when the firewall restarts.
-  # This hook is needed as a restart of Firewall overwrites nodogsplash iptables entries.
-  option fwhook_enabled '1'
-
-  # Serve the file splash.html from this directory
-  option webroot '/etc/nodogsplash/htdocs'
-
-  # Use plain configuration file
-  #option config '/etc/nodogsplash/nodogsplash.conf'
-
-  # Use this option to set the device nogogsplash will bind to.
-  # The value may be an interface section in /etc/config/network or a device name such as br-lan.
-  option gatewayinterface 'br-lan'
-
-  option gatewayname 'OpenWrt Nodogsplash'
-  option maxclients '250'
-
-  # Enables debug output (0-7)
-  #option debuglevel '7'
-
-  # Client timeouts in minutes
-  option preauthidletimeout '30'
-  option authidletimeout '120'
-  # Session Timeout is the interval after which clients are forced out (a value of 0 means never)
-  option sessiontimeout '1200'
-
-  # The interval in seconds at which nodogsplash checks client timeout status
-  option checkinterval '600'
-
-  # Enable BinAuth Support.
-  # If set, a program is called with several parameters on authentication (request) and deauthentication.
-  # Request for authentication:
-  # $<BinAuth> auth_client <client_mac> '<username>' '<password>'
-  #
-  # The username and password values may be empty strings and are URL encoded.
-  # The program is expected to output the number of seconds the client
-  # is to be authenticated. Zero or negative seconds will cause the authentification request
-  # to be rejected. The same goes for an exit code that is not 0.
-  # The output may contain a user specific download and upload limit in KBit/s:
-  # <seconds> <upload> <download>
-  #
-  # Called on authentication or deauthentication:
-  # $<BinAuth> <*auth|*deauth> <incoming_bytes> <outgoing_bytes> <session_start> <session_end>
-  #
-  # "client_auth": Client authenticated via this script.
-  # "client_deauth": Client deauthenticated by the client via splash page.
-  # "idle_deauth": Client was deauthenticated because of inactivity.
-  # "timeout_deauth": Client was deauthenticated because the session timed out.
-  # "ndsctl_auth": Client was authenticated manually by the ndsctl tool.
-  # "ndsctl_deauth": Client was deauthenticated by the ndsctl tool.
-  # "shutdown_deauth": Client was deauthenticated by Nodogsplash terminating.
-  #
-  # Values session_start and session_start are in seconds since 1970 or 0 for unknown/unlimited.
-  #
-  #option binauth '/bin/myauth.sh'
-
-  # Enable Forwarding Authentication Service (FAS)
-  # If set redirection is changed from splash.html to a FAS (provided by the system administrator)
-  # The value is the IP port number of the FAS
-  #option fasport '80'
-
-  # Option: fasremoteip
-  # Default: GatewayAddress (the IP of NDS)
-  # If set, this is the remote ip address of the FAS.
-  #option fasremoteip '46.32.240.41'
-
-  # Option: faspath
-  # Default: /
-  # This is the path from the FAS Web Root to the FAS login page
-  # (not the file system root).
-  #option faspath '/onboard-wifi.net/nodog/fas.php'
-
-  # Option: fas_secure_enabled
-  # Default: 1
-  # If set to "1", authaction and the client token are not revealed and it is the responsibility
-  # of the FAS to request the token from NDSCTL.
-  # If set to "0", the client token is sent to the FAS in clear text in the query string of the
-  # redirect along with authaction and redir.
-  #option fas_secure_enabled '0'
-
-  # Your router may have several interfaces, and you
-  # probably want to keep them private from the network/gatewayinterface.
-  # If so, you should block the entire subnets on those interfaces, e.g.:
-  #list authenticated_users 'block to 192.168.0.0/16'
-  #list authenticated_users 'block to 10.0.0.0/8'
-
-  # Typical ports you will probably want to open up.
-  #list authenticated_users 'allow tcp port 22'
-  #list authenticated_users 'allow tcp port 53'
-  #list authenticated_users 'allow udp port 53'
-  #list authenticated_users 'allow tcp port 80'
-  #list authenticated_users 'allow tcp port 443'
-  # Or for happy customers allow all
-  list authenticated_users 'allow all'
-
-  # For preauthenticated users to resolve IP addresses in their
-  # initial request not using the router itself as a DNS server,
-  # Leave commented to help prevent DNS tunnelling
-  #list preauthenticated_users 'allow tcp port 53'
-  #list preauthenticated_users 'allow udp port 53'
-
-  # Allow ports for SSH/Telnet/DNS/DHCP/HTTP/HTTPS
-  list users_to_router 'allow tcp port 22'
-  list users_to_router 'allow tcp port 23'
-  list users_to_router 'allow tcp port 53'
-  list users_to_router 'allow udp port 53'
-  list users_to_router 'allow udp port 67'
-  list users_to_router 'allow tcp port 80'
-
-  # MAC addresses that are / are not allowed to access the splash page
-  # Value is either 'allow' or 'block'. The allowedmac or blockedmac list is used.
-  #option macmechanism 'allow'
-  #list allowedmac '00:00:C0:01:D0:0D'
-  #list allowedmac '00:00:C0:01:D0:1D'
-  #list blockedmac '00:00:C0:01:D0:2D'
-
-  # MAC addresses that do not need to authenticate
-  #list trustedmac '00:00:C0:01:D0:1D'
-
-  # Nodogsplash uses specific HEXADECIMAL values to mark packets used by iptables as a bitwise mask.
-  # This mask can conflict with the requirements of other packages such as mwan3, sqm etc
-  # Any values set here are interpreted as in hex format.
-  #
-  # List: fw_mark_authenticated
-  # Default: 30000 (0011|0000|0000|0000|0000 binary)
-  #
-  # List: fw_mark_trusted
-  # Default: 20000 (0010|0000|0000|0000|0000 binary)
-  #
-  # List: fw_mark_blocked
-  # Default: 10000 (0001|0000|0000|0000|0000 binary)
-  #
-  #list fw_mark_authenticated '30000'
-  #list fw_mark_trusted '20000'
-  #list fw_mark_blocked '10000'
-
diff --git a/nodogsplash/files/etc/init.d/nodogsplash b/nodogsplash/files/etc/init.d/nodogsplash
deleted file mode 100755 (executable)
index 3c3335c..0000000
+++ /dev/null
@@ -1,200 +0,0 @@
-#!/bin/sh /etc/rc.common
-
-#
-# Startup/shutdown script for nodogsplash captive portal
-#
-
-START=95
-STOP=95
-
-USE_PROCD=1
-
-IPT=/usr/sbin/iptables
-WD_DIR=/usr/bin
-# -s -d 5 runs in background, with level 5 (not so verbose) messages to syslog
-# -f -d 7 runs in foreground, with level 7 (verbose) debug messages to terminal
-OPTIONS="-s -f -d 5"
-CONFIG=""
-
-
-addline() {
-  append CONFIG "$1" "$N"
-}
-
-setup_mac_lists() {
-  local cfg="$1"
-  local macs=""
-  local val
-
-  append_mac() {
-    append macs "$1" ","
-  }
-
-  config_get val "$cfg" macmechanism
-  if [ -z "$val" ]; then
-    # Check if we have AllowedMACList or BlockedMACList defined they will be ignored
-    config_get val "$cfg" allowedmac
-    if [ -n "$val" ]; then
-      echo "Ignoring allowedmac - macmechanism not \"allow\"" >&2
-    fi
-
-    config_get val "$cfg" blockedmac
-    if [ -n "$val" ]; then
-      echo "Ignoring blockedmac - macmechanism not \"block\"" >&2
-    fi
-  elif [ "$val" = "allow" ]; then
-    config_list_foreach "$cfg" allowedmac append_mac
-    addline "AllowedMACList $macs"
-  elif [ "$val" = "block" ]; then
-    config_list_foreach "$cfg" blockedmac append_mac
-    addline "BlockedMACList $macs"
-  else
-    echo "Invalid macmechanism '$val' - allow or block are valid." >&2
-    exit 1
-  fi
-
-  macs=""
-  config_list_foreach "$cfg" trustedmac append_mac
-  if [ -n "$macs" ]; then
-    addline "TrustedMACList $macs"
-  fi
-}
-
-setup_firewall() {
-  local cfg="$1"
-  local uci_name
-  local val
-
-  append_firewall() {
-    addline "  FirewallRule $1"
-  }
-
-  for rule in authenticated-users preauthenticated-users users-to-router trusted-users trusted-users-to-router; do
-    # uci does not allow dashes
-    uci_name=${rule//-/_}
-    addline "FirewallRuleSet $rule {"
-    config_list_foreach "$cfg" "$uci_name" append_firewall
-    addline "}"
-    config_get val "$cfg" "policy_${uci_name}"
-    if [ -n "$val" ]; then
-      addline "EmptyRuleSetPolicy $rule $val"
-    fi
-  done
-}
-
-wait_for_interface() {
-  local ifname="$1"
-  local timeout=10
-
-  for i in $(seq $timeout); do
-    if [ $(ip -4 addr show dev $ifname 2> /dev/null | grep -c inet) -ne 0 ]; then
-      break
-    fi
-    sleep 1
-    if [ $i = $timeout ]; then
-      echo "Interface $ifname not detected." >&2
-      exit 1
-    fi
-  done
-}
-
-generate_uci_config() {
-  local cfg="$1"
-  local val
-  local ifname
-  local download
-  local upload
-
-  # Init config file content
-  CONFIG="# auto-generated config file from /etc/config/nodogsplash"
-
-  config_get val "$cfg" config
-  if [ -n "$val" ]; then
-    if [ ! -f "$val" ]; then
-      echo "Configuration file '$file' doesn't exist." >&2
-      exit 1
-    fi
-    addline "$(cat $val)"
-  fi
-
-  config_get ifname "$cfg" gatewayinterface
-  if [ -z "$ifname" ]; then
-    config_get ifname "$cfg" network
-  fi
-
-  # Get device name if interface name is a section name in /etc/config/network
-  if network_get_device tmp "$ifname"; then
-      ifname="$tmp"
-  fi
-
-  if [ -z "$ifname" ]; then
-      echo "Option network or gatewayinterface missing." >&2
-      exit 1
-  fi
-
-  wait_for_interface "$ifname"
-
-  addline "GatewayInterface $ifname"
-
-  for option in binauth fasport fasremoteip faspath fas_secure_enabled \
-    daemon debuglevel maxclients gatewayname gatewayinterface gatewayiprange \
-    gatewayaddress gatewayport webroot splashpage statuspage imagesdir pagesdir \
-    redirecturl sessiontimeout preauthidletimeout authidletimeout checkinterval \
-    setmss mssvalue trafficcontrol downloadlimit uploadlimit \
-    syslogfacility ndsctlsocket fw_mark_authenticated \
-    fw_mark_blocked fw_mark_trusted
-  do
-    config_get val "$cfg" "$option"
-
-    if [ -n "$val" ]; then
-      addline "$option $val"
-    fi
-  done
-
-  config_get download "$cfg" downloadlimit
-  config_get upload "$cfg" uploadlimit
-
-  if [ -n "$upload" -o -n "$download" ]; then
-    addline "TrafficControl yes"
-  fi
-
-  setup_mac_lists "$cfg"
-  setup_firewall "$cfg"
-
-  echo "$CONFIG" > "/tmp/etc/nodogsplash_$cfg.conf"
-}
-
-# setup configuration and start instance
-create_instance() {
-  local cfg="$1"
-  local val
-
-  config_get_bool val "$cfg" enabled 0
-  [ $val -gt 0 ] || return 0
-
-  generate_uci_config "$cfg"
-
-  procd_open_instance $cfg
-  procd_set_param command /usr/bin/nodogsplash -c "/tmp/etc/nodogsplash_$cfg.conf" $OPTIONS
-  procd_set_param respawn
-  procd_set_param file "/tmp/etc/nodogsplash_$cfg.conf"
-  procd_close_instance
-}
-
-start_service() {
-  # For network_get_device()
-  include /lib/functions
-
-  # For nodogsplash.conf file
-  mkdir -p /tmp/etc/
-
-  config_load nodogsplash
-  config_foreach create_instance nodogsplash
-}
-
-stop_service() {
-  # When procd terminates nodogsplash, it does not exit fast enough.
-  # Otherwise procd will restart nodogsplash twice. First time starting
-  # nodogsplash fails, second time it succeeds.
-  sleep 1
-}
diff --git a/nodogsplash/files/etc/uci-defaults/40_nodogsplash b/nodogsplash/files/etc/uci-defaults/40_nodogsplash
deleted file mode 100644 (file)
index c4f461a..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-
-uci -q batch <<-EOF
-       delete firewall.nodogsplash
-       set firewall.nodogsplash=include
-       set firewall.nodogsplash.type=script
-       set firewall.nodogsplash.path=/usr/lib/nodogsplash/restart.sh
-       commit firewall
-EOF
diff --git a/nodogsplash/files/usr/lib/nodogsplash/restart.sh b/nodogsplash/files/usr/lib/nodogsplash/restart.sh
deleted file mode 100755 (executable)
index e67f11d..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-
-# Check if nodogsplash is running
-if ndsctl status &> /dev/null; then
-  if [ "$(uci -q get nodogsplash.@nodogsplash[0].fwhook_enabled)" = "1" ]; then
-    /etc/init.d/nodogsplash restart
-  fi
-fi
diff --git a/nodogsplash/patches/0001-fix-invalid-pointer-when-clock-is-turned-back.patch b/nodogsplash/patches/0001-fix-invalid-pointer-when-clock-is-turned-back.patch
deleted file mode 100644 (file)
index 9ea55d0..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-From af548c1f885e46309baa6aa175a3822fd16afb2a Mon Sep 17 00:00:00 2001
-From: Moritz Warning <moritzwarning@web.de>
-Date: Thu, 14 Mar 2019 17:19:40 +0100
-Subject: [PATCH] fix invalid pointer when clock is turned back
-
----
- src/util.c | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)
-
-diff --git a/src/util.c b/src/util.c
-index 621062d..77228bf 100644
---- a/src/util.c
-+++ b/src/util.c
-@@ -362,14 +362,14 @@ format_duration(time_t from, time_t to, char buf[64])
- {
-       int days, hours, minutes, seconds;
-       long long int secs;
-+      const char *neg = "";
-       if (from <= to) {
-               secs = to - from;
-       } else {
-               secs = from - to;
-               // Prepend minus sign
--              buf[0] = '-';
--              buf += 1;
-+              neg = "-";
-       }
-       days = secs / (24 * 60 * 60);
-@@ -381,13 +381,13 @@ format_duration(time_t from, time_t to, char buf[64])
-       seconds = secs;
-       if (days > 0) {
--              sprintf(buf, "%dd %dh %dm %ds", days, hours, minutes, seconds);
-+              snprintf(buf, 64, "%s%dd %dh %dm %ds", neg, days, hours, minutes, seconds);
-       } else if (hours > 0) {
--              sprintf(buf, "%dh %dm %ds", hours, minutes, seconds);
-+              snprintf(buf, 64, "%s%dh %dm %ds", neg, hours, minutes, seconds);
-       } else if (minutes > 0) {
--              sprintf(buf, "%dm %ds", minutes, seconds);
-+              snprintf(buf, 64, "%s%dm %ds", neg, minutes, seconds);
-       } else {
--              sprintf(buf, "%ds", seconds);
-+              snprintf(buf, 64, "%s%ds", neg, seconds);
-       }
-       return buf;
--- 
-2.20.1
-
index 9f971071b23434f842f72810d8962109f556f12c..a091119b801e33dc40c64842ccbbc1a65994c42f 100644 (file)
@@ -1,8 +1,8 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=pimbd
-PKG_SOURCE_VERSION:=68f5fc803119e4b33a88b35c096f4d6ac28b6de5
-PKG_VERSION:=2015-08-18-$(PKG_SOURCE_VERSION)
+PKG_SOURCE_VERSION:=dbf4e5913b06e3160f506df15e6a047a403a5f21
+PKG_VERSION:=2018-06-19-$(PKG_SOURCE_VERSION)
 PKG_RELEASE:=1
 
 PKG_SOURCE_PROTO:=git
@@ -17,7 +17,8 @@ include $(INCLUDE_DIR)/package.mk
 include $(INCLUDE_DIR)/cmake.mk
 
 # Spammy debug builds for now
-CMAKE_OPTIONS += -DL_LEVEL=7
+CMAKE_OPTIONS += -DL_LEVEL=7 \
+                -DWITH_LIBUBOX=1
 
 define Package/pimbd
   SECTION:=net
index f8963e01ac3a9710097ad892c11e91e35504504f..5681a5bdfdae3e74b3394f45e2fd495992dcc919 100644 (file)
@@ -8,12 +8,21 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=quagga
-PKG_VERSION:=1.1.0
+PKG_VERSION:=1.1.1
 PKG_RELEASE:=1
-PKG_MD5SUM:=daa303871e07ea5856aae6fd79e89722
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
-PKG_SOURCE_URL:=http://download.savannah.gnu.org/releases/quagga/
+PKG_SOURCE_URL:=https://download.savannah.gnu.org/releases/quagga/
+PKG_HASH:=b5a94e5bdad3062e04595a5692b8cc435f0a85102f75dfdca0a06d093b4ef63f
+
+PKG_MAINTAINER:=Vasilis Tsiligiannis <acinonyx@openwrt.gr>
+PKG_LICENSE:=GPL-2.0-or-later
+PKG_LICENSE_FILES:=COPYING
+
+PKG_BUILD_PARALLEL:=1
+PKG_FIXUP:=autoreconf
+PKG_INSTALL:=1
+
 PKG_CONFIG_DEPENDS:= \
        CONFIG_IPV6 \
        CONFIG_PACKAGE_quagga-watchquagga \
@@ -26,10 +35,6 @@ PKG_CONFIG_DEPENDS:= \
        CONFIG_PACKAGE_quagga-ripd \
        CONFIG_PACKAGE_quagga-ripngd \
        CONFIG_PACKAGE_quagga-vtysh
-PKG_BUILD_PARALLEL:=1
-PKG_FIXUP:=autoreconf
-PKG_INSTALL:=1
-PKG_LICENSE:=GPL-2.0
 
 include $(INCLUDE_DIR)/package.mk
 
@@ -37,10 +42,9 @@ define Package/quagga/Default
   SECTION:=net
   CATEGORY:=Network
   SUBMENU:=Routing and Redirection
-  DEPENDS:=quagga
   TITLE:=The Quagga Software Routing Suite
-  URL:=http://www.quagga.net
-  MAINTAINER:=Vasilis Tsiligiannis <acinonyx@openwrt.gr>
+  URL:=https://www.quagga.net
+  DEPENDS:=quagga
 endef
 
 define Package/quagga
diff --git a/quagga/patches/001-bgpd-Fix-AS_PATH-size-calculation-for-long-paths.patch b/quagga/patches/001-bgpd-Fix-AS_PATH-size-calculation-for-long-paths.patch
new file mode 100644 (file)
index 0000000..3ecbc0e
--- /dev/null
@@ -0,0 +1,28 @@
+From: Andreas Jaggi <aj@open.ch>
+Date: Mon, 2 Oct 2017 19:38:43 +0530
+Subject: bgpd: Fix AS_PATH size calculation for long paths
+Origin: http://git.savannah.gnu.org/cgit/quagga.git/commit?id=7a42b78be9a4108d98833069a88e6fddb9285008
+Bug-Debian: https://bugs.debian.org/879474
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2017-16227
+
+If you have an AS_PATH with more entries than
+what can be written into a single AS_SEGMENT_MAX
+it needs to be broken up.  The code that noticed
+that the AS_PATH needs to be broken up was not
+correctly calculating the size of the resulting
+message.  This patch addresses this issue.
+---
+ bgpd/bgp_aspath.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/bgpd/bgp_aspath.c
++++ b/bgpd/bgp_aspath.c
+@@ -903,7 +903,7 @@ aspath_put (struct stream *s, struct asp
+               assegment_header_put (s, seg->type, AS_SEGMENT_MAX);
+               assegment_data_put (s, seg->as, AS_SEGMENT_MAX, use32bit);
+               written += AS_SEGMENT_MAX;
+-              bytes += ASSEGMENT_SIZE (written, use32bit);
++              bytes += ASSEGMENT_SIZE (AS_SEGMENT_MAX, use32bit);
+             }
+           
+           /* write the final segment, probably is also the first */
diff --git a/quagga/patches/002-Quagga-2018-0543.patch b/quagga/patches/002-Quagga-2018-0543.patch
new file mode 100644 (file)
index 0000000..1f77143
--- /dev/null
@@ -0,0 +1,58 @@
+From cc2e6770697e343f4af534114ab7e633d5beabec Mon Sep 17 00:00:00 2001
+From: Paul Jakma <paul@jakma.org>
+Date: Wed, 3 Jan 2018 23:57:33 +0000
+Subject: bgpd/security: invalid attr length sends NOTIFY with data overrun
+
+Security issue: Quagga-2018-0543
+
+See: https://www.quagga.net/security/Quagga-2018-0543.txt
+
+* bgpd/bgp_attr.c: (bgp_attr_parse) An invalid attribute length is correctly
+  checked, and a NOTIFY prepared.  The NOTIFY can include the incorrect
+  received data with the NOTIFY, for debug purposes.  Commit
+  c69698704806a9ac5 modified the code to do that just, and also send the
+  malformed attr with the NOTIFY.  However, the invalid attribute length was
+  used as the length of the data to send back.
+
+  The result is a read past the end of data, which is then written to the
+  NOTIFY message and sent to the peer.
+
+  A configured BGP peer can use this bug to read up to 64 KiB of memory from
+  the bgpd process, or crash the process if the invalid read is caught by
+  some means (unmapped page and SEGV, or other mechanism) resulting in a DoS.
+
+  This bug _ought_ /not/ be exploitable by anything other than the connected
+  BGP peer, assuming the underlying TCP transport is secure.  For no BGP
+  peer should send on an UPDATE with this attribute.  Quagga will not, as
+  Quagga always validates the attr header length, regardless of type.
+
+  However, it is possible that there are BGP implementations that do not
+  check lengths on some attributes (e.g.  optional/transitive ones of a type
+  they do not recognise), and might pass such malformed attrs on.  If such
+  implementations exists and are common, then this bug might be triggerable
+  by BGP speakers further hops away.  Those peers will not receive the
+  NOTIFY (unless they sit on a shared medium), however they might then be
+  able to trigger a DoS.
+
+  Fix: use the valid bound to calculate the length.
+
+--- a/bgpd/bgp_attr.c
++++ b/bgpd/bgp_attr.c
+@@ -2079,6 +2079,8 @@ bgp_attr_parse (struct peer *peer, struc
+   memset (seen, 0, BGP_ATTR_BITMAP_SIZE);
+   /* End pointer of BGP attribute. */
++  assert (size <= stream_get_size (BGP_INPUT (peer)));
++  assert (size <= stream_get_endp (BGP_INPUT (peer)));
+   endp = BGP_INPUT_PNT (peer) + size;
+   
+   /* Get attributes to the end of attribute length. */
+@@ -2160,7 +2162,7 @@ bgp_attr_parse (struct peer *peer, struc
+           bgp_notify_send_with_data (peer,
+                                      BGP_NOTIFY_UPDATE_ERR,
+                                      BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
+-                                     startp, attr_endp - startp);
++                                     startp, endp - startp);
+         return BGP_ATTR_PARSE_ERROR;
+       }
+       
diff --git a/quagga/patches/003-Quagga-2018-1114.patch b/quagga/patches/003-Quagga-2018-1114.patch
new file mode 100644 (file)
index 0000000..a4b91c5
--- /dev/null
@@ -0,0 +1,99 @@
+From e69b535f92eafb599329bf725d9b4c6fd5d7fded Mon Sep 17 00:00:00 2001
+From: Paul Jakma <paul@jakma.org>
+Date: Sat, 6 Jan 2018 19:52:10 +0000
+Subject: bgpd/security: Fix double free of unknown attribute
+
+Security issue: Quagga-2018-1114
+See: https://www.quagga.net/security/Quagga-2018-1114.txt
+
+It is possible for bgpd to double-free an unknown attribute. This can happen
+via bgp_update_receive receiving an UPDATE with an invalid unknown attribute.
+bgp_update_receive then will call bgp_attr_unintern_sub and bgp_attr_flush,
+and the latter may try free an already freed unknown attr.
+
+* bgpd/bgp_attr.c: (transit_unintern) Take a pointer to the caller's storage
+  for the (struct transit *), so that transit_unintern can NULL out the
+  caller's reference if the (struct transit) is freed.
+  (cluster_unintern) By inspection, appears to have a similar issue.
+  (bgp_attr_unintern_sub) adjust for above.
+
+--- a/bgpd/bgp_attr.c
++++ b/bgpd/bgp_attr.c
+@@ -186,15 +186,17 @@ cluster_intern (struct cluster_list *clu
+ }
+ void
+-cluster_unintern (struct cluster_list *cluster)
++cluster_unintern (struct cluster_list **cluster)
+ {
+-  if (cluster->refcnt)
+-    cluster->refcnt--;
++  struct cluster_list *c = *cluster;
++  if (c->refcnt)
++    c->refcnt--;
+-  if (cluster->refcnt == 0)
++  if (c->refcnt == 0)
+     {
+-      hash_release (cluster_hash, cluster);
+-      cluster_free (cluster);
++      hash_release (cluster_hash, c);
++      cluster_free (c);
++      *cluster = NULL;
+     }
+ }
+@@ -344,15 +346,18 @@ transit_intern (struct transit *transit)
+ }
+ void
+-transit_unintern (struct transit *transit)
++transit_unintern (struct transit **transit)
+ {
+-  if (transit->refcnt)
+-    transit->refcnt--;
++  struct transit *t = *transit;
++  
++  if (t->refcnt)
++    t->refcnt--;
+-  if (transit->refcnt == 0)
++  if (t->refcnt == 0)
+     {
+-      hash_release (transit_hash, transit);
+-      transit_free (transit);
++      hash_release (transit_hash, t);
++      transit_free (t);
++      *transit = NULL;
+     }
+ }
+@@ -793,11 +798,11 @@ bgp_attr_unintern_sub (struct attr *attr
+       UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES));
+       
+       if (attr->extra->cluster)
+-        cluster_unintern (attr->extra->cluster);
++        cluster_unintern (&attr->extra->cluster);
+       UNSET_FLAG(attr->flag, ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST));
+       
+       if (attr->extra->transit)
+-        transit_unintern (attr->extra->transit);
++        transit_unintern (&attr->extra->transit);
+     }
+ }
+--- a/bgpd/bgp_attr.h
++++ b/bgpd/bgp_attr.h
+@@ -184,10 +184,10 @@ extern unsigned long int attr_unknown_co
+ /* Cluster list prototypes. */
+ extern int cluster_loop_check (struct cluster_list *, struct in_addr);
+-extern void cluster_unintern (struct cluster_list *);
++extern void cluster_unintern (struct cluster_list **);
+ /* Transit attribute prototypes. */
+-void transit_unintern (struct transit *);
++void transit_unintern (struct transit **);
+ /* Below exported for unit-test purposes only */
+ struct bgp_attr_parser_args {
diff --git a/quagga/patches/004-Quagga-2018-1550.patch b/quagga/patches/004-Quagga-2018-1550.patch
new file mode 100644 (file)
index 0000000..4bd3da8
--- /dev/null
@@ -0,0 +1,104 @@
+From 9e5251151894aefdf8e9392a2371615222119ad8 Mon Sep 17 00:00:00 2001
+From: Paul Jakma <paul@jakma.org>
+Date: Sat, 6 Jan 2018 22:31:52 +0000
+Subject: bgpd/security: debug print of received NOTIFY data can over-read msg
+ array
+
+Security issue: Quagga-2018-1550
+See: https://www.quagga.net/security/Quagga-2018-1550.txt
+
+* bgpd/bgp_debug.c: (struct message) Nearly every one of the NOTIFY
+  code/subcode message arrays has their corresponding size variables off
+  by one, as most have 1 as first index.
+
+  This means (bgp_notify_print) can cause mes_lookup to overread the (struct
+  message) by 1 pointer value if given an unknown index.
+
+  Fix the bgp_notify_..._msg_max variables to use the compiler to calculate
+  the correct sizes.
+
+--- a/bgpd/bgp_debug.c
++++ b/bgpd/bgp_debug.c
+@@ -29,6 +29,7 @@ Software Foundation, Inc., 59 Temple Pla
+ #include "log.h"
+ #include "sockunion.h"
+ #include "filter.h"
++#include "memory.h"
+ #include "bgpd/bgpd.h"
+ #include "bgpd/bgp_aspath.h"
+@@ -73,7 +74,8 @@ const struct message bgp_status_msg[] =
+   { Clearing,    "Clearing"    },
+   { Deleted,     "Deleted"     },
+ };
+-const int bgp_status_msg_max = BGP_STATUS_MAX;
++#define BGP_DEBUG_MSG_MAX(msg) const int msg ## _max = array_size (msg)
++BGP_DEBUG_MSG_MAX (bgp_status_msg);
+ /* BGP message type string. */
+ const char *bgp_type_str[] =
+@@ -84,7 +86,8 @@ const char *bgp_type_str[] =
+   "NOTIFICATION",
+   "KEEPALIVE",
+   "ROUTE-REFRESH",
+-  "CAPABILITY"
++  "CAPABILITY",
++  NULL,
+ };
+ /* message for BGP-4 Notify */
+@@ -98,15 +101,15 @@ static const struct message bgp_notify_m
+   { BGP_NOTIFY_CEASE, "Cease"},
+   { BGP_NOTIFY_CAPABILITY_ERR, "CAPABILITY Message Error"},
+ };
+-static const int bgp_notify_msg_max = BGP_NOTIFY_MAX;
++BGP_DEBUG_MSG_MAX (bgp_notify_msg);
+ static const struct message bgp_notify_head_msg[] = 
+ {
+   { BGP_NOTIFY_HEADER_NOT_SYNC, "/Connection Not Synchronized"},
+   { BGP_NOTIFY_HEADER_BAD_MESLEN, "/Bad Message Length"},
+-  { BGP_NOTIFY_HEADER_BAD_MESTYPE, "/Bad Message Type"}
++  { BGP_NOTIFY_HEADER_BAD_MESTYPE, "/Bad Message Type"},
+ };
+-static const int bgp_notify_head_msg_max = BGP_NOTIFY_HEADER_MAX;
++BGP_DEBUG_MSG_MAX (bgp_notify_head_msg);
+ static const struct message bgp_notify_open_msg[] = 
+ {
+@@ -119,7 +122,7 @@ static const struct message bgp_notify_o
+   { BGP_NOTIFY_OPEN_UNACEP_HOLDTIME, "/Unacceptable Hold Time"}, 
+   { BGP_NOTIFY_OPEN_UNSUP_CAPBL, "/Unsupported Capability"},
+ };
+-static const int bgp_notify_open_msg_max = BGP_NOTIFY_OPEN_MAX;
++BGP_DEBUG_MSG_MAX (bgp_notify_open_msg);
+ static const struct message bgp_notify_update_msg[] = 
+ {
+@@ -136,7 +139,7 @@ static const struct message bgp_notify_u
+   { BGP_NOTIFY_UPDATE_INVAL_NETWORK, "/Invalid Network Field"},
+   { BGP_NOTIFY_UPDATE_MAL_AS_PATH, "/Malformed AS_PATH"},
+ };
+-static const int bgp_notify_update_msg_max = BGP_NOTIFY_UPDATE_MAX;
++BGP_DEBUG_MSG_MAX (bgp_notify_update_msg);
+ static const struct message bgp_notify_cease_msg[] =
+ {
+@@ -150,7 +153,7 @@ static const struct message bgp_notify_c
+   { BGP_NOTIFY_CEASE_COLLISION_RESOLUTION, "/Connection collision resolution"},
+   { BGP_NOTIFY_CEASE_OUT_OF_RESOURCE, "/Out of Resource"},
+ };
+-static const int bgp_notify_cease_msg_max = BGP_NOTIFY_CEASE_MAX;
++BGP_DEBUG_MSG_MAX (bgp_notify_cease_msg);
+ static const struct message bgp_notify_capability_msg[] = 
+ {
+@@ -159,7 +162,7 @@ static const struct message bgp_notify_c
+   { BGP_NOTIFY_CAPABILITY_INVALID_LENGTH, "/Invalid Capability Length"},
+   { BGP_NOTIFY_CAPABILITY_MALFORMED_CODE, "/Malformed Capability Value"},
+ };
+-static const int bgp_notify_capability_msg_max = BGP_NOTIFY_CAPABILITY_MAX;
++BGP_DEBUG_MSG_MAX (bgp_notify_capability_msg);
+ /* Origin strings. */
+ const char *bgp_origin_str[] = {"i","e","?"};
diff --git a/quagga/patches/005-Quagga-2018-1975.patch b/quagga/patches/005-Quagga-2018-1975.patch
new file mode 100644 (file)
index 0000000..5e0c6ee
--- /dev/null
@@ -0,0 +1,32 @@
+From ce07207c50a3d1f05d6dd49b5294282e59749787 Mon Sep 17 00:00:00 2001
+From: Paul Jakma <paul@jakma.org>
+Date: Sat, 6 Jan 2018 21:20:51 +0000
+Subject: bgpd/security: fix infinite loop on certain invalid OPEN messages
+
+Security issue: Quagga-2018-1975
+See: https://www.quagga.net/security/Quagga-2018-1975.txt
+
+* bgpd/bgp_packet.c: (bgp_capability_msg_parse) capability parser can infinite
+  loop due to checks that issue 'continue' without bumping the input
+  pointer.
+
+--- a/bgpd/bgp_packet.c
++++ b/bgpd/bgp_packet.c
+@@ -2251,7 +2251,8 @@ bgp_capability_msg_parse (struct peer *p
+   end = pnt + length;
+-  while (pnt < end)
++  /* XXX: Streamify this */
++  for (; pnt < end; pnt += hdr->length + 3)
+     {      
+       /* We need at least action, capability code and capability length. */
+       if (pnt + 3 > end)
+@@ -2339,7 +2340,6 @@ bgp_capability_msg_parse (struct peer *p
+           zlog_warn ("%s unrecognized capability code: %d - ignored",
+                      peer->host, hdr->code);
+         }
+-      pnt += hdr->length + 3;
+     }
+   return 0;
+ }
index 84451033f937ca7e4876c4e508bc6c5ac1b881ff..18078bc8871a138a2a9b52b4d5097c3025a68b36 100644 (file)
@@ -1,6 +1,6 @@
 --- a/lib/command.c
 +++ b/lib/command.c
-@@ -3198,6 +3198,13 @@ DEFUN (config_write_file,
+@@ -3200,6 +3200,13 @@ DEFUN (config_write_file,
                 VTY_NEWLINE);
          goto finished;
        }
@@ -14,7 +14,7 @@
    if (link (config_file, config_file_sav) != 0)
      {
        vty_out (vty, "Can't backup old configuration file %s.%s", config_file_sav,
-@@ -3211,7 +3218,23 @@ DEFUN (config_write_file,
+@@ -3213,7 +3220,23 @@ DEFUN (config_write_file,
                VTY_NEWLINE);
        goto finished;
      }