Compare commits

..

72 commits

Author SHA1 Message Date
Simon Wunderlich
83f515d7ae
Merge pull request #624 from ecsv/batadv-for-18.06
batman-adv: Fix missing include for backported 2020.4 patch
2020-10-27 17:07:28 +01:00
Sven Eckelmann
7448ab9d65 batman-adv: Fix missing include for backported 2020.4 patch
The build can fail in some configurations because the include for
batadv_send_skb_unicast was missing in batman-adv 2018.1.

Reported-by: Martin Weinelt <martin@darmstadt.freifunk.net>
Fixes: c197ddb225 ("batman-adv: Merge bugfixes from 2020.4")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
2020-10-27 15:49:57 +01:00
Simon Wunderlich
8f47c32d58
Merge pull request #621 from ecsv/batadv-for-18.06
openwrt-18.06: batman-adv: Merge bugfixes from 2020.4
2020-10-27 15:03:11 +01:00
Sven Eckelmann
351c782c20 batctl: Merge bugfixes from 2020.4
* tcpdump: Fix endianness in ICMPv6 Echo Request/Reply parsing

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2020-10-24 22:02:21 +02:00
Sven Eckelmann
c197ddb225 batman-adv: Merge bugfixes from 2020.4
* bla: fix type misuse for backbone_gw hash indexing
* mcast/TT: fix wrongly dropped or rerouted packets
* Add missing include for in_interrupt()
* mcast: fix duplicate mcast packets in BLA backbone from LAN
* mcast: fix duplicate mcast packets in BLA backbone from mesh
* mcast: fix duplicate mcast packets from BLA backbone to mesh

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2020-10-24 21:59:58 +02:00
Simon Wunderlich
3862f61ee8
Merge pull request #604 from ecsv/batadv-for-18.06
openwrt-18.06: batman-adv: Merge bugfixes from 2020.3
2020-08-27 10:27:23 +02:00
Sven Eckelmann
71a7397822 batman-adv: Merge bugfixes from 2020.3
* Avoid uninitialized chaddr when handling DHCP
* Fix own OGM check in aggregated OGMs
* bla: use netif_rx_ni when not in interrupt context

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2020-08-25 20:38:30 +02:00
Simon Wunderlich
1f4d94422d
Merge pull request #585 from ecsv/batadv-for-18.06
openwrt-18.06: batctl: Merge bugfixes from 2020.2
2020-07-07 09:20:09 +02:00
Sven Eckelmann
8dd6c08c2d batctl: Merge bugfixes from 2020.2
* fix endianness when reading radiotap header
* Only remove batadv interface on hardif reduction

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2020-07-06 20:12:06 +02:00
Alexander Couzens
0c19201587 nodogsplash: update to 4.0.3
Fix a traversal path attack.

Signed-off-by: Alexander Couzens <lynxis@fe80.eu>
2020-05-06 13:24:48 +02:00
Simon Wunderlich
b682059b2b
Merge pull request #564 from ecsv/batadv-for-18.06
openwrt-18.06: batman-adv: Merge bugfixes from 2020.1
2020-04-27 10:25:46 +02:00
Sven Eckelmann
719709a03e batman-adv: Merge bugfixes from 2020.1
* fix batadv_nc_random_weight_tq
* Fix refcnt leak in batadv_show_throughput_override
* Fix refcnt leak in batadv_store_throughput_override
* Fix refcnt leak in batadv_v_ogm_process

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2020-04-24 21:03:09 +02:00
Sven Eckelmann
4e7858709c batctl: Merge bugfixes from 2020.1
* Return EXIT_FAILURE when throughputmeter failed

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2020-04-24 21:00:59 +02:00
Simon Wunderlich
300fec38d2
Merge pull request #555 from ecsv/batadv-for-18.06
openwrt-18.06: batman-adv: Merge bugfixes from 2020.0
2020-03-10 17:08:55 +01:00
Sven Eckelmann
8f8ab76e18 batman-adv: Merge bugfixes from 2020.0
* Don't schedule OGM for disabled interface

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2020-03-06 20:59:02 +01:00
Josef Schlehofer
0e63ef9276 quagga: update to version 1.1.1 (#541)
Makefile changes:
- Use HTTPS everywhere
- Reorder some things to have it in sync with other packages
- Fixed SPDX License Identifier
- Added PKG_LICENSE_FILES
- For checksum use SHA256

Refreshed patches

Fixes CVEs:
- CVE-2017-5495
- CVE-2017-16227

Fixes security issues:
- Quagga-2018-0543: attr_endp used for NOTIFY data
https://gogs.quagga.net/Quagga/quagga/src/master/doc/security/Quagga-2018-0543.txt
- Quagga-2018-1114: bgpd double free
https://gogs.quagga.net/Quagga/quagga/src/master/doc/security/Quagga-2018-1114.txt
- Quagga-2018-1550: debug overrun in notify lookup tables
https://gogs.quagga.net/Quagga/quagga/src/master/doc/security/Quagga-2018-1550.txt
- Quagga-2018-1975: BGP capability inf. loop
https://gogs.quagga.net/Quagga/quagga/src/master/doc/security/Quagga-2018-1975.txt

Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
2020-01-26 23:13:23 +01:00
Josef Schlehofer
9fa2b249cc [OpenWrt 18.06] bird: Update to version 1.6.8 (security fix) (#539)
* bird: Bump to v1.6.7

Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
(cherry-picked from commit 559619d9d9)

* bird: Update to version 1.6.8

Fixes CVE-2019-16159

Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
(cherry picked from commit
6c61ab5d2ef59d2559a8735b8252b5a0238013b43e5fb8a96c5d9d06e7bc00b2)

Co-authored-by: Toke Høiland-Jørgensen <toke@toke.dk>
2020-01-01 17:33:24 +01:00
Simon Wunderlich
b3125f0d4c
Merge pull request #537 from ecsv/batadv-for-18.06
openwrt-18.06: batman-adv: Merge bugfixes from 2019.5
2019-12-14 16:59:15 +01:00
Sven Eckelmann
0d22982f30 batman-adv: Merge bugfixes from 2019.5
* fix DAT candidate selection on little endian systems

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2019-12-13 22:11:22 +01:00
Josef Schlehofer
3610d114f9 pimbd: update to current git HEAD (#534)
Allow compilation with gcc 7.3.0.

Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
(cherry-picked from commit c299f8bcea)
Signed-off-by: Josef Schlehofer <pepe.schlehofer@gmail.com>
2019-12-08 15:38:03 +01:00
Simon Wunderlich
c52779c05a
Merge pull request #520 from ecsv/batadv-for-18.06
openwrt-18.06: batman-adv: Merge bugfixes from 2019.4
2019-10-26 10:30:47 +02:00
Sven Eckelmann
ee3264b6aa batman-adv: Merge bugfixes from 2019.4
* fix uninit-value in batadv_netlink_get_ifindex()
* Only read OGM tvlv_len after buffer len check
* Only read OGM2 tvlv_len after buffer len check
* Avoid free/alloc race when handling OGM2 buffer
* Avoid free/alloc race when handling OGM buffer
* Introduce own OGM2 buffer mutex
* Avoid OGM workqueue synchronous cancel deadlock

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2019-10-25 22:41:19 +02:00
zorun
049cb8a4c4
Merge pull request #511 from adrianschmutzler/babeld1806
[18.06] babeld: Update to version 1.8.5
2019-09-04 00:34:51 +02:00
Adrian Schmutzler
e80f582b2b babeld: Update to version 1.8.5
This updates babeld to the latest release from the
babeld-1.8-branch, which introduces mostly fixes:

22 July 2019: babeld-1.8.5

  * Fixed a bug that caused confustion between learned routes and
    imported routes (thanks to Fabian Bläse).
  * Fixed a bug that prevented install filters from being evaluated
    (thanks to Killian Lufau).

9 November 2018: babeld-1.8.4

  * Fixed a bug that discarded pipelined commands received on the local
    configuration interface.
  * Added the per-interface option rfc6126-compatible.

24 September 2018: babeld-1.8.3

  * Fixed a read-only two byte buffer overflow in the packet parser.
    This is a read-only overflow, and hence most probably not exploitable.
  * Fixed an issue with creating unreachable routes on recent kernels
    (4.16 and up).  Thanks to Christof Schulze.
  * Notice interface changes faster by listening to more netlink events.
    Thanks to Christof Schulze.
  * Fixed a local interface issue when an interface has no link-local
    address.  Thanks to Christof Schulze.

During the last months, "babeld-1.8.5" has shown superior stability
compared to earlier versions in my tests.

Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
2019-09-03 11:47:43 +02:00
Rob White
6e50f8b998 nodogsplash: Backport Version 4.0.1. (#493)
This version has numerous fixes and enhancements.
It is compatible with the previous v3.2.1 release and onwards.

 Important fixes in this version:
 * Fix coding error in fas-aes.php [bluewavenet]
 * Make debuglevel platform independent [mwarning]
 * Fix memory handling bug, issue nodogsplash/nodogsplash#341 [mwarning] [stevo01]
 * ndsctl_thread - ignore interupts when returning from epoll [lynxis]
 * auth.c - use correct types to prevent cast and comparement of uint and int [lynxis]
 * openwrt/init.d - prevent start of the daemon if configuration generation fails [lynxis]
 * Generate Error 403 Forbidden, if Gateway Port is accessed directly [bluewavenet]
 * Validate fasremoteip as a valid dotted format IPv4 address [bluewavenet] [mwarning]
 * Prevent client CPD "Too Many Redirects" error. [bluewavenet]

Maintainer: Moritz Warning <moritzwarning@web.de>

Signed-off-by: Rob White <rob@blue-wave.net>
2019-07-30 16:20:15 +02:00
Rob White
a55193512f nodogsplash: Backport of Version 4.0.0. (#486)
This version has numerous fixes and enhancements.
It is compatible with the previous v3.2.1 release and onwards.

Maintainer: Moritz Warning <moritzwarning@web.de>

Signed-off-by: Rob White <rob@blue-wave.net>
2019-07-25 13:32:53 +02:00
Jo-Philipp Wich
bb156bf355
Merge pull request #455 from BKPepe/bird-openwrt18.06
[OpenWrt 18.06] bird: update to version 1.6.6
2019-06-26 19:24:35 +02:00
Simon Wunderlich
7589804a56
Merge pull request #474 from ecsv/batadv-for-18.06
openwrt-18.06: batman-adv: Fix duplicated OGMs on NETDEV_UP
2019-06-02 22:41:16 +02:00
Sven Eckelmann
c07326c3ba 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 v2016.3 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: 549909f89d ("batman-adv: upgrade package to latest release 2016.3")
Reported-by: Linus Lüssing <linus.luessing@c0d3.blue>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
2019-06-02 14:07:39 +02:00
Simon Wunderlich
cad1fba86f
Merge pull request #469 from ecsv/batadv-for-18.06
openwrt-18.06: batman-adv: Merge bugfixes from 2019.2
2019-05-24 09:45:38 +02:00
Sven Eckelmann
145ba7f46a batman-adv: Merge bugfixes from 2019.2
* mcast: fix multicast tt/tvlv worker locking
* fix for leaked TVLV handler

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2019-05-23 19:53:52 +02:00
Sven Eckelmann
40b75193bc batman-adv: Reorder patches
Signed-off-by: Sven Eckelmann <sven@narfation.org>
2019-05-23 19:08:04 +02:00
Simon Wunderlich
e5fe4b63e8
Merge pull request #462 from ecsv/batadv-18.06
openwrt-18.06: batman-adv: Merge bugfixes from 2019.1
2019-03-29 13:33:01 +01:00
Sven Eckelmann
ee2d981d00 batman-adv: Merge bugfixes from 2019.1
* fix uninit-value in batadv_interface_tx()
* Reduce claim hash refcnt only for removed entry
* Reduce tt_local hash refcnt only for removed entry
* Reduce tt_global hash refcnt only for removed entry

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2019-03-28 20:39:10 +01:00
Moritz Warning
4d7a182ef3 nodogsplash: fix invalid pointer bug when clock is turned back (#456)
Signed-off-by: Moritz Warning <moritzwarning@web.de>
2019-03-14 18:31:33 +01:00
Josef Schlehofer
d3f317b4ed
bird: update to version 1.6.6
Signed-off-by: Josef Schlehofer <josef.schlehofer@nic.cz>
2019-03-13 12:29:51 +01:00
Axel Neumann
2ad165c954
Merge pull request #452 from dangowrt/openwrt-18.06
bmx7: update to git snapshot as of 2018-12-29
2019-03-05 00:52:11 +01:00
Daniel Golle
71f9aae5e4 luci-app-bmx7: update to v0.1-alpha
consolidated commits from master branch:
 fce1287 luci-app-bmx7: show mDNS menu if available
 3e259f8 luci-app-bmx7: fix bmx7-info script's "$info" call
 a7d7f4b luci-app-bmx7: fix bmx7-info script's indentation
 9345df9 luci-app-bmx7: update version, dependencies and maintainer
 a1e1020 luci-app-bmx7: refactory, multiple fixes and add topology graph

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2019-03-02 22:34:57 +01:00
Daniel Golle
0e3d70176c bmx7: update to git snapshot as of 2018-12-29
consolidated commits from master branch:
 25916fb bmx7: update to git snapshot as of 2018-12-29
(dfe8097 bmx7: Avoid namespace collision with libubox.)
(43449bc treewide: Basic cleanup and alignment to package guidelines (#383))
 440ad46 bmx7: add config trigger

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
2019-03-02 22:34:57 +01:00
Sven Eckelmann
42af8350c1 batman-adv: Refresh patches
Signed-off-by: Sven Eckelmann <sven@narfation.org>
2019-02-11 11:24:47 +01:00
Simon Wunderlich
ea345d16a6
Merge pull request #442 from ecsv/batadv-18.06
openwrt-18.06: batman-adv: Merge bugfixes from 2019.0
2019-01-16 10:00:25 +01:00
Sven Eckelmann
02313085ea batman-adv: Merge bugfixes from 2019.0
* Avoid WARN on net_device without parent in netns
* Force mac header to start of data on xmit

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2019-01-16 09:45:07 +01:00
Simon Wunderlich
bc6e7f6903
Merge pull request #425 from ecsv/batadv-18.06
openwrt-18.06: batman-adv: Merge bugfixes from 2018.4
2018-11-08 11:38:58 +01:00
Sven Eckelmann
c00a1bfbbf alfred: Merge bugfixes from 2018.4
* Fix detection of own packets for IPv4 mode
* Request MAC resolution for IPv4 address not in ARP cache

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2018-11-08 00:18:54 +01:00
Sven Eckelmann
7bf62cc8b5 batman-adv: Merge bugfixes from 2018.4
* Use explicit tvlv padding for ELP packets
* Expand merged fragment buffer for full packet

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2018-11-08 00:10:24 +01:00
Simon Wunderlich
d1cf6d1949
Merge pull request #422 from ecsv/batadv-18.06
openwrt-18.06: batman-adv package fixes
2018-10-18 15:01:58 +02:00
Sven Eckelmann
121c92d669 batctl: Don't overwrite default PKG_BUILD_DIR
There is no benefit to overwrite the PKG_BUILD_DIR directory for batctl. As
seen with kmod-batman-adv, it actually can also break the build.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2018-10-14 16:04:31 +02:00
Sven Eckelmann
95e56cf644 alfred: Add openwrt revision to internal version
OpenWrt is using a modified version of the software and these modifications
may introduce extra bugs (or behavior changes). It is also patched for
stable releases instead of switching to new releases. The revision should
therefore be added to the version number to make it easier understandable
which modified version the user may have installed.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2018-10-14 16:04:31 +02:00
Sven Eckelmann
93cce266fe batctl: Add openwrt revision to internal version
OpenWrt is using a modified version of the software and these modifications
may introduce extra bugs (or behavior changes). It is also patched for
stable releases instead of switching to new releases. The revision should
therefore be added to the version number to make it easier understandable
which modified version the user may have installed.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2018-10-14 16:04:31 +02:00
Sven Eckelmann
1a83b56d47 batman-adv: Add openwrt revision to internal version
OpenWrt is using a modified version of the software and these modifications
may introduce extra bugs (or behavior changes). It is also patched for
stable releases instead of switching to new releases. The revision should
therefore be added to the version number to make it easier understandable
which modified version the user may have installed.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2018-10-14 16:04:31 +02:00
Sven Eckelmann
1ba424a4d0 batman-adv: Load module with AutoProbe
cfg80211 is loaded by kmodloader after the modules with a priority
(AutoLoad) are loaded. batman-adv should therefore also be loaded at that
time and must not load cfg80211 itself. The information in the ELF header
are enough for kmodloader to load these two modules in the correct order.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2018-10-14 16:04:31 +02:00
Sven Eckelmann
b9656fb31e batman-adv: Fix search for cfg80211 module symbols
The Module.symvers with the exported symbols of all other kernel modules in
OpenWrt is usually placed in the main source directory of the package. But
the actual sources for batman-adv are found in net/batman-adv. OpenWrt must
therefore be informed to move it to this subdirectory or otherwise modpost
will fail to find the symbols

  WARNING: "cfg80211_get_station" [.../batman-adv-2018.1/net/batman-adv/batman-adv.ko] undefined!

The dependency will then be missing in the .modinfo depends= option and
thus it the kernel module loader will not correctly load the cfg80211.ko
during bootup.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2018-10-14 16:04:31 +02:00
Sven Eckelmann
059d7266a9 batman-adv: Remove unused option "interfaces" in config
Signed-off-by: Sven Eckelmann <sven@narfation.org>
2018-10-14 16:04:31 +02:00
Sven Eckelmann
3d5c2d06b6 batman-adv: Add DEBUG_LOG -> DEBUGFS dependency
The debug log is only available when the debugfs is also enabled. This
must be reflected in Kconfig to avoid incompatible selection of batman-adv
options.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2018-10-14 16:04:31 +02:00
Sven Eckelmann
a9a4b04b98 batman-adv: Rebuild automatically on mac80211 changes
Signed-off-by: Sven Eckelmann <sven@narfation.org>
2018-10-14 15:31:24 +02:00
Moritz Warning
8b760071d1 nodogsplash: fix download hash
The tagging of the release was wrong, as a result, the hash of the downloaded files is different from the usual download package.
The content has been verified to be the same.

Signed-off-by: Moritz Warning <moritzwarning@web.de>
2018-09-28 15:32:43 +02:00
Moritz Warning
ebc5874d9c
Merge pull request #417 from bluewavenet/openwrt-18.06
nodogsplash: Backport v3.2.1 to OpenWrt 18.06
2018-09-27 18:37:13 +02:00
Rob White
f68a998fb2 nodogsplash: Backport v3.2.1 to OpenWrt 18.06
This release provides bugfixes and some minor enhancements:

  * reset upload/download counter when a client has been authenticated a second time [mwarning]
  * print sesssion duration as 0 in "ndsctl json" and "ndsctl clients" output when a session has not been started [mwarning]
  * rework html templater to speed up splash page generation [mwarning]
  * FAS documentation updates [bluewavenet]
  * Add CSS file and update splash and status html [bluewavenet]

Signed-off-by: Rob White <rob@blue-wave.net>
2018-09-27 14:51:23 +01:00
Simon Wunderlich
2e21588922
Merge pull request #414 from ecsv/batadv-18.06
openwrt-18.06: batman-adv: Merge bugfixes from 2018.3
2018-09-17 10:55:06 +02:00
Moritz Warning
3785b5552f
Merge pull request #411 from bluewavenet/openwrt-18.06
nodogsplash: add missing config options
2018-09-15 12:14:59 +02:00
Sven Eckelmann
ddef3900a4 batman-adv: Merge bugfixes from 2018.3
* Avoid probe ELP information leak
* Fix segfault when writing to throughput_override
* Fix segfault when writing to sysfs elp_interval
* fix backbone_gw refcount on queue_work() failure
* fix hardif_neigh refcount on queue_work() failure
* Prevent duplicated gateway_node entry
* Prevent duplicated nc_node entry
* Prevent duplicated softif_vlan entry
* Prevent duplicated global TT entry
* Prevent duplicated tvlv handler

Signed-off-by: Sven Eckelmann <sven@narfation.org>
2018-09-15 11:19:36 +02:00
Rob White
ed5d97c2ce nodogsplash: add missing config options
sessiontimeout (minutes) until client is forced out
checkinterval (seconds) interval at which nodogsplash checks client timeout status

Add real world useful values to timeout options.

Signed-off-by: Rob White rob@blue-wave.net
2018-09-15 10:02:54 +01:00
Moritz Warning
b0e37f285f
Merge pull request #409 from wfleurant/backport-fix-luci-cjdns
backport: luci-app-cjdns: luci admin support for cjdns-v20.2 (#394)
2018-09-11 11:22:04 +02:00
William Fleurant
85775e956c
luci-app-cjdns: luci admin support for cjdns-v20.2 (#394)
* luci-app-cjdns: luci admin support for cjdns-v20.2

* adds layer 2 and 3 address display column
* fixes switch label pinger
* get version from addr string
* parse addr string for peerStats publicKey

Signed-off-by: William Fleurant <william@netblazr.com>

* luci-app-cjdns: bump release, update repo-url and license year

Signed-off-by: William Fleurant <william@netblazr.com>

* luci-app-cjdns: support views for 17.01 and 18.06
- fixed user/name column
- removed latency column
- combind peerstats functions
- fix css on overview page
- table displays with `cbi_update_table` with fallback
- columns ordered similar to peerStats.js output
- normalized XHR polling to mimic wireless.htm by jow@openwrt

Signed-off-by: William Fleurant <william@netblazr.com>

Signed-off-by: William Fleurant <william@netblazr.com>
2018-09-10 03:08:29 +00:00
Moritz Warning
59e815882d
Merge pull request #407 from bluewavenet/openwrt-18.06
nodogsplash: Backport v3.2.0 to Openwrt 18.06
2018-09-05 14:23:59 +02:00
Rob White
883dec4212 nodogsplash: Backport v3.2.0
Signed-off-by: Rob White <rob@blue-wave.net>
2018-09-04 17:15:48 +01:00
Rob White
021153d84f nodogsplash: Remove nodogsplash and nodogsplash2
in preparation for backport of v3.2.0

Signed-off-by: Rob White <rob@blue-wave.net>
2018-09-04 17:12:31 +01:00
Moritz Warning
9d9c0d054e
Merge pull request #403 from dangowrt/bmx7-for-openwrt-18.06
bmx7: sync with master branch
2018-08-19 16:01:22 +02:00
Eneas U de Queiroz
ab3529a555 bmx7: Avoid namespace collision with libubox.
Applied Daniel Golle's patch from
https://github.com/bmx-routing/bmx7/pull/35 to "rename some list stuff
to avoid namespace collision with libubox."

Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
2018-08-16 17:13:42 +02:00
Paul Spooren
f0b852b291 bmx7: add config trigger
this should automatically reload bmx7 if the config files is changed

Signed-off-by: Paul Spooren <mail@aparcar.org>
2018-08-16 17:13:42 +02:00
Simon Wunderlich
1b9d1c419f
Merge pull request #385 from ecsv/batadv-2018.1
openwrt-18.06: batman-adv: add patches from 2018.1-maint 2018-06-12
2018-06-13 11:53:17 +02:00
Simon Wunderlich
a22f490620
Merge pull request #380 from ecsv/batadv-2018.1
openwrt-18.06: batman-adv: add patches from 2018.1-maint 2018-06-03
2018-06-04 14:12:59 +02:00
319 changed files with 17522 additions and 6941 deletions

View file

@ -1,16 +0,0 @@
Please make sure that the issue subject starts with `<package-name>: `
Also make sure that the package is maintained in this repository and not in OpenWrt-base, OpenWrt-packages or OpenWrt-LuCI.
Issues related to releases below 18.06 and forks are not supported or maintained and will be closed.
# Issue template (remove lines from top till here)
Maintainer: @\<github-user> (find it by checking history of the package Makefile)
Environment: (put here arch, model, OpenWrt version)
Description:
```
Formating code blocks by wrapping them with pairs of ```
```

View file

@ -1,5 +0,0 @@
Maintainer: me / @\<github-user> (find it by checking history of the package Makefile)
Compile tested: (put here arch, model, OpenWrt version)
Run tested: (put here arch, model, OpenWrt version, tests done)
Description:

View file

@ -1,6 +0,0 @@
ARG ARCH=x86-64
FROM openwrt/rootfs:$ARCH
ADD entrypoint.sh /entrypoint.sh
CMD ["/entrypoint.sh"]

View file

@ -1,91 +0,0 @@
name: Check autorelease deprecation
on:
pull_request_target:
types: [opened, synchronize, converted_to_draft, ready_for_review, edited]
jobs:
build:
name: Check autorelease deprecation
runs-on: ubuntu-latest
strategy:
fail-fast: false
permissions:
pull-requests: write
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Determine branch name
run: |
BRANCH="${GITHUB_BASE_REF#refs/heads/}"
echo "Building for $BRANCH"
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
- name: Determine changed packages
run: |
RET=0
# only detect packages with changes
PKG_ROOTS=$(find . -name Makefile | \
grep -v ".*/src/Makefile" | \
sed -e 's@./\(.*\)/Makefile@\1/@')
CHANGES=$(git diff --diff-filter=d --name-only origin/$BRANCH...)
for ROOT in $PKG_ROOTS; do
for CHANGE in $CHANGES; do
if [[ "$CHANGE" == "$ROOT"* ]]; then
if grep -q '$(AUTORELEASE)' "$ROOT/Makefile"; then
CONTAINS_AUTORELEASE+="$ROOT"
fi
break
fi
done
done
if [ -n "$CONTAINS_AUTORELEASE" ]; then
RET=1
cat > "$GITHUB_WORKSPACE/pr_comment.md" << EOF
Please do no longer set *PKG_RELEASE* to *AUTORELEASE* as the
feature is deprecated. Please use an integer instead. Below is a
list of affected packages including correct *PKG_RELEASE*:
EOF
fi
for ROOT in $CONTAINS_AUTORELEASE; do
echo -n " - ${ROOT}Makefile: PKG_RELEASE:=" >> "$GITHUB_WORKSPACE/pr_comment.md"
last_bump="$(git log --pretty=format:'%h %s' "$ROOT" |
grep --max-count=1 -e ': [uU]pdate to ' -e ': [bB]ump to ' |
cut -f 1 -d ' ')"
if [ -n "$last_bump" ]; then
echo -n $(($(git rev-list --count "$last_bump..HEAD" "$ROOT") + 2)) >> "$GITHUB_WORKSPACE/pr_comment.md"
else
echo -n $(($(git rev-list --count HEAD "$ROOT") + 2)) >> "$GITHUB_WORKSPACE/pr_comment.md"
fi
echo >> "$GITHUB_WORKSPACE/pr_comment.md"
done
exit $RET
- name: Find Comment
uses: peter-evans/find-comment@v2
if: ${{ failure() }}
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
- name: Create or update comment
uses: peter-evans/create-or-update-comment@v2
if: ${{ failure() }}
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body-file: 'pr_comment.md'
edit-mode: replace

View file

@ -1,26 +0,0 @@
#!/bin/sh
color_out() {
printf "\e[0;$1m$PKG_NAME: %s\e[0;0m\n" "$2"
}
success() {
color_out 32 "$1"
}
info() {
color_out 36 "$1"
}
err() {
color_out 31 "$1"
}
warn() {
color_out 33 "$1"
}
err_die() {
err "$1"
exit 1
}

View file

@ -1,62 +0,0 @@
#!/bin/sh
# not enabling `errtrace` and `pipefail` since those are bash specific
set -o errexit # failing commands causes script to fail
set -o nounset # undefined variables causes script to fail
echo "src/gz packages_ci file:///ci" >> /etc/opkg/distfeeds.conf
FINGERPRINT="$(usign -F -p /ci/packages_ci.pub)"
cp /ci/packages_ci.pub "/etc/opkg/keys/$FINGERPRINT"
mkdir -p /var/lock/
opkg update
[ -n "${CI_HELPER:=''}" ] || CI_HELPER="/ci/.github/workflows/ci_helpers.sh"
for PKG in /ci/*.ipk; do
tar -xzOf "$PKG" ./control.tar.gz | tar xzf - ./control
# package name including variant
PKG_NAME=$(sed -ne 's#^Package: \(.*\)$#\1#p' ./control)
# package version without release
PKG_VERSION=$(sed -ne 's#^Version: \(.*\)-[0-9]*$#\1#p' ./control)
# package source contianing test.sh script
PKG_SOURCE=$(sed -ne 's#^Source: .*/\(.*\)$#\1#p' ./control)
echo "Testing package $PKG_NAME in version $PKG_VERSION from $PKG_SOURCE"
export PKG_NAME PKG_VERSION CI_HELPER
PRE_TEST_SCRIPT=$(find /ci/ -name "$PKG_SOURCE" -type d)/pre-test.sh
if [ -f "$PRE_TEST_SCRIPT" ]; then
echo "Use package specific pre-test.sh"
if sh "$PRE_TEST_SCRIPT" "$PKG_NAME" "$PKG_VERSION"; then
echo "Pre-test successful"
else
echo "Pre-test failed"
exit 1
fi
else
echo "No pre-test.sh script available"
fi
opkg install "$PKG"
TEST_SCRIPT=$(find /ci/ -name "$PKG_SOURCE" -type d)/test.sh
if [ -f "$TEST_SCRIPT" ]; then
echo "Use package specific test.sh"
if sh "$TEST_SCRIPT" "$PKG_NAME" "$PKG_VERSION"; then
echo "Test succesful"
else
echo "Test failed"
exit 1
fi
else
echo "No test.sh script available"
fi
opkg remove "$PKG_NAME" --force-removal-of-dependent-packages --force-remove --autoremove || true
done

View file

@ -1,63 +0,0 @@
name: Test Formalities
on:
pull_request:
jobs:
build:
name: Test Formalities
runs-on: ubuntu-latest
strategy:
fail-fast: false
steps:
- uses: actions/checkout@v3
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
- name: Determine branch name
run: |
BRANCH="${GITHUB_BASE_REF#refs/heads/}"
echo "Building for $BRANCH"
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
- name: Test formalities
run: |
source .github/workflows/ci_helpers.sh
RET=0
for commit in $(git rev-list HEAD ^origin/$BRANCH); do
info "=== Checking commit '$commit'"
if git show --format='%P' -s $commit | grep -qF ' '; then
err "Pull request should not include merge commits"
RET=1
fi
author="$(git show -s --format=%aN $commit)"
if echo $author | grep -q '\S\+\s\+\S\+'; then
success "Author name ($author) seems ok"
else
err "Author name ($author) need to be your real name 'firstname lastname'"
RET=1
fi
subject="$(git show -s --format=%s $commit)"
if echo "$subject" | grep -q -e '^[0-9A-Za-z,+/_-]\+: ' -e '^Revert '; then
success "Commit subject line seems ok ($subject)"
else
err "Commit subject line MUST start with '<package name>: ' ($subject)"
RET=1
fi
body="$(git show -s --format=%b $commit)"
sob="$(git show -s --format='Signed-off-by: %aN <%aE>' $commit)"
if echo "$body" | grep -qF "$sob"; then
success "Signed-off-by match author"
else
err "Signed-off-by is missing or doesn't match author (should be '$sob')"
RET=1
fi
done
exit $RET

View file

@ -1,157 +0,0 @@
name: Test Build
on:
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
build:
name: Test ${{ matrix.arch }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- arch: aarch64_generic
target: armsr-armv8
runtime_test: true
- arch: arm_cortex-a15_neon-vfpv4
target: armsr-armv7
runtime_test: true
- arch: arm_cortex-a9_vfpv3-d16
target: mvebu-cortexa9
runtime_test: false
- arch: i386_pentium-mmx
target: x86-geode
runtime_test: true
- arch: mips_24kc
target: ath79-generic
runtime_test: true
- arch: powerpc_464fp
target: apm821xx-nand
runtime_test: false
- arch: powerpc_8548
target: mpc85xx-p1010
runtime_test: false
- arch: riscv64_riscv64
target: sifiveu-generic
runtime_test: false
- arch: x86_64
target: x86-64
runtime_test: true
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Determine branch name
run: |
BRANCH="${GITHUB_BASE_REF#refs/heads/}"
echo "Building for $BRANCH"
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
- name: Determine changed packages
run: |
# only detect packages with changes
PKG_ROOTS=$(find . -name Makefile | \
grep -v ".*/src/Makefile" | \
sed -e 's@./\(.*\)/Makefile@\1/@')
CHANGES=$(git diff --diff-filter=d --name-only origin/$BRANCH)
for ROOT in $PKG_ROOTS; do
for CHANGE in $CHANGES; do
if [[ "$CHANGE" == "$ROOT"* ]]; then
PACKAGES+=$(echo "$ROOT" | sed -e 's@\(.*\)/@\1 @')
break
fi
done
done
# fallback to test packages if nothing explicitly changes this is
# should run if other mechanics in packages.git changed
PACKAGES="${PACKAGES:-bird2 cjdns olsrd}"
echo "Building $PACKAGES"
echo "PACKAGES=$PACKAGES" >> $GITHUB_ENV
- name: Generate build keys
run: |
sudo apt-get update
sudo apt-get install -y signify-openbsd
signify-openbsd -G -n -c 'DO NOT USE - OpenWrt packages feed CI' -p packages_ci.pub -s packages_ci.sec
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "KEY_BUILD<<$EOF" >> $GITHUB_ENV
cat packages_ci.sec >> $GITHUB_ENV
echo "$EOF" >> $GITHUB_ENV
- name: Build
uses: openwrt/gh-action-sdk@v5
env:
ARCH: ${{ matrix.arch }}-${{ env.BRANCH }}
FEEDNAME: packages_ci
INDEX: 1
KEY_BUILD: ${{ env.KEY_BUILD }}
- name: Move created packages to project dir
run: cp bin/packages/${{ matrix.arch }}/packages_ci/* . || true
- name: Store packages
uses: actions/upload-artifact@v3
with:
name: ${{env.ARCHIVE_NAME}}-packages
path: |
Packages
Packages.*
*.ipk
PKG-INFO
- name: Store logs
uses: actions/upload-artifact@v3
with:
name: ${{ matrix.arch}}-logs
path: logs/
- name: Remove logs
run: sudo rm -rf logs/ || true
- name: Check if any packages were built
run: |
if [ -n "$(find . -maxdepth 1 -type f -name '*.ipk' -print -quit)" ]; then
echo "Found *.ipk files"
HAVE_IPKS=true
else
echo "No *.ipk files found"
HAVE_IPKS=false
fi
echo "HAVE_IPKS=$HAVE_IPKS" >> $GITHUB_ENV
- name: Register QEMU
if: ${{ matrix.runtime_test && fromJSON(env.HAVE_IPKS) }}
run: |
sudo apt-get update
sudo apt-get install -y qemu-user-static binfmt-support
sudo update-binfmts --import
- name: Build Docker container
if: ${{ matrix.runtime_test && fromJSON(env.HAVE_IPKS) }}
run: |
docker build -t test-container --build-arg ARCH .github/workflows/
env:
ARCH: ${{ matrix.arch }}-${{ env.BRANCH }}
- name: Test via Docker container
if: ${{ matrix.runtime_test && fromJSON(env.HAVE_IPKS) }}
run: |
docker run --rm -v $GITHUB_WORKSPACE:/ci test-container

18
README Normal file
View file

@ -0,0 +1,18 @@
This is an OpenWrt package feed containing community maintained routing packages.
To use these packages, add the following line to the feeds.conf
in the OpenWrt buildroot:
src-git routing git://github.com/openwrt-routing/packages.git
Update the feed:
./scripts/feeds update routing
Activate the package:
./scripts/feeds install -a -p routing
The routing packages should now appear in menuconfig.

View file

@ -1,21 +0,0 @@
# OpenWrt Routing Feed
## Description
This OpenWrt package feed contains community maintained routing packages.
## Usage
This repository is intended to be layered on-top of an OpenWrt buildroot.
If you do not have an OpenWrt buildroot installed, see the documentation at:
[OpenWrt Buildroot Installation][1] on the OpenWrt support site.
This feed is enabled by default. To install all its package definitions, run:
```
./scripts/feeds update routing
./scripts/feeds install -a -p routing
```
[1]: https://openwrt.org/docs/guide-developer/build-system/install-buildsystem

View file

@ -9,15 +9,13 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=ahcpd
PKG_VERSION:=0.53
PKG_RELEASE:=3
PKG_RELEASE:=2
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://www.irif.fr/~jch/software/files/
PKG_HASH:=a4622e817d2b2a9b878653f085585bd57f3838cc546cca6028d3b73ffcac0d52
PKG_MAINTAINER:=Gabriel Kerneis <gabriel@kerneis.info>
PKG_SOURCE_URL:=http://www.pps.univ-paris-diderot.fr/~jch/software/files/
PKG_MD5SUM:=a1a610bf20965aa522cd766bf3d5829a
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENCE
include $(INCLUDE_DIR)/package.mk
@ -25,7 +23,8 @@ define Package/ahcpd
SECTION:=net
CATEGORY:=Network
TITLE:=Ad-Hoc Configuration Protocol daemon
URL:=https://www.irif.fr/~jch/software/ahcp/
URL:=http://www.pps.univ-paris-diderot.fr/~jch/software/ahcp/
MAINTAINER:=Gabriel Kerneis <gabriel@kerneis.info>
DEPENDS:=@IPV6 +ip +librt
endef

View file

@ -1,45 +1,39 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2013 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=alfred
PKG_VERSION:=2024.0
PKG_RELEASE:=1
PKG_VERSION:=2018.1
PKG_RELEASE:=2
PKG_HASH:=808fa6acf65c7a8e26405115176a5587157f746108cbe5dd974788eb05416d76
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
PKG_HASH:=d029a43638ab16771e5f71e134bc843d1713d74041c65bcda18a31d18f5531bd
PKG_MAINTAINER:=Simon Wunderlich <sw@simonwunderlich.de>
PKG_LICENSE:=GPL-2.0-only MIT
PKG_LICENSE_FILES:=LICENSES/preferred/GPL-2.0 LICENSES/preferred/MIT
PKG_BUILD_PARALLEL:=1
PKG_BUILD_FLAGS:=gc-sections lto
PKG_CONFIG_DEPENDS += \
CONFIG_ALFRED_NEEDS_lua \
CONFIG_ALFRED_NEEDS_libgps \
CONFIG_PACKAGE_ALFRED_VIS \
CONFIG_PACKAGE_ALFRED_BATHOSTS \
CONFIG_PACKAGE_ALFRED_GPSD
PKG_LICENSE:=GPL-2.0
include $(INCLUDE_DIR)/package.mk
init-y := alfred
define Package/alfred
URL:=https://www.open-mesh.org/
SECTION:=net
CATEGORY:=Network
TITLE:=A.L.F.R.E.D. - Almighty Lightweight Fact Remote Exchange Daemon
URL:=https://www.open-mesh.org/
DEPENDS:= +libc @IPV6 +libnl-tiny +librt \
+ALFRED_NEEDS_lua:lua \
+ALFRED_NEEDS_libgps:libgps
endef
define Package/alfred/description
alfred is a user space daemon for distributing arbitrary local information
over the mesh/network in a decentralized fashion. This data can be anything
which appears to be useful - originally designed to replace the batman-adv
alfred is a user space daemon for distributing arbitrary local information over
the mesh/network in a decentralized fashion. This data can be anything which
appears to be useful - originally designed to replace the batman-adv
visualization (vis), you may distribute hostnames, phone books, administration
information, DNS information, the local weather forecast ...
@ -60,13 +54,22 @@ define Package/alfred/config
source "$(SOURCE)/Config.in"
endef
MAKE_FLAGS += \
MAKE_ALFRED_FLAGS=\
CONFIG_ALFRED_VIS=$(if $(CONFIG_PACKAGE_ALFRED_VIS),y,n) \
CONFIG_ALFRED_GPSD=$(if $(CONFIG_PACKAGE_ALFRED_GPSD),y,n) \
CONFIG_ALFRED_CAPABILITIES=n \
LIBNL_NAME="libnl-tiny" \
LIBNL_GENL_NAME="libnl-tiny" \
REVISION="$(PKG_VERSION)-openwrt-$(PKG_RELEASE)"
REVISION="openwrt-$(PKG_VERSION)-$(PKG_RELEASE)"
TARGET_CFLAGS += -ffunction-sections -fdata-sections -flto
TARGET_LDFLAGS += -Wl,--gc-sections -fuse-linker-plugin
define Build/Compile
CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS)" \
$(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_FLAGS) $(MAKE_ALFRED_FLAGS) all
endef
define Package/alfred/install
$(INSTALL_DIR) $(1)/usr/sbin

View file

@ -1,5 +1,5 @@
config 'alfred' 'alfred'
list interface 'br-lan'
option interface 'br-lan'
option mode 'master'
option batmanif 'bat0'
option start_vis '1'

View file

@ -1,41 +1,81 @@
#!/bin/sh /etc/rc.common
#
# Copyright (C) 2013 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
START=99
USE_PROCD=1
STOP=99
alfred_args=""
vis_args=""
facters_dir="/etc/alfred"
pid_file_alfred="/var/run/alfred.pid"
pid_file_vis="/var/run/batadv-vis.pid"
enable=0
vis_enable=0
SERVICE_DAEMONIZE=1
SERVICE_WRITE_PID=1
append_interface()
wait_for_dir()
{
append "interfaces" "$1" ","
local ifce="$1" dir="$2"
if ! [ -d "$dir" ] ; then
timeout=30
echo "${initscript}: waiting $timeout secs for $ifce interface..."
for i in $(seq $timeout); do
sleep 1
[ -d "$dir" ] && break
if [ $i == $timeout ] ; then
echo "${initscript}: $ifce not detected, alfred not starting."
exit 1
fi
done
fi
}
alfred_start() {
wait_for_ll_address()
{
local iface="$1"
local timeout=30
echo "${initscript}: waiting $timeout secs for $iface address..."
for i in $(seq $timeout); do
# We look for
# - the link-local address (starts with fe80)
# - without tentative flag (bit 0x40 in the flags field; the first char of the fifth field is evaluated)
# - on interface $iface
if awk '
BEGIN { RET=1 }
$1 ~ /^fe80/ && $5 ~ /^[012389ab]/ && $6 == "'"$iface"'" { RET=0 }
END { exit RET }
' /proc/net/if_inet6; then
return
fi
sleep 1
done
echo "${initscript}: $iface address not detected, alfred not starting."
exit 1
}
alfred_start()
{
local args=""
local section="$1"
local disabled interface mode
local interfaces
# check if section is disabled
config_get_bool disabled "$section" disabled 0
[ $disabled = 0 ] || return 1
args="-f"
args=""
config_list_foreach "$section" "interface" append_interface
if [ -z "$interfaces" ]; then
config_get interface "$section" interface
append_interface "$interface"
fi
append args "-i $interfaces"
append args "-i $interface"
config_get mode "$section" mode
[ "$mode" = "master" ] && append args "-m"
@ -43,6 +83,12 @@ alfred_start() {
config_get batmanif "$section" batmanif
append args "-b $batmanif"
if [ "$batmanif" != "none" ]; then
wait_for_dir "$batmanif" "/sys/class/net/$batmanif/mesh"
fi
wait_for_ll_address "$interface"
append alfred_args "$args"
enable=1
@ -57,41 +103,41 @@ alfred_start() {
return 0
}
start_service() {
start()
{
config_load "alfred"
config_foreach alfred_start alfred
[ "$enable" = "0" ] && return 0
if [ "$enable" = "0" ]; then
exit 0
fi
procd_open_instance "alfred"
procd_set_param command /usr/sbin/alfred
procd_append_param command ${alfred_args}
procd_close_instance
echo "${initscript}: starting alfred"
SERVICE_PID_FILE="$pid_file_alfred"
service_start /usr/sbin/alfred ${alfred_args}
[ "$vis_enable" = "1" ] && {
procd_open_instance "batadv-vis"
procd_set_param command /usr/sbin/batadv-vis
procd_append_param command ${vis_args}
procd_close_instance
}
if [ "$vis_enable" = "1" ]; then
echo "${initscript}: starting batadv-vis"
SERVICE_PID_FILE="$pid_file_vis"
service_start /usr/sbin/batadv-vis ${vis_args}
fi
[ "$run_facters" = "1" ] && {
if [ "$run_facters" = "1" ]; then
( for file in $facters_dir/* ; do [ -x $file ] && $file ; done )
if ! ( grep -q "for file in $facters_dir/\* ; do " /etc/crontabs/root 2>/dev/null ) ; then
echo "*/5 * * * * ( for file in $facters_dir/* ; do [ -x \$file ] && \$file ; done )" >> /etc/crontabs/root
/etc/init.d/cron enable
/etc/init.d/cron restart
fi
}
fi
}
service_triggers() {
procd_add_reload_trigger "alfred"
}
stop_service() {
[ -e /etc/crontabs/root ] && {
stop()
{
SERVICE_PID_FILE="$pid_file_alfred"
service_stop /usr/sbin/alfred
SERVICE_PID_FILE="$pid_file_vis"
[ -x /usr/sbin/batadv-vis ] && service_stop /usr/sbin/batadv-vis
sed "\|for file in $facters_dir/\* ; do |d" -i /etc/crontabs/root
/etc/init.d/cron restart
}
}

View file

@ -0,0 +1,37 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Mon, 29 Oct 2018 18:05:42 +0100
Subject: [PATCH] alfred: Fix detection of own packets for IPv4 mode
The incoming packet address is checked for a match against the local
interface addresses to avoid processing its own packets. The IPv4
implementation used the same code but only initialized 4 of the 16 bytes of
the address in the recv function. The interface initialization code in
netsock_set_interfaces set all unused bytes to zero but recv_alfred_packet
was modified to use 12 random bytes from the stack.
Both functions must work the same way and first set the address bytes to
zero and overwrite the actual used bytes with the address bytes. Otherwise,
the result of netsock_set_interfaces for own packets is random in the IPv4
implementation.
Fixes: c7da798113a2 ("alfred: IPv4 multicast distribution support.")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Tested-by: Jonathan Haws <jhaws@sdl.usu.edu>
Origin: upstream, https://git.open-mesh.org/alfred.git/commit/db842ed210d00345619e0ebc45a4d0d840e0b7e5
---
recv.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/recv.c b/recv.c
index 59d759cfba816d3dd7ed4a56fd3269730093bcfd..5ff4bb5df2354d7f2310e2105ee385b9365b0c4b 100644
--- a/recv.c
+++ b/recv.c
@@ -416,6 +416,7 @@ int recv_alfred_packet(struct globals *globals, struct interface *interface,
packet = (struct alfred_tlv *)buf;
+ memset(&alfred_source, 0, sizeof(alfred_source));
if (globals->ipv4mode) {
memcpy(&alfred_source, &source4.sin_addr, sizeof(source4.sin_addr));
} else {

View file

@ -0,0 +1,84 @@
From: Jonathan Haws <jhaws@sdl.usu.edu>
Date: Mon, 29 Oct 2018 11:57:59 -0600
Subject: [PATCH] alfred: Request MAC resolution for IPv4 address not in ARP cache
When using IPv4, if the remote server is not yet in the ARP cache, the
MAC resolution will fail and data appear to not be shared via alfred.
Add a routine (modified from batctl sources) to request MAC resolution
by simply sending a datagram to the discard port (UDP/9). This adds the
remote MAC to the ARP cache, resulting in successful MAC resolution.
Fixes: c7da798113a2 ("alfred: IPv4 multicast distribution support.")
Signed-off-by: Jonathan Haws <jhaws@sdl.usu.edu>
Tested-by: Gary Zou <guohuizou2000@sina.com>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/alfred.git/commit/5610d5bf8f4447b4d689aede638b4e92ae343340
---
util.c | 34 ++++++++++++++++++++++++++++++++--
1 file changed, 32 insertions(+), 2 deletions(-)
diff --git a/util.c b/util.c
index dd3f00fa6280d7de04a11acb8485c11cead3d0a4..07947929dfe2d5a22ca16f5bf33846d7365c771e 100644
--- a/util.c
+++ b/util.c
@@ -30,6 +30,7 @@
#include <sys/ioctl.h>
#include <sys/time.h>
#include <time.h>
+#include <unistd.h>
#include "alfred.h"
int time_diff(struct timespec *tv1, struct timespec *tv2,
@@ -80,11 +81,35 @@ bool is_valid_ether_addr(uint8_t addr[ETH_ALEN])
return true;
}
+static void ipv4_request_mac_resolve(const alfred_addr *addr)
+{
+ const struct sockaddr *sockaddr;
+ struct sockaddr_in inet4;
+ size_t sockaddr_len;
+ int sock;
+ char t = 0;
+
+ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock < 0)
+ return;
+
+ memset(&inet4, 0, sizeof(inet4));
+ inet4.sin_family = AF_INET;
+ inet4.sin_port = htons(9);
+ inet4.sin_addr.s_addr = addr->ipv4.s_addr;
+ sockaddr = (const struct sockaddr *)&inet4;
+ sockaddr_len = sizeof(inet4);
+
+ sendto(sock, &t, sizeof(t), 0, sockaddr, sockaddr_len);
+ close(sock);
+}
+
int ipv4_arp_request(struct interface *interface, const alfred_addr *addr,
struct ether_addr *mac)
{
struct arpreq arpreq;
struct sockaddr_in *sin;
+ int retries = 1;
memset(&arpreq, 0, sizeof(arpreq));
memset(mac, 0, ETH_ALEN);
@@ -96,8 +121,13 @@ int ipv4_arp_request(struct interface *interface, const alfred_addr *addr,
strncpy(arpreq.arp_dev, interface->interface, sizeof(arpreq.arp_dev));
arpreq.arp_dev[sizeof(arpreq.arp_dev) - 1] = '\0';
- if (ioctl(interface->netsock, SIOCGARP, &arpreq) < 0)
- return -1;
+ while ((ioctl(interface->netsock, SIOCGARP, &arpreq) < 0) || !(arpreq.arp_flags & ATF_COM)) {
+ ipv4_request_mac_resolve(addr);
+ usleep(200000);
+
+ if (retries-- == 0)
+ break;
+ }
if (arpreq.arp_flags & ATF_COM) {
memcpy(mac, arpreq.arp_ha.sa_data, sizeof(*mac));

View file

@ -10,7 +10,7 @@ PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://www.pps.univ-paris-diderot.fr/~jch/software/files/
PKG_HASH:=c411430bb102f08d3d68d2fb5010b5da0149908b671ac0fb12abd8c8ee6380c5
PKG_MD5SUM:=40d4931986913f5f8d9b5b70abf6fda5
include $(INCLUDE_DIR)/package.mk

View file

@ -1,23 +1,20 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Copyright (C) 2007-2021 OpenWrt.org
# Copyright (C) 2007-2009 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=babeld
PKG_VERSION:=1.13.1
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_HASH:=15f24d26da0ccfc073abcdef0309f281e4684f2aa71126f826572c4c845e8dd9
PKG_MAINTAINER:=Gabriel Kerneis <gabriel@kerneis.info>, \
Baptiste Jonglez <openwrt-pkg@bitsofnetworks.org>, \
Nick Hainke <vincent@systemli.org>
PKG_HASH:=202d99c275604507c6ce133710522f1ddfb62cb671c26f1ac2d3ab44af3d5bc4
PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENCE
include $(INCLUDE_DIR)/package.mk
@ -25,17 +22,21 @@ define Package/babeld
SECTION:=net
CATEGORY:=Network
SUBMENU:=Routing and Redirection
TITLE:=A loop-avoiding distance-vector routing protocol
TITLE:=A loop-free distance-vector routing protocol
URL:=https://www.irif.fr/~jch/software/babel/
DEPENDS:=@IPV6 +libubus +libubox
MAINTAINER:=Gabriel Kerneis <gabriel@kerneis.info>, \
Baptiste Jonglez <openwrt-pkg@bitsofnetworks.org>
DEPENDS:=@IPV6
endef
define Package/babeld/description
Babel is a loop-avoiding distance-vector routing protocol for IPv6 and IPv4
with fast convergence properties. It is based on the ideas in DSDV, AODV and
Cisco's EIGRP, but is designed to work well not only in wired networks but
also in wireless mesh networks, and has been extended with support for
overlay networks. Babel is an IETF standard protocol (RFC 8966).
Babel is a loop-avoiding distance-vector routing protocol roughly based
on DSDV and AODV, but with provisions for link cost estimation and
redistribution of routes from other routing protocols.
While it is optimised for wireless mesh networks, Babel will also work
efficiently on wired networks. It will generate between 1.2 and 2.4 times
the amount of routing traffic that RIPng would generate, while
never counting to infinity.
endef
define Package/babeld/conffiles
@ -46,7 +47,6 @@ endef
MAKE_FLAGS+= \
CFLAGS="$(TARGET_CFLAGS)" \
LDLIBS="" \
LDLIBS+="-lubus -lubox"
define Package/babeld/install
$(INSTALL_DIR) $(1)/usr/sbin

View file

@ -1,7 +1,5 @@
package babeld
# Detailed documentation: https://openwrt.org/docs/guide-user/services/babeld
# Babeld reads options from the following files (the last one takes precedence
# if an option is defined in several places):
# - the file defined by the option conf_file (default: /etc/babeld.conf),
@ -24,7 +22,6 @@ config general
## See comment at the top of this file for more details.
# option 'conf_file' '/etc/babeld.conf'
# option 'conf_dir' '/tmp/babel.d/'
# option 'ubus_bindings' 'false'
config interface
## Remove this line to enable babeld on this interface
@ -42,10 +39,7 @@ config interface
option 'ignore' 'true'
## Physical interface name
option 'ifname' 'tun-example'
## Specify the type of interface: tunnels use the RTT-based metric.
option 'type' 'tunnel'
## Other options that can be overriden.
# option 'max_rtt_penalty' '96'
# option 'max_rtt_penalty' '90'
# A config interface without "option ifname" will set default options
# for all interfaces. Interface-specific configuration always overrides
@ -55,49 +49,27 @@ config interface
# option 'update_interval' '30'
# A filter consists of a type ('in', 'out', 'redistribute' or 'install'),
# a set of selectors ('ip', 'eq', etc.) and a set of actions to perform
# ('allow', 'deny', 'metric xxx', 'src-prefix xxx', 'table xxx', 'pref-src xxx').
# See babeld man page ("Filtering rules") for more details.
# Below is a sample filter that redistributes the default route if its
# protocol number is "boot", e.g. when it is installed by dhcp (see
# /etc/iproute2/rt_protos). This filter is disabled thanks to the 'ignore'
# setting.
# A filter consists of a type ('in', 'out' or 'redistribute'), an action
# ('allow', 'deny' or 'metric xxx') and a set of selectors ('ip', 'eq',
# etc.). See babeld man page ("Filtering rules") for more details.
# Here is a sample filter wich redistributes the default route if its
# protocol number is "boot", e.g. when it installed by dhcp. It is
# disabled by default.
config filter
option 'ignore' 'true'
# Type of filter
# Type
option 'type' 'redistribute'
# Selectors: ip, eq, le, ge, src_ip, src_eq, src_le, src_ge, neigh, id,
# proto, local, if.
option 'ip' '0.0.0.0/0'
option 'eq' '0'
option 'proto' '3'
# Action, which can be any of: allow, deny, metric <NUMBER>, src-prefix <PREFIX>,
# table <ID>, pref-src <IP>.
# The action defaults to "allow" if not specified. Here, we specify a higher
# redistribution metric than the default (0).
# Action (one of: allow, deny, metric XXX, src-prefix XXX).
option 'action' 'metric 128'
# Another example filter: don't redistribute local addresses in a certain IP prefix.
# By default, babeld redistributes *all* local addresses.
# Notice that the 'local' selector is a boolean.
config filter
option 'ignore' 'true'
option 'type' 'redistribute'
# Only apply to routes/addresses within this prefix.
option 'ip' '198.51.100.0/24'
# Notice that the 'local' selector is a boolean.
option 'local' 'true'
# Don't redistribute.
option 'action' 'deny'
# Example install filter, to change or filter routes before they are inserted
# into the kernel.
config filter
option 'ignore' 'true'
option 'type' 'install'
# Optional: only apply to routes within 2001:db8:cafe::/48
option 'ip' '2001:db8:cafe::/48'
# We specify the kernel routing table and the preferred source address to use for these routes.
# "Allow" is implicit.
option 'action' 'table 200 pref-src 2001:db8:ba:be1::42'
# No action means "allow"

View file

@ -1,132 +0,0 @@
--- a/babeld.c
+++ b/babeld.c
@@ -54,6 +54,8 @@ THE SOFTWARE.
#include "local.h"
#include "version.h"
+#include "ubus.h"
+
struct timeval now;
unsigned char myid[8];
@@ -505,6 +507,9 @@ main(int argc, char **argv)
}
}
+ if(ubus_bindings)
+ babeld_add_ubus();
+
init_signals();
rc = resize_receive_buffer(1500);
if(rc < 0)
@@ -597,6 +602,8 @@ main(int argc, char **argv)
FD_SET(local_sockets[i].fd, &readfds);
maxfd = MAX(maxfd, local_sockets[i].fd);
}
+ if(ubus_bindings)
+ maxfd = babeld_ubus_add_read_sock(&readfds, maxfd);
rc = select(maxfd + 1, &readfds, NULL, NULL, &tv);
if(rc < 0) {
if(errno != EINTR) {
@@ -665,6 +672,9 @@ main(int argc, char **argv)
i++;
}
+ if(ubus_bindings)
+ babeld_ubus_receive(&readfds);
+
if(reopening) {
kernel_dump_time = now.tv_sec;
check_neighbours_timeout = now;
--- a/generate-version.sh
+++ b/generate-version.sh
@@ -10,4 +10,4 @@ else
version="unknown"
fi
-echo "#define BABELD_VERSION \"$version\""
+echo "#define BABELD_VERSION \"$version-ubus-mod\""
--- a/configuration.c
+++ b/configuration.c
@@ -42,6 +42,8 @@ THE SOFTWARE.
#include "hmac.h"
#include "configuration.h"
+#include "ubus.h"
+
static struct filter *input_filters = NULL;
static struct filter *output_filters = NULL;
static struct filter *redistribute_filters = NULL;
@@ -1024,7 +1026,8 @@ parse_option(int c, gnc_t gnc, void *clo
strcmp(token, "daemonise") == 0 ||
strcmp(token, "skip-kernel-setup") == 0 ||
strcmp(token, "ipv6-subtrees") == 0 ||
- strcmp(token, "reflect-kernel-metric") == 0) {
+ strcmp(token, "reflect-kernel-metric") == 0 ||
+ strcmp(token, "ubus-bindings") == 0) {
int b;
c = getbool(c, &b, gnc, closure);
if(c < -1)
@@ -1042,6 +1045,8 @@ parse_option(int c, gnc_t gnc, void *clo
has_ipv6_subtrees = b;
else if(strcmp(token, "reflect-kernel-metric") == 0)
reflect_kernel_metric = b;
+ else if(strcmp(token, "ubus-bindings") == 0)
+ ubus_bindings = b;
else
abort();
} else if(strcmp(token, "protocol-group") == 0) {
--- a/local.c
+++ b/local.c
@@ -42,6 +42,8 @@ THE SOFTWARE.
#include "local.h"
#include "version.h"
+#include "ubus.h"
+
int local_server_socket = -1;
struct local_socket local_sockets[MAX_LOCAL_SOCKETS];
int num_local_sockets = 0;
@@ -191,6 +193,8 @@ local_notify_neighbour(struct neighbour
if(local_sockets[i].monitor)
local_notify_neighbour_1(&local_sockets[i], neigh, kind);
}
+ if(ubus_bindings)
+ ubus_notify_neighbour(neigh, kind);
}
static void
@@ -228,6 +232,8 @@ local_notify_xroute(struct xroute *xrout
if(local_sockets[i].monitor)
local_notify_xroute_1(&local_sockets[i], xroute, kind);
}
+ if(ubus_bindings)
+ ubus_notify_xroute(xroute, kind);
}
static void
@@ -273,6 +279,8 @@ local_notify_route(struct babel_route *r
if(local_sockets[i].monitor)
local_notify_route_1(&local_sockets[i], route, kind);
}
+ if(ubus_bindings)
+ ubus_notify_route(route, kind);
}
static void
--- a/Makefile
+++ b/Makefile
@@ -11,11 +11,11 @@ LDLIBS = -lrt
SRCS = babeld.c net.c kernel.c util.c interface.c source.c neighbour.c \
route.c xroute.c message.c resend.c configuration.c local.c \
- hmac.c rfc6234/sha224-256.c BLAKE2/ref/blake2s-ref.c
+ hmac.c ubus.c rfc6234/sha224-256.c BLAKE2/ref/blake2s-ref.c
OBJS = babeld.o net.o kernel.o util.o interface.o source.o neighbour.o \
route.o xroute.o message.o resend.o configuration.o local.o \
- hmac.o rfc6234/sha224-256.o BLAKE2/ref/blake2s-ref.o
+ hmac.o ubus.o rfc6234/sha224-256.o BLAKE2/ref/blake2s-ref.o
babeld: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o babeld $(OBJS) $(LDLIBS)

View file

@ -1,535 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
#include <sys/select.h>
#include <libubox/blob.h>
#include <libubox/blobmsg.h>
#include <libubox/list.h>
#include <libubus.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include "babeld.h"
#include "configuration.h"
#include "interface.h"
#include "kernel.h"
#include "local.h"
#include "message.h"
#include "neighbour.h"
#include "net.h"
#include "resend.h"
#include "route.h"
#include "source.h"
#include "util.h"
#include "version.h"
#include "xroute.h"
#include "ubus.h"
// Definition of header variable whether to enable ubus bindings.
int ubus_bindings = 0;
// Shared state maintained throughout calls to handle ubus messages.
static struct ubus_context *shared_ctx;
// List of exported routes (to be used with ubox's list helpers).
struct xroute_list_entry {
struct list_head list;
struct xroute *xroute;
};
// List of received routes (to be used with ubox's list helpers).
struct route_list_entry {
struct list_head list;
struct babel_route *route;
};
// List of neighbours (to be used with ubox's list helpers).
struct neighbour_list_entry {
struct list_head list;
struct neighbour *neighbour;
};
// Definition of interface function enums (to be used with ubox's blobmsg
// helpers).
enum { INTERFACE_IFNAME, __INTERFACE_MAX };
// Definition of interface parsing (to be used with ubox's blobmsg helpers).
static const struct blobmsg_policy interface_policy[__INTERFACE_MAX] = {
[INTERFACE_IFNAME] = {"ifname", BLOBMSG_TYPE_STRING},
};
// Definition of filter function enums (to be used with ubox's blobmsg
// helpers).
enum { FILTER_IFNAME, FILTER_TYPE, FILTER_METRIC, __FILTER_MAX };
// Definition of filter parsing (to be used with ubox's blobmsg helpers).
static const struct blobmsg_policy filter_policy[__FILTER_MAX] = {
[FILTER_IFNAME] = {"ifname", BLOBMSG_TYPE_STRING},
[FILTER_TYPE] = {"type", BLOBMSG_TYPE_INT32},
[FILTER_METRIC] = {"metric", BLOBMSG_TYPE_INT32},
};
// Adds a filter (ubus equivalent to "filter"-function).
static int babeld_ubus_add_filter(struct ubus_context *ctx_local,
struct ubus_object *obj,
struct ubus_request_data *req,
const char *method, struct blob_attr *msg) {
struct blob_attr *tb[__FILTER_MAX];
struct blob_buf b = {0};
struct filter *filter = NULL;
char *ifname;
int metric, type;
blobmsg_parse(filter_policy, __FILTER_MAX, tb, blob_data(msg), blob_len(msg));
if (!tb[FILTER_IFNAME])
return UBUS_STATUS_INVALID_ARGUMENT;
if (!tb[FILTER_TYPE])
return UBUS_STATUS_INVALID_ARGUMENT;
type = blobmsg_get_u32(tb[FILTER_TYPE]);
if (tb[FILTER_METRIC])
metric = blobmsg_get_u32(tb[FILTER_METRIC]);
filter = calloc(1, sizeof(struct filter));
if (filter == NULL)
return UBUS_STATUS_UNKNOWN_ERROR;
filter->af = AF_INET6;
filter->proto = 0;
filter->plen_le = 128;
filter->src_plen_le = 128;
filter->action.add_metric = metric;
ifname = blobmsg_get_string(tb[FILTER_IFNAME]);
filter->ifname = strdup(ifname);
filter->ifindex = if_nametoindex(filter->ifname);
add_filter(filter, type);
return UBUS_STATUS_OK;
}
// Adds an inteface (ubus equivalent to "interface"-function).
static int babeld_ubus_add_interface(struct ubus_context *ctx_local,
struct ubus_object *obj,
struct ubus_request_data *req,
const char *method,
struct blob_attr *msg) {
struct blob_attr *tb[__INTERFACE_MAX];
struct blob_buf b = {0};
struct interface *ifp = NULL;
char *ifname;
blobmsg_parse(interface_policy, __INTERFACE_MAX, tb, blob_data(msg),
blob_len(msg));
if (!tb[INTERFACE_IFNAME])
return UBUS_STATUS_INVALID_ARGUMENT;
ifname = blobmsg_get_string(tb[INTERFACE_IFNAME]);
ifp = add_interface(ifname, NULL);
if (ifp == NULL)
return UBUS_STATUS_UNKNOWN_ERROR;
return UBUS_STATUS_OK;
}
// Sends a babel info message on ubus socket.
static int babeld_ubus_babeld_info(struct ubus_context *ctx_local,
struct ubus_object *obj,
struct ubus_request_data *req,
const char *method, struct blob_attr *msg) {
struct blob_buf b = {0};
void *prefix;
char host[64];
int ret;
blob_buf_init(&b, 0);
blobmsg_add_string(&b, "babeld-version", BABELD_VERSION);
blobmsg_add_string(&b, "my-id", format_eui64(myid));
if (!gethostname(host, sizeof(host)))
blobmsg_add_string(&b, "host", host);
ret = ubus_send_reply(ctx_local, req, b.head);
if (ret)
fprintf(stderr, "Failed to send reply: %s\n", ubus_strerror(ret));
blob_buf_free(&b);
return ret;
}
// Appends an exported route message entry to the buffer.
static void babeld_add_xroute_buf(struct xroute *xroute, struct blob_buf *b) {
void *prefix;
prefix = blobmsg_open_table(b, format_prefix(xroute->prefix, xroute->plen));
blobmsg_add_string(b, "src-prefix",
format_prefix(xroute->src_prefix, xroute->src_plen));
blobmsg_add_u32(b, "metric", xroute->metric);
blobmsg_close_table(b, prefix);
}
// Sends an exported routes message on ubus socket, splitting apart IPv4 and
// IPv6 routes.
static int babeld_ubus_get_xroutes(struct ubus_context *ctx_local,
struct ubus_object *obj,
struct ubus_request_data *req,
const char *method, struct blob_attr *msg) {
struct blob_buf b = {0};
struct xroute_stream *xroutes;
struct xroute_list_entry *cur, *tmp;
void *ipv4, *ipv6;
int ret;
LIST_HEAD(xroute_ipv4_list);
LIST_HEAD(xroute_ipv6_list);
blob_buf_init(&b, 0);
xroutes = xroute_stream();
if (xroutes) {
while (1) {
struct xroute *xroute = xroute_stream_next(xroutes);
if (xroute == NULL)
break;
struct xroute_list_entry *xr =
calloc(1, sizeof(struct xroute_list_entry));
xr->xroute = xroute;
if (v4mapped(xroute->prefix)) {
list_add(&xr->list, &xroute_ipv4_list);
} else {
list_add(&xr->list, &xroute_ipv6_list);
}
}
xroute_stream_done(xroutes);
}
ipv4 = blobmsg_open_table(&b, "IPv4");
list_for_each_entry_safe(cur, tmp, &xroute_ipv4_list, list) {
babeld_add_xroute_buf(cur->xroute, &b);
list_del(&cur->list);
free(cur);
}
blobmsg_close_table(&b, ipv4);
ipv6 = blobmsg_open_table(&b, "IPv6");
list_for_each_entry_safe(cur, tmp, &xroute_ipv6_list, list) {
babeld_add_xroute_buf(cur->xroute, &b);
list_del(&cur->list);
free(cur);
}
blobmsg_close_table(&b, ipv6);
ret = ubus_send_reply(ctx_local, req, b.head);
if (ret)
fprintf(stderr, "Failed to send reply: %s\n", ubus_strerror(ret));
blob_buf_free(&b);
return ret;
}
// Appends an route message entry to the buffer.
static void babeld_add_route_buf(struct babel_route *route,
struct blob_buf *b) {
void *prefix;
prefix = blobmsg_open_table(
b, format_prefix(route->src->prefix, route->src->plen));
blobmsg_add_string(
b, "src-prefix",
format_prefix(route->src->src_prefix, route->src->src_plen));
blobmsg_add_u32(b, "route_metric", route_metric(route));
blobmsg_add_u32(b, "route_smoothed_metric", route_smoothed_metric(route));
blobmsg_add_u32(b, "refmetric", route->refmetric);
blobmsg_add_string(b, "id", format_eui64(route->src->id));
blobmsg_add_u32(b, "seqno", (uint32_t)route->seqno);
blobmsg_add_u32(b, "age", (int)(now.tv_sec - route->time));
blobmsg_add_string(b, "via", format_address(route->neigh->address));
if (memcmp(route->nexthop, route->neigh->address, 16) != 0)
blobmsg_add_string(b, "nexthop", format_address(route->nexthop));
blobmsg_add_u8(b, "installed", route->installed);
blobmsg_add_u8(b, "feasible", route_feasible(route));
blobmsg_close_table(b, prefix);
}
// Sends received routes message on ubus socket, splitting apart IPv4 and IPv6
// routes.
static int babeld_ubus_get_routes(struct ubus_context *ctx_local,
struct ubus_object *obj,
struct ubus_request_data *req,
const char *method, struct blob_attr *msg) {
struct blob_buf b = {0};
struct route_stream *routes;
struct route_list_entry *cur, *tmp;
void *prefix, *ipv4, *ipv6;
int ret;
LIST_HEAD(route_ipv4_list);
LIST_HEAD(route_ipv6_list);
blob_buf_init(&b, 0);
routes = route_stream(0);
if (routes) {
while (1) {
struct babel_route *route = route_stream_next(routes);
if (route == NULL)
break;
struct route_list_entry *r = calloc(1, sizeof(struct route_list_entry));
r->route = route;
if (v4mapped(route->src->prefix)) {
list_add(&r->list, &route_ipv4_list);
} else {
list_add(&r->list, &route_ipv6_list);
}
}
route_stream_done(routes);
}
ipv4 = blobmsg_open_table(&b, "IPv4");
list_for_each_entry_safe(cur, tmp, &route_ipv4_list, list) {
babeld_add_route_buf(cur->route, &b);
list_del(&cur->list);
free(cur);
}
blobmsg_close_table(&b, ipv4);
ipv6 = blobmsg_open_table(&b, "IPv6");
list_for_each_entry_safe(cur, tmp, &route_ipv6_list, list) {
babeld_add_route_buf(cur->route, &b);
list_del(&cur->list);
free(cur);
}
blobmsg_close_table(&b, ipv6);
ret = ubus_send_reply(ctx_local, req, b.head);
if (ret)
fprintf(stderr, "Failed to send reply: %s\n", ubus_strerror(ret));
blob_buf_free(&b);
return ret;
}
// Appends an neighbour entry to the buffer.
static void babeld_add_neighbour_buf(struct neighbour *neigh,
struct blob_buf *b) {
void *neighbour;
neighbour = blobmsg_open_table(b, format_address(neigh->address));
blobmsg_add_string(b, "dev", neigh->ifp->name);
blobmsg_add_u32(b, "hello-reach", neigh->hello.reach);
blobmsg_add_u32(b, "uhello-reach", neigh->uhello.reach);
blobmsg_add_u32(b, "rxcost", neighbour_rxcost(neigh));
blobmsg_add_u32(b, "txcost", neigh->txcost);
blobmsg_add_string(b, "rtt", format_thousands(neigh->rtt));
blobmsg_add_u8(b, "if_up", if_up(neigh->ifp));
blobmsg_close_table(b, neighbour);
}
// Sends neighbours message on ubus socket, splitting apart IPv4 and IPv6
// neighbours.
static int babeld_ubus_get_neighbours(struct ubus_context *ctx_local,
struct ubus_object *obj,
struct ubus_request_data *req,
const char *method,
struct blob_attr *msg) {
struct blob_buf b = {0};
struct neighbour *neigh;
struct neighbour_list_entry *cur, *tmp;
void *ipv4, *ipv6;
int ret;
LIST_HEAD(neighbour_ipv4_list);
LIST_HEAD(neighbour_ipv6_list);
blob_buf_init(&b, 0);
FOR_ALL_NEIGHBOURS(neigh) {
struct neighbour_list_entry *n =
calloc(1, sizeof(struct neighbour_list_entry));
n->neighbour = neigh;
if (v4mapped(neigh->address)) {
list_add(&n->list, &neighbour_ipv4_list);
} else {
list_add(&n->list, &neighbour_ipv6_list);
}
}
ipv4 = blobmsg_open_table(&b, "IPv4");
list_for_each_entry_safe(cur, tmp, &neighbour_ipv4_list, list) {
babeld_add_neighbour_buf(cur->neighbour, &b);
list_del(&cur->list);
free(cur);
}
blobmsg_close_table(&b, ipv4);
ipv6 = blobmsg_open_table(&b, "IPv6");
list_for_each_entry_safe(cur, tmp, &neighbour_ipv6_list, list) {
babeld_add_neighbour_buf(cur->neighbour, &b);
list_del(&cur->list);
free(cur);
}
blobmsg_close_table(&b, ipv6);
ret = ubus_send_reply(ctx_local, req, b.head);
if (ret)
fprintf(stderr, "Failed to send reply: %s\n", ubus_strerror(ret));
blob_buf_free(&b);
return ret;
}
// List of functions we expose via the ubus bus.
static const struct ubus_method babeld_methods[] = {
UBUS_METHOD("add_interface", babeld_ubus_add_interface, interface_policy),
UBUS_METHOD("add_filter", babeld_ubus_add_filter, filter_policy),
UBUS_METHOD_NOARG("get_info", babeld_ubus_babeld_info),
UBUS_METHOD_NOARG("get_xroutes", babeld_ubus_get_xroutes),
UBUS_METHOD_NOARG("get_routes", babeld_ubus_get_routes),
UBUS_METHOD_NOARG("get_neighbours", babeld_ubus_get_neighbours),
};
// Definition of the ubus object type.
static struct ubus_object_type babeld_object_type =
UBUS_OBJECT_TYPE("babeld", babeld_methods);
// Object we announce via the ubus bus.
static struct ubus_object babeld_object = {
.name = "babeld",
.type = &babeld_object_type,
.methods = babeld_methods,
.n_methods = ARRAY_SIZE(babeld_methods),
};
// Registers handlers for babel methods in the global ubus context.
static bool ubus_init_object() {
int ret;
ret = ubus_add_object(shared_ctx, &babeld_object);
if (ret) {
fprintf(stderr, "Failed to add object: %s\n", ubus_strerror(ret));
return false;
}
return true;
}
// Initializes the global ubus context, connecting to the bus to be able to
// receive and send messages.
static bool babeld_ubus_init(void) {
if (shared_ctx)
return true;
shared_ctx = ubus_connect(NULL);
if (!shared_ctx)
return false;
return true;
}
void ubus_notify_route(struct babel_route *route, int kind) {
struct blob_buf b = {0};
char method[50]; // possible methods are route.change, route.add, route.flush
if (!babeld_object.has_subscribers)
return;
if (!route)
return;
if (!shared_ctx)
return;
blob_buf_init(&b, 0);
babeld_add_route_buf(route, &b);
snprintf(method, sizeof(method), "route.%s", local_kind(kind));
ubus_notify(shared_ctx, &babeld_object, method, b.head, -1);
blob_buf_free(&b);
}
void ubus_notify_xroute(struct xroute *xroute, int kind) {
struct blob_buf b = {0};
char method[50]; // possible methods are xroute.change, xroute.add,
// xroute.flush
if (!babeld_object.has_subscribers)
return;
if (!xroute)
return;
if (!shared_ctx)
return;
blob_buf_init(&b, 0);
babeld_add_xroute_buf(xroute, &b);
snprintf(method, sizeof(method), "xroute.%s", local_kind(kind));
ubus_notify(shared_ctx, &babeld_object, method, b.head, -1);
blob_buf_free(&b);
}
void ubus_notify_neighbour(struct neighbour *neigh, int kind) {
struct blob_buf b = {0};
char method[50]; // possible methods are neigh.change, neigh.add, neigh.flush
if (!babeld_object.has_subscribers)
return;
if (!neigh)
return;
if (!shared_ctx)
return;
blob_buf_init(&b, 0);
babeld_add_neighbour_buf(neigh, &b);
snprintf(method, sizeof(method), "neigh.%s", local_kind(kind));
ubus_notify(shared_ctx, &babeld_object, method, b.head, -1);
blob_buf_free(&b);
}
void babeld_ubus_receive(fd_set *readfds) {
if (!shared_ctx)
return;
if (FD_ISSET(shared_ctx->sock.fd, readfds))
ubus_handle_event(shared_ctx);
}
int babeld_ubus_add_read_sock(fd_set *readfds, int maxfd) {
if (!shared_ctx)
return maxfd;
FD_SET(shared_ctx->sock.fd, readfds);
return MAX(maxfd, shared_ctx->sock.fd);
}
bool babeld_add_ubus() {
if (!babeld_ubus_init()) {
fprintf(stderr, "Failed to initialize ubus!\n");
return false;
}
if (!ubus_init_object()) {
fprintf(stderr, "Failed to add objects to ubus!\n");
return false;
}
return true;
}

View file

@ -1,99 +0,0 @@
/*
IPC integration of babeld with OpenWrt.
The ubus interface offers following functions:
- add_filter '{"ifname":"eth0", "type":0, "metric":5000}'
type:
0: FILTER_TYPE_INPUT
1: FILTER_TYPE_OUTPUT
2: FILTER_TYPE_REDISTRIBUTE
3: FILTER_TYPE_INSTALL
- add_interface '{"ifname":"eth0"}'
- get_info
- get_neighbours
- get_xroutes
- get_routes
All output is divided into IPv4 and IPv6.
Ubus notifications are sent if we receive updates for
- xroutes
- routes
- neighbours
The format is:
- {route,xroute,neighbour}.add: Object was added
- {route,xroute,neighbour}.change: Object was changed
- {route,xroute,neighbour}.flush: Object was flushed
*/
#include <stdbool.h>
#include <sys/select.h>
struct babel_route;
struct neighbour;
struct xroute;
// Whether to enable ubus bindings (boolean option).
extern int ubus_bindings;
/**
* Initialize ubus interface.
*
* Connect to the ubus daemon and expose the ubus functions.
*
* @return if initializing ubus was successful
*/
bool babeld_add_ubus();
/**
* Add ubus socket to given filedescriptor set.
*
* We need to check repeatedly if the ubus socket has something to read.
* The functions allows to add the ubus socket to the normal while(1)-loop of
* babeld.
*
* @param readfs: the filedescriptor set
* @param maxfd: the current maximum file descriptor
* @return the maximum file descriptor
*/
int babeld_ubus_add_read_sock(fd_set *readfds, int maxfd);
/**
* Check and process ubus socket.
*
* If the ubus-socket signals that data is available, the ubus_handle_event is
* called.
*/
void babeld_ubus_receive(fd_set *readfds);
/***
* Notify the ubus bus that a new xroute is received.
*
* If a new xroute is received or changed, we will notify subscribers.
*
* @param xroute: xroute that experienced some change
* @param kind: kind that describes if we have a flush, add or change
*/
void ubus_notify_xroute(struct xroute *xroute, int kind);
/***
* Notify the ubus bus that a new route is received.
*
* If a new route is received or changed, we will notify subscribers.
*
* @param route: route that experienced some change
* @param kind: kind that describes if we have a flush, add or change
*/
void ubus_notify_route(struct babel_route *route, int kind);
/***
* Notify the ubus bus that a new neighbour is received.
*
* If a new neighbour is received or changed, we will notify subscribers.
*
* @param neigh: neighbour that experienced some change
* @param kind: kind that describes if we have a flush, add or change
*/
void ubus_notify_neighbour(struct neighbour *neigh, int kind);

View file

@ -1,31 +1,31 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2014 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=batctl
PKG_VERSION:=2024.0
PKG_RELEASE:=1
PKG_VERSION:=2018.1
PKG_RELEASE:=4
PKG_HASH:=27877d0da6916f88a6cecbbb3f3d23cc4558ef7c7294324bf4fd050ed606b553
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
PKG_HASH:=76853e87201af63c411db152fd0c625a729a9733115897d1331604e2c5a67c7d
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_MAINTAINER:=Simon Wunderlich <sw@simonwunderlich.de>
PKG_LICENSE:=GPL-2.0-only ISC MIT
PKG_LICENSE_FILES:=LICENSES/preferred/GPL-2.0 LICENSES/preferred/MIT LICENSES/deprecated/ISC
PKG_BUILD_PARALLEL:=1
PKG_BUILD_FLAGS:=gc-sections lto
PKG_LICENSE:=GPL-2.0
include $(INCLUDE_DIR)/package.mk
define Package/batctl/Default
define Package/batctl
URL:=https://www.open-mesh.org/
SECTION:=net
CATEGORY:=Network
URL:=https://www.open-mesh.org/
DEPENDS:=+libnl-tiny +libc +librt
PROVIDES:=batctl
DEPENDS:=+kmod-batman-adv +libnl-tiny +libc +librt
TITLE:=B.A.T.M.A.N. Advanced user space configuration tool batctl
MAINTAINER:=Simon Wunderlich <sw@simonwunderlich.de>
endef
define Package/batctl/description
@ -35,214 +35,46 @@ define Package/batctl/description
version $(PKG_VERSION) of the user space utility.
endef
define Package/batctl-tiny
$(call Package/batctl/Default)
TITLE:=B.A.T.M.A.N. Advanced user space configuration tool (Minimal)
VARIANT:=tiny
ALTERNATIVES:=100:/usr/sbin/batctl:/usr/libexec/batctl-tiny
endef
# The linker can identify unused sections of a binary when each symbol is stored
# in a separate section. This mostly removes unused linker sections and reduces
# the size by ~3% on mipsel.
define Package/batctl-tiny/description
$(Package/batctl/description)
Only configuration relevant subcommands are enabled.
endef
TARGET_CFLAGS += -ffunction-sections -fdata-sections
TARGET_LDFLAGS += -Wl,--gc-sections
define Package/batctl-default
$(call Package/batctl/Default)
TITLE:=B.A.T.M.A.N. Advanced user space configuration tool (Default)
VARIANT:=default
ALTERNATIVES:=200:/usr/sbin/batctl:/usr/libexec/batctl-default
endef
# Link-time optimization allows to move parts of the optimization from the single
# source file to the global source view. This is done by emitting the GIMPLE
# representation in each object file and analyzing it again during the link step.
define Package/batctl-default/description
$(Package/batctl/description)
Standard subcommands for configuration and online debugging are enabled.
endef
TARGET_CFLAGS += -flto
TARGET_LDFLAGS += -fuse-linker-plugin
define Package/batctl-full
$(call Package/batctl/Default)
TITLE:=B.A.T.M.A.N. Advanced user space configuration tool (Full)
VARIANT:=full
ALTERNATIVES:=300:/usr/sbin/batctl:/usr/libexec/batctl-full
endef
define Package/batctl-full/description
$(Package/batctl/description)
Subcommands for configuration, online and offline debugging are enabled.
endef
MAKE_VARS += \
MAKE_BATCTL_ENV += \
CPPFLAGS="$(TARGET_CPPFLAGS)" \
CFLAGS="$(TARGET_CFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS)" \
LIBNL_NAME="libnl-tiny" \
LIBNL_GENL_NAME="libnl-tiny"
MAKE_FLAGS += \
REVISION="$(PKG_VERSION)-openwrt-$(PKG_RELEASE)"
MAKE_BATCTL_ARGS += \
REVISION="$(PKG_BATCTL_SHORTREV)" \
CC="$(TARGET_CC)" \
DESTDIR="$(PKG_INSTALL_DIR)" \
batctl install \
REVISION="openwrt-$(PKG_VERSION)-$(PKG_RELEASE)"
config-n := \
aggregation \
ap_isolation \
backbonetable \
bisect_iv \
bonding \
bla_backbone_json \
bla_claim_json \
bridge_loop_avoidance \
claimtable \
dat_cache \
dat_cache_json \
distributed_arp_table \
elp_interval \
event \
fragmentation \
gateways \
gateways_json \
gw_mode \
hardif_json \
hardifs_json \
hop_penalty \
interface \
isolation_mark \
loglevel \
mcast_flags \
mcast_flags_json \
mesh_json \
multicast_fanout \
multicast_forceflood \
multicast_mode \
neighbors \
neighbors_json \
network_coding \
orig_interval \
originators \
originators_json \
ping \
routing_algo \
statistics \
tcpdump \
throughput_override \
throughputmeter \
traceroute \
transglobal \
translate \
translocal \
transtable_global_json \
transtable_local_json \
vlan_json \
config-settings := \
aggregation \
ap_isolation \
bonding \
bridge_loop_avoidance \
distributed_arp_table \
elp_interval \
fragmentation \
gw_mode \
hop_penalty \
interface \
isolation_mark \
loglevel \
multicast_fanout \
multicast_forceflood \
multicast_mode \
network_coding \
orig_interval \
routing_algo \
throughput_override \
config-tables := \
backbonetable \
claimtable \
dat_cache \
gateways \
mcast_flags \
neighbors \
originators \
statistics \
transglobal \
translocal \
config-json := \
bla_backbone_json \
bla_claim_json \
dat_cache_json \
gateways_json \
hardif_json \
hardifs_json \
mcast_flags_json \
mesh_json \
neighbors_json \
originators_json \
transtable_global_json \
transtable_local_json \
vlan_json \
config-tools := \
event \
ping \
tcpdump \
throughputmeter \
traceroute \
translate \
config-extratools := \
bisect_iv \
ifeq ($(BUILD_VARIANT),tiny)
config-y := \
$(config-settings) \
endif
ifeq ($(BUILD_VARIANT),default)
config-y := \
$(config-settings) \
$(config-tables) \
$(config-json) \
$(config-tools) \
endif
ifeq ($(BUILD_VARIANT),full)
config-y := \
$(config-settings) \
$(config-tables) \
$(config-json) \
$(config-tools) \
$(config-extratools) \
endif
define ConfigVars
$(subst $(space),,$(foreach opt,$(config-$(1)),CONFIG_$(opt)=$(1)
))
define Build/Compile
$(MAKE_BATCTL_ENV) $(MAKE) -C "$(PKG_BUILD_DIR)" $(MAKE_BATCTL_ARGS)
endef
define batctl_config
$(call ConfigVars,n)$(call ConfigVars,y)
endef
$(eval $(call shexport,batctl_config))
MAKE_FLAGS += $$$$$(call shvar,batctl_config)
define Package/batctl-tiny/install
$(INSTALL_DIR) $(1)/usr/libexec
$(INSTALL_BIN) $(PKG_BUILD_DIR)/batctl $(1)/usr/libexec/batctl-tiny
define Build/Clean
rm -rf $(BUILD_DIR)/$(PKG_NAME)/
endef
define Package/batctl-default/install
$(INSTALL_DIR) $(1)/usr/libexec
$(INSTALL_BIN) $(PKG_BUILD_DIR)/batctl $(1)/usr/libexec/batctl-default
define Package/batctl/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/batctl $(1)/usr/sbin/
endef
define Package/batctl-full/install
$(INSTALL_DIR) $(1)/usr/libexec
$(INSTALL_BIN) $(PKG_BUILD_DIR)/batctl $(1)/usr/libexec/batctl-full
endef
$(eval $(call BuildPackage,batctl-default))
$(eval $(call BuildPackage,batctl-tiny))
$(eval $(call BuildPackage,batctl-full))
$(eval $(call BuildPackage,batctl))

View file

@ -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");

View file

@ -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;

View file

@ -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);
}

View file

@ -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",

View file

@ -1,88 +1,36 @@
# SPDX-License-Identifier: GPL-2.0
# Copyright (C) 2007-2019 B.A.T.M.A.N. contributors:
#
# Marek Lindner, Simon Wunderlich
#
# B.A.T.M.A.N meshing protocol
#
config KMOD_BATMAN_ADV_DEBUG_LOG
bool "enable verbose debug logging"
depends on PACKAGE_kmod-batman-adv
depends on KMOD_BATMAN_ADV_DEBUGFS
default n
config BATMAN_ADV_BATMAN_V
bool "B.A.T.M.A.N. V protocol"
config KMOD_BATMAN_ADV_BLA
bool "enable bridge loop avoidance"
depends on PACKAGE_kmod-batman-adv
default y
help
This option enables the B.A.T.M.A.N. V protocol, the successor
of the currently used B.A.T.M.A.N. IV protocol. The main
changes include splitting of the OGM protocol into a neighbor
discovery protocol (Echo Location Protocol, ELP) and a new OGM
Protocol OGMv2 for flooding protocol information through the
network, as well as a throughput based metric.
B.A.T.M.A.N. V is currently considered experimental and not
compatible to B.A.T.M.A.N. IV networks.
config BATMAN_ADV_BLA
bool "Bridge Loop Avoidance"
depends on PACKAGE_kmod-batman-adv
select PACKAGE_kmod-lib-crc16
default y
help
This option enables BLA (Bridge Loop Avoidance), a mechanism
to avoid Ethernet frames looping when mesh nodes are connected
to both the same LAN and the same mesh. If you will never use
more than one mesh node in the same LAN, you can safely remove
this feature and save some space.
config BATMAN_ADV_DAT
bool "Distributed ARP Table"
config KMOD_BATMAN_ADV_DAT
bool "enable distributed arp table"
depends on PACKAGE_kmod-batman-adv
default y
help
This option enables DAT (Distributed ARP Table), a DHT based
mechanism that increases ARP reliability on sparse wireless
mesh networks. If you think that your network does not need
this option you can safely remove it and save some space.
config BATMAN_ADV_NC
bool "Network Coding"
depends on PACKAGE_kmod-batman-adv
help
This option enables network coding, a mechanism that aims to
increase the overall network throughput by fusing multiple
packets in one transmission.
Note that interfaces controlled by batman-adv must be manually
configured to have promiscuous mode enabled in order to make
network coding work.
If you think that your network does not need this feature you
can safely disable it and save some space.
config BATMAN_ADV_MCAST
bool "Multicast optimisation"
config KMOD_BATMAN_ADV_DEBUGFS
bool "enable debugfs support"
depends on PACKAGE_kmod-batman-adv
default y
help
This option enables the multicast optimisation which aims to
reduce the air overhead while improving the reliability of
multicast messages.
config BATMAN_ADV_DEBUG
bool "B.A.T.M.A.N. debugging"
config KMOD_BATMAN_ADV_MCAST
bool "enable multicast transmission optimization"
depends on PACKAGE_kmod-batman-adv
help
This is an option for use by developers; most people should
say N here. This enables compilation of support for
outputting debugging information to the debugfs log or tracing
buffer. The output is controlled via the batadv netdev specific
log_level setting.
default y
config BATMAN_ADV_TRACING
bool "B.A.T.M.A.N. tracing support"
config KMOD_BATMAN_ADV_NC
bool "enable network coding [requires promisc mode support]"
depends on PACKAGE_kmod-batman-adv
select KERNEL_FTRACE
select KERNEL_ENABLE_DEFAULT_TRACERS
help
This is an option for use by developers; most people should
say N here. Select this option to gather traces like the debug
messages using the generic tracing infrastructure of the kernel.
BATMAN_ADV_DEBUG must also be selected to get trace events for
batadv_dbg.
default n
config KMOD_BATMAN_ADV_BATMAN_V
bool "enable batman v routing algorithm"
depends on PACKAGE_kmod-batman-adv
default y

View file

@ -1,52 +1,42 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2010 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=batman-adv
PKG_VERSION:=2024.0
PKG_RELEASE:=2
PKG_VERSION:=2018.1
PKG_RELEASE:=13
PKG_HASH:=b866b28dbbe5c9238abbdf5abbc30fc526dea56898ce4c1bd76d5c017843048b
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://downloads.open-mesh.org/batman/releases/batman-adv-$(PKG_VERSION)
PKG_HASH:=61110697b5799f646a2a82a4dcf97faed4bb12a7cc43bf4683d2c4de4f6b40e7
PKG_EXTMOD_SUBDIRS:=net/batman-adv
PKG_MAINTAINER:=Simon Wunderlich <sw@simonwunderlich.de>
PKG_LICENSE:=GPL-2.0-only MIT
PKG_LICENSE_FILES:=LICENSES/preferred/GPL-2.0 LICENSES/preferred/MIT
PKG_BUILD_PARALLEL:=1
PKG_LICENSE:=GPL-2.0
PKG_EXTMOD_SUBDIRS=net/batman-adv
STAMP_CONFIGURED_DEPENDS := $(STAGING_DIR)/usr/include/mac80211-backport/backport/autoconf.h
PKG_CONFIG_DEPENDS += \
CONFIG_BATMAN_ADV_BATMAN_V \
CONFIG_BATMAN_ADV_BLA \
CONFIG_BATMAN_ADV_DAT \
CONFIG_BATMAN_ADV_NC \
CONFIG_BATMAN_ADV_MCAST \
CONFIG_BATMAN_ADV_DEBUG \
CONFIG_BATMAN_ADV_TRACING
include $(INCLUDE_DIR)/kernel.mk
include $(INCLUDE_DIR)/package.mk
define KernelPackage/batman-adv
SUBMENU:=Network Support
TITLE:=B.A.T.M.A.N. Adv
URL:=https://www.open-mesh.org/
DEPENDS:=+BATMAN_ADV_BLA:kmod-lib-crc16 +kmod-lib-crc32c +kmod-cfg80211 +batctl
MAINTAINER:=Simon Wunderlich <sw@simonwunderlich.de>
SUBMENU:=Network Support
DEPENDS:=+KMOD_BATMAN_ADV_BLA:kmod-lib-crc16 +kmod-crypto-crc32c +kmod-lib-crc32c +kmod-cfg80211
TITLE:=B.A.T.M.A.N. Adv
FILES:=$(PKG_BUILD_DIR)/net/batman-adv/batman-adv.$(LINUX_KMOD_SUFFIX)
AUTOLOAD:=$(call AutoProbe,batman-adv)
endef
define KernelPackage/batman-adv/description
B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is
a routing protocol for multi-hop ad-hoc mesh networks. The
networks may be wired or wireless. See
https://www.open-mesh.org/ for more information and user space
tools. This package builds version $(PKG_VERSION) of the kernel
module.
B.A.T.M.A.N. advanced is a kernel module which allows to
build layer 2 mesh networks. This package builds
version $(PKG_VERSION) of the kernel module.
endef
define KernelPackage/batman-adv/config
@ -59,43 +49,62 @@ endef
PKG_EXTRA_KCONFIG:= \
CONFIG_BATMAN_ADV=m \
CONFIG_BATMAN_ADV_DEBUG=$(if $(CONFIG_BATMAN_ADV_DEBUG),y,n) \
CONFIG_BATMAN_ADV_BLA=$(if $(CONFIG_BATMAN_ADV_BLA),y,n) \
CONFIG_BATMAN_ADV_DAT=$(if $(CONFIG_BATMAN_ADV_DAT),y,n) \
CONFIG_BATMAN_ADV_MCAST=$(if $(CONFIG_BATMAN_ADV_MCAST),y,n) \
CONFIG_BATMAN_ADV_NC=$(if $(CONFIG_BATMAN_ADV_NC),y,n) \
CONFIG_BATMAN_ADV_BATMAN_V=$(if $(CONFIG_BATMAN_ADV_BATMAN_V),y,n) \
CONFIG_BATMAN_ADV_TRACING=$(if $(CONFIG_BATMAN_ADV_TRACING),y,n) \
CONFIG_BATMAN_ADV_DEBUG=$(if $(CONFIG_KMOD_BATMAN_ADV_DEBUG_LOG),y,n) \
CONFIG_BATMAN_ADV_DEBUGFS=$(if $(CONFIG_KMOD_BATMAN_ADV_DEBUGFS),y,n) \
CONFIG_BATMAN_ADV_BLA=$(if $(CONFIG_KMOD_BATMAN_ADV_BLA),y,n) \
CONFIG_BATMAN_ADV_DAT=$(if $(CONFIG_KMOD_BATMAN_ADV_DAT),y,n) \
CONFIG_BATMAN_ADV_MCAST=$(if $(CONFIG_KMOD_BATMAN_ADV_MCAST),y,n) \
CONFIG_BATMAN_ADV_NC=$(if $(CONFIG_KMOD_BATMAN_ADV_NC),y,n) \
CONFIG_BATMAN_ADV_BATMAN_V=$(if $(CONFIG_KMOD_BATMAN_ADV_BATMAN_V),y,n) \
PKG_EXTRA_CFLAGS:= \
$(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=m,%,$(filter %=m,$(PKG_EXTRA_KCONFIG)))) \
$(patsubst CONFIG_%, -DCONFIG_%=1, $(patsubst %=y,%,$(filter %=y,$(PKG_EXTRA_KCONFIG)))) \
NOSTDINC_FLAGS = \
$(KERNEL_NOSTDINC_FLAGS) \
-I$(PKG_BUILD_DIR)/net/batman-adv \
-I$(STAGING_DIR)/usr/include/mac80211-backport \
-I$(STAGING_DIR)/usr/include/mac80211-backport/uapi \
-I$(STAGING_DIR)/usr/include/mac80211 \
-I$(STAGING_DIR)/usr/include/mac80211/uapi \
-I$(PKG_BUILD_DIR)/include/ \
-include backport/autoconf.h \
-include backport/backport.h \
-include $(PKG_BUILD_DIR)/compat-hacks.h \
-DBATADV_SOURCE_VERSION=\\\"$(PKG_VERSION)-openwrt-$(PKG_RELEASE)\\\"
-DBATADV_SOURCE_VERSION=\\\"openwrt-$(PKG_VERSION)-$(PKG_RELEASE)\\\"
COMPAT_SOURCES = \
$(if $(CONFIG_KMOD_BATMAN_ADV_MCAST),../../compat-sources/net/core/skbuff.o,) \
$(if $(CONFIG_KMOD_BATMAN_ADV_MCAST),../../compat-sources/net/ipv4/igmp.o,) \
$(if $(CONFIG_KMOD_BATMAN_ADV_MCAST),../../compat-sources/net/ipv6/mcast_snoop.o,) \
define Build/Compile
+env "batman-adv-y=$(COMPAT_SOURCES)" \
$(MAKE) $(PKG_JOBS) -C "$(LINUX_DIR)" \
$(KERNEL_MAKE_FLAGS) \
M="$(PKG_BUILD_DIR)/net/batman-adv" \
ARCH="$(LINUX_KARCH)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
SUBDIRS="$(PKG_BUILD_DIR)/net/batman-adv" \
$(PKG_EXTRA_KCONFIG) \
EXTRA_CFLAGS="$(PKG_EXTRA_CFLAGS)" \
NOSTDINC_FLAGS="$(NOSTDINC_FLAGS)" \
modules
endef
define Build/Prepare
$(call Build/Prepare/Default)
$(CP) ./files/compat-hacks.h $(PKG_BUILD_DIR)/
endef
define Build/Clean
rm -rf $(BUILD_DIR)/$(PKG_NAME)/
endef
define KernelPackage/batman-adv/install
$(CP) ./files/. $(1)/
$(INSTALL_DIR) $(1)/etc/config $(1)/etc/hotplug.d/net $(1)/etc/hotplug.d/iface $(1)/lib/batman-adv $(1)/usr/sbin $(1)/lib/netifd/proto
$(INSTALL_DATA) ./files/etc/config/batman-adv $(1)/etc/config
$(INSTALL_DATA) ./files/lib/batman-adv/config.sh $(1)/lib/batman-adv
$(INSTALL_BIN) ./files/etc/hotplug.d/net/99-batman-adv $(1)/etc/hotplug.d/net
$(INSTALL_BIN) ./files/lib/netifd/proto/batadv.sh $(1)/lib/netifd/proto
$(INSTALL_BIN) ./files/lib/netifd/proto/batadv_vlan.sh $(1)/lib/netifd/proto
endef
$(eval $(call KernelPackage,batman-adv))

View file

@ -0,0 +1,440 @@
/* Please avoid adding hacks here - instead add it to mac80211/backports.git */
#undef CONFIG_MODULE_STRIPPED
#include <linux/version.h> /* LINUX_VERSION_CODE */
#include <linux/types.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0)
#define dev_get_iflink(_net_dev) ((_net_dev)->iflink)
#endif /* < KERNEL_VERSION(4, 1, 0) */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0)
/* Linux 3.15 misses the uapi include.... */
#include <uapi/linux/nl80211.h>
#endif /* < KERNEL_VERSION(3, 16, 0) */
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0)
#include <linux/netdevice.h>
#define netdev_master_upper_dev_link(dev, upper_dev, upper_priv, upper_info, extack) ({\
BUILD_BUG_ON(upper_priv != NULL); \
BUILD_BUG_ON(upper_info != NULL); \
BUILD_BUG_ON(extack != NULL); \
netdev_set_master(dev, upper_dev); \
})
#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
#include <linux/netdevice.h>
#define netdev_master_upper_dev_link(dev, upper_dev, upper_priv, upper_info, extack) ({\
BUILD_BUG_ON(upper_priv != NULL); \
BUILD_BUG_ON(upper_info != NULL); \
BUILD_BUG_ON(extack != NULL); \
netdev_master_upper_dev_link(dev, upper_dev); \
})
#elif LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
#include <linux/netdevice.h>
#define netdev_master_upper_dev_link(dev, upper_dev, upper_priv, upper_info, extack) ({\
BUILD_BUG_ON(extack != NULL); \
netdev_master_upper_dev_link(dev, upper_dev, upper_priv, upper_info); \
})
#endif /* < KERNEL_VERSION(4, 5, 0) */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0)
/* for batadv_v_elp_get_throughput which would have used
* STATION_INFO_EXPECTED_THROUGHPUT in Linux 4.0.0
*/
#define NL80211_STA_INFO_EXPECTED_THROUGHPUT 28
/* wild hack for batadv_getlink_net only */
#define get_link_net get_xstats_size || 1 ? fallback_net : (struct net*)netdev->rtnl_link_ops->get_xstats_size
#endif /* < KERNEL_VERSION(4, 0, 0) */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0)
struct sk_buff *skb_checksum_trimmed(struct sk_buff *skb,
unsigned int transport_len,
__sum16(*skb_chkf)(struct sk_buff *skb));
int ip_mc_check_igmp(struct sk_buff *skb, struct sk_buff **skb_trimmed);
int ipv6_mc_check_mld(struct sk_buff *skb, struct sk_buff **skb_trimmed);
#endif /* < KERNEL_VERSION(4, 2, 0) */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 3, 0)
#define IFF_NO_QUEUE 0; dev->tx_queue_len = 0
static inline bool hlist_fake(struct hlist_node *h)
{
return h->pprev == &h->next;
}
#endif /* < KERNEL_VERSION(4, 3, 0) */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0)
#include <linux/ethtool.h>
#define ethtool_link_ksettings batadv_ethtool_link_ksettings
struct batadv_ethtool_link_ksettings {
struct {
__u32 speed;
__u8 duplex;
} base;
};
#define __ethtool_get_link_ksettings(__dev, __link_settings) \
batadv_ethtool_get_link_ksettings(__dev, __link_settings)
static inline int
batadv_ethtool_get_link_ksettings(struct net_device *dev,
struct ethtool_link_ksettings *link_ksettings)
{
struct ethtool_cmd cmd;
int ret;
memset(&cmd, 0, sizeof(cmd));
ret = __ethtool_get_settings(dev, &cmd);
if (ret != 0)
return ret;
link_ksettings->base.duplex = cmd.duplex;
link_ksettings->base.speed = ethtool_cmd_speed(&cmd);
return 0;
}
#endif /* < KERNEL_VERSION(4, 6, 0) */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)
#ifdef netif_trans_update
#undef netif_trans_update
#endif
#define netif_trans_update batadv_netif_trans_update
static inline void batadv_netif_trans_update(struct net_device *dev)
{
dev->trans_start = jiffies;
}
#endif /* < KERNEL_VERSION(4, 7, 0) */
#include_next <linux/netlink.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 7, 0)
#include_next <net/netlink.h>
static inline bool batadv_nla_need_padding_for_64bit(struct sk_buff *skb);
static inline int batadv_nla_align_64bit(struct sk_buff *skb, int padattr)
{
if (batadv_nla_need_padding_for_64bit(skb) &&
!nla_reserve(skb, padattr, 0))
return -EMSGSIZE;
return 0;
}
static inline struct nlattr *batadv__nla_reserve_64bit(struct sk_buff *skb,
int attrtype,
int attrlen, int padattr)
{
if (batadv_nla_need_padding_for_64bit(skb))
batadv_nla_align_64bit(skb, padattr);
return __nla_reserve(skb, attrtype, attrlen);
}
static inline void batadv__nla_put_64bit(struct sk_buff *skb, int attrtype,
int attrlen, const void *data,
int padattr)
{
struct nlattr *nla;
nla = batadv__nla_reserve_64bit(skb, attrtype, attrlen, padattr);
memcpy(nla_data(nla), data, attrlen);
}
static inline bool batadv_nla_need_padding_for_64bit(struct sk_buff *skb)
{
#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
/* The nlattr header is 4 bytes in size, that's why we test
* if the skb->data _is_ aligned. A NOP attribute, plus
* nlattr header for next attribute, will make nla_data()
* 8-byte aligned.
*/
if (IS_ALIGNED((unsigned long)skb_tail_pointer(skb), 8))
return true;
#endif
return false;
}
static inline int batadv_nla_total_size_64bit(int payload)
{
return NLA_ALIGN(nla_attr_size(payload))
#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
+ NLA_ALIGN(nla_attr_size(0))
#endif
;
}
static inline int batadv_nla_put_64bit(struct sk_buff *skb, int attrtype,
int attrlen, const void *data,
int padattr)
{
size_t len;
if (batadv_nla_need_padding_for_64bit(skb))
len = batadv_nla_total_size_64bit(attrlen);
else
len = nla_total_size(attrlen);
if (unlikely(skb_tailroom(skb) < len))
return -EMSGSIZE;
batadv__nla_put_64bit(skb, attrtype, attrlen, data, padattr);
return 0;
}
#ifdef nla_put_u64_64bit
#undef nla_put_u64_64bit
#endif
#define nla_put_u64_64bit(_skb, _attrtype, _value, _padattr) \
batadv_nla_put_u64_64bit(_skb, _attrtype, _value, _padattr)
static inline int batadv_nla_put_u64_64bit(struct sk_buff *skb, int attrtype,
u64 value, int padattr)
{
return batadv_nla_put_64bit(skb, attrtype, sizeof(u64), &value,
padattr);
}
#endif /* < KERNEL_VERSION(4, 7, 0) */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
#include_next <linux/cache.h>
/* hack for netlink.c which marked the family ops as ro */
#ifdef __ro_after_init
#undef __ro_after_init
#endif
#define __ro_after_init
#endif /* < KERNEL_VERSION(4, 10, 0) */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 9)
#include <linux/netdevice.h>
/* work around missing attribute needs_free_netdev and priv_destructor in
* net_device
*/
#define ether_setup(dev) \
void batadv_softif_free2(struct net_device *dev) \
{ \
batadv_softif_free(dev); \
free_netdev(dev); \
} \
void (*t1)(struct net_device *dev) __attribute__((unused)); \
bool t2 __attribute__((unused)); \
ether_setup(dev)
#define needs_free_netdev destructor = batadv_softif_free2; t2
#define priv_destructor destructor = batadv_softif_free2; t1
#endif /* < KERNEL_VERSION(4, 11, 9) */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 13, 0)
static inline void *batadv_skb_put(struct sk_buff *skb, unsigned int len)
{
return (void *)skb_put(skb, len);
}
#ifdef skb_put
#undef skb_put
#endif
#define skb_put batadv_skb_put
static inline void *batadv_skb_put_zero(struct sk_buff *skb, unsigned int len)
{
void *tmp = skb_put(skb, len);
memset(tmp, 0, len);
return tmp;
}
#ifdef skb_put_zero
#undef skb_put_zero
#endif
#define skb_put_zero batadv_skb_put_zero
static inline void *batadv_skb_put_data(struct sk_buff *skb, const void *data,
unsigned int len)
{
void *tmp = skb_put(skb, len);
memcpy(tmp, data, len);
return tmp;
}
#ifdef skb_put_data
#undef skb_put_data
#endif
#define skb_put_data batadv_skb_put_data
#endif /* < KERNEL_VERSION(4, 13, 0) */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
#define batadv_softif_slave_add(__dev, __slave_dev, __extack) \
batadv_softif_slave_add(__dev, __slave_dev)
#endif /* < KERNEL_VERSION(4, 15, 0) */
#ifndef from_timer
#define TIMER_DATA_TYPE unsigned long
#define TIMER_FUNC_TYPE void (*)(TIMER_DATA_TYPE)
static inline void timer_setup(struct timer_list *timer,
void (*callback)(struct timer_list *),
unsigned int flags)
{
__setup_timer(timer, (TIMER_FUNC_TYPE)callback,
(TIMER_DATA_TYPE)timer, flags);
}
#define from_timer(var, callback_timer, timer_fieldname) \
container_of(callback_timer, typeof(*var), timer_fieldname)
#endif /* !from_timer */
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 16, 0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 18, 0)
#include <net/cfg80211.h>
/* cfg80211 fix: https://patchwork.kernel.org/patch/10449857/ */
static inline int batadv_cfg80211_get_station(struct net_device *dev,
const u8 *mac_addr,
struct station_info *sinfo)
{
memset(sinfo, 0, sizeof(*sinfo));
return cfg80211_get_station(dev, mac_addr, sinfo);
}
#define cfg80211_get_station(dev, mac_addr, sinfo) \
batadv_cfg80211_get_station(dev, mac_addr, sinfo)
#endif /* < KERNEL_VERSION(4, 18, 0) */
#ifdef __CHECK_POLL
typedef unsigned __bitwise __poll_t;
#else
typedef unsigned __poll_t;
#endif
#endif /* < KERNEL_VERSION(4, 16, 0) */
/* <DECLARE_EWMA> */
#include <linux/version.h>
#include_next <linux/average.h>
#include <linux/bug.h>
#ifdef DECLARE_EWMA
#undef DECLARE_EWMA
#endif /* DECLARE_EWMA */
/*
* Exponentially weighted moving average (EWMA)
*
* This implements a fixed-precision EWMA algorithm, with both the
* precision and fall-off coefficient determined at compile-time
* and built into the generated helper funtions.
*
* The first argument to the macro is the name that will be used
* for the struct and helper functions.
*
* The second argument, the precision, expresses how many bits are
* used for the fractional part of the fixed-precision values.
*
* The third argument, the weight reciprocal, determines how the
* new values will be weighed vs. the old state, new values will
* get weight 1/weight_rcp and old values 1-1/weight_rcp. Note
* that this parameter must be a power of two for efficiency.
*/
#define DECLARE_EWMA(name, _precision, _weight_rcp) \
struct ewma_##name { \
unsigned long internal; \
}; \
static inline void ewma_##name##_init(struct ewma_##name *e) \
{ \
BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
/* \
* Even if you want to feed it just 0/1 you should have \
* some bits for the non-fractional part... \
*/ \
BUILD_BUG_ON((_precision) > 30); \
BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
e->internal = 0; \
} \
static inline unsigned long \
ewma_##name##_read(struct ewma_##name *e) \
{ \
BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
BUILD_BUG_ON((_precision) > 30); \
BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
return e->internal >> (_precision); \
} \
static inline void ewma_##name##_add(struct ewma_##name *e, \
unsigned long val) \
{ \
unsigned long internal = READ_ONCE(e->internal); \
unsigned long weight_rcp = ilog2(_weight_rcp); \
unsigned long precision = _precision; \
\
BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
BUILD_BUG_ON((_precision) > 30); \
BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
\
WRITE_ONCE(e->internal, internal ? \
(((internal << weight_rcp) - internal) + \
(val << precision)) >> weight_rcp : \
(val << precision)); \
}
/* </DECLARE_EWMA> */

View file

@ -0,0 +1,20 @@
config 'mesh' 'bat0'
option 'aggregated_ogms'
option 'ap_isolation'
option 'bonding'
option 'fragmentation'
option 'gw_bandwidth'
option 'gw_mode'
option 'gw_sel_class'
option 'log_level'
option 'orig_interval'
option 'bridge_loop_avoidance'
option 'distributed_arp_table'
option 'multicast_mode'
option 'network_coding'
option 'hop_penalty'
option 'isolation_mark'
# yet another batX instance
# config 'mesh' 'bat5'

View file

@ -0,0 +1,12 @@
#!/bin/sh
. /lib/batman-adv/config.sh
bat_load_module
config_load batman-adv
case "$ACTION" in
add)
[ -d /sys/class/net/$INTERFACE/mesh/ ] && bat_config "$INTERFACE"
;;
esac

View file

@ -1,97 +0,0 @@
#!/bin/sh
# This UCI-Defaults script will split the batadv proto network interfaces
# in batadv_hardif and batadv proto. The configuration options from
# /etc/config/batman-adv will be moved to the latter.
. /lib/functions.sh
proto_batadv_to_batadv_hardif() {
local section="$1"
local proto
local mesh
local routing_algo
config_get proto "${section}" proto
config_get mesh "${section}" mesh
config_get routing_algo "${section}" routing_algo
if [ -z "$mesh" -o "${proto}" != "batadv" ]; then
continue
fi
uci set network."${section}".proto="batadv_hardif"
uci rename network."${section}".mesh="master"
uci delete network."${section}".routing_algo
# create new section or adjust existing one
uci set network."${mesh}"=interface
uci set network."${mesh}".proto=batadv
[ -n "${routing_algo}" ] && uci set network."${mesh}".routing_algo="${routing_algo}"
}
mv_batadv_config_section() {
local section="$1"
local aggregated_ogms
local ap_isolation
local bonding
local bridge_loop_avoidance
local distributed_arp_table
local fragmentation
local gw_bandwidth
local gw_mode
local gw_sel_class
local hop_penalty
local isolation_mark
local log_level
local multicast_mode
local network_coding
local orig_interval
config_get aggregated_ogms "${section}" aggregated_ogms
config_get ap_isolation "${section}" ap_isolation
config_get bonding "${section}" bonding
config_get bridge_loop_avoidance "${section}" bridge_loop_avoidance
config_get distributed_arp_table "${section}" distributed_arp_table
config_get fragmentation "${section}" fragmentation
config_get gw_bandwidth "${section}" gw_bandwidth
config_get gw_mode "${section}" gw_mode
config_get gw_sel_class "${section}" gw_sel_class
config_get hop_penalty "${section}" hop_penalty
config_get isolation_mark "${section}" isolation_mark
config_get log_level "${section}" log_level
config_get multicast_mode "${section}" multicast_mode
config_get network_coding "${section}" network_coding
config_get orig_interval "${section}" orig_interval
# update section in case it exists
[ -n "${aggregated_ogms}" ] && uci set network."${section}".aggregated_ogms="${aggregated_ogms}"
[ -n "${ap_isolation}" ] && uci set network."${section}".ap_isolation="${ap_isolation}"
[ -n "${bonding}" ] && uci set network."${section}".bonding="${bonding}"
[ -n "${bridge_loop_avoidance}" ] && uci set network."${section}".bridge_loop_avoidance="${bridge_loop_avoidance}"
[ -n "${distributed_arp_table}" ] && uci set network."${section}".distributed_arp_table="${distributed_arp_table}"
[ -n "${fragmentation}" ] && uci set network."${section}".fragmentation="${fragmentation}"
[ -n "${gw_bandwidth}" ] && uci set network."${section}".gw_bandwidth="${gw_bandwidth}"
[ -n "${gw_mode}" ] && uci set network."${section}".gw_mode="${gw_mode}"
[ -n "${gw_sel_class}" ] && uci set network."${section}".gw_sel_class="${gw_sel_class}"
[ -n "${hop_penalty}" ] && uci set network."${section}".hop_penalty="${hop_penalty}"
[ -n "${isolation_mark}" ] && uci set network."${section}".isolation_mark="${isolation_mark}"
[ -n "${log_level}" ] && uci set network."${section}".log_level="${log_level}"
[ -n "${multicast_mode}" ] && uci set network."${section}".multicast_mode="${multicast_mode}"
[ -n "${network_coding}" ] && uci set network."${section}".network_coding="${network_coding}"
[ -n "${orig_interval}" ] && uci set network."${section}".orig_interval="${orig_interval}"
}
if [ -f /etc/config/batman-adv ]; then
config_load network
config_foreach proto_batadv_to_batadv_hardif 'interface'
uci commit network
config_load batman-adv
config_foreach mv_batadv_config_section 'mesh'
uci commit network
rm -f /etc/config/batman-adv
fi
exit 0

View file

@ -0,0 +1,51 @@
#!/bin/sh
bat_load_module()
{
[ -d "/sys/module/batman_adv/" ] && return
. /lib/functions.sh
load_modules /etc/modules.d/*-crc16 /etc/modules.d/*-crypto* /etc/modules.d/*-lib-crc* /etc/modules.d/*-batman-adv*
}
bat_config()
{
local mesh="$1"
local aggregated_ogms ap_isolation bonding bridge_loop_avoidance distributed_arp_table fragmentation
local gw_bandwidth gw_mode gw_sel_class isolation_mark hop_penalty multicast_mode network_coding log_level
local orig_interval
config_get aggregated_ogms "$mesh" aggregated_ogms
config_get ap_isolation "$mesh" ap_isolation
config_get bonding "$mesh" bonding
config_get bridge_loop_avoidance "$mesh" bridge_loop_avoidance
config_get distributed_arp_table "$mesh" distributed_arp_table
config_get fragmentation "$mesh" fragmentation
config_get gw_bandwidth "$mesh" gw_bandwidth
config_get gw_mode "$mesh" gw_mode
config_get gw_sel_class "$mesh" gw_sel_class
config_get hop_penalty "$mesh" hop_penalty
config_get isolation_mark "$mesh" isolation_mark
config_get multicast_mode "$mesh" multicast_mode
config_get network_coding "$mesh" network_coding
config_get log_level "$mesh" log_level
config_get orig_interval "$mesh" orig_interval
[ ! -f "/sys/class/net/$mesh/mesh/orig_interval" ] && echo "batman-adv mesh $mesh does not exist - check your interface configuration" && return 1
[ -n "$aggregated_ogms" ] && echo $aggregated_ogms > /sys/class/net/$mesh/mesh/aggregated_ogms
[ -n "$ap_isolation" ] && echo $ap_isolation > /sys/class/net/$mesh/mesh/ap_isolation
[ -n "$bonding" ] && echo $bonding > /sys/class/net/$mesh/mesh/bonding
[ -n "$bridge_loop_avoidance" ] && echo $bridge_loop_avoidance > /sys/class/net/$mesh/mesh/bridge_loop_avoidance 2>&-
[ -n "$distributed_arp_table" ] && echo $distributed_arp_table > /sys/class/net/$mesh/mesh/distributed_arp_table 2>&-
[ -n "$fragmentation" ] && echo $fragmentation > /sys/class/net/$mesh/mesh/fragmentation
[ -n "$gw_bandwidth" ] && echo $gw_bandwidth > /sys/class/net/$mesh/mesh/gw_bandwidth
[ -n "$gw_mode" ] && echo $gw_mode > /sys/class/net/$mesh/mesh/gw_mode
[ -n "$gw_sel_class" ] && echo $gw_sel_class > /sys/class/net/$mesh/mesh/gw_sel_class
[ -n "$hop_penalty" ] && echo $hop_penalty > /sys/class/net/$mesh/mesh/hop_penalty
[ -n "$isolation_mark" ] && echo $isolation_mark > /sys/class/net/$mesh/mesh/isolation_mark
[ -n "$multicast_mode" ] && echo $multicast_mode > /sys/class/net/$mesh/mesh/multicast_mode 2>&-
[ -n "$network_coding" ] && echo $network_coding > /sys/class/net/$mesh/mesh/network_coding 2>&-
[ -n "$log_level" ] && echo $log_level > /sys/class/net/$mesh/mesh/log_level 2>&-
[ -n "$orig_interval" ] && echo $orig_interval > /sys/class/net/$mesh/mesh/orig_interval
}

109
batman-adv/files/lib/netifd/proto/batadv.sh Executable file → Normal file
View file

@ -1,123 +1,34 @@
#!/bin/sh
[ -n "$INCLUDE_ONLY" ] || {
. /lib/functions.sh
. ../netifd-proto.sh
init_proto "$@"
}
proto_batadv_init_config() {
no_device=1
available=1
proto_config_add_boolean 'aggregated_ogms:bool'
proto_config_add_boolean 'ap_isolation:bool'
proto_config_add_boolean 'bonding:bool'
proto_config_add_boolean 'bridge_loop_avoidance:bool'
proto_config_add_boolean 'distributed_arp_table:bool'
proto_config_add_boolean 'fragmentation:bool'
proto_config_add_string 'gw_bandwidth'
proto_config_add_string 'gw_mode'
proto_config_add_int 'gw_sel_class'
proto_config_add_int 'hop_penalty'
proto_config_add_string 'isolation_mark'
proto_config_add_string 'log_level'
proto_config_add_int 'multicast_fanout'
proto_config_add_boolean 'multicast_mode:bool'
proto_config_add_boolean 'network_coding:bool'
proto_config_add_int 'orig_interval'
proto_config_add_string 'routing_algo'
proto_config_add_string "mesh"
proto_config_add_string "routing_algo"
}
proto_batadv_setup() {
local config="$1"
local iface="$config"
local iface="$2"
local aggregated_ogms
local ap_isolation
local bonding
local bridge_loop_avoidance
local distributed_arp_table
local fragmentation
local gw_bandwidth
local gw_mode
local gw_sel_class
local hop_penalty
local isolation_mark
local log_level
local multicast_fanout
local multicast_mode
local network_coding
local orig_interval
local routing_algo
local mesh routing_algo
json_get_vars mesh routing_algo
json_get_vars aggregated_ogms
json_get_vars ap_isolation
json_get_vars bonding
json_get_vars bridge_loop_avoidance
json_get_vars distributed_arp_table
json_get_vars fragmentation
json_get_vars gw_bandwidth
json_get_vars gw_mode
json_get_vars gw_sel_class
json_get_vars hop_penalty
json_get_vars isolation_mark
json_get_vars log_level
json_get_vars multicast_fanout
json_get_vars multicast_mode
json_get_vars network_coding
json_get_vars orig_interval
json_get_vars routing_algo
set_default routing_algo 'BATMAN_IV'
batctl routing_algo "$routing_algo"
batctl meshif "$iface" interface create
[ -n "$aggregated_ogms" ] && batctl meshif "$iface" aggregation "$aggregated_ogms"
[ -n "$ap_isolation" ] && batctl meshif "$iface" ap_isolation "$ap_isolation"
[ -n "$bonding" ] && batctl meshif "$iface" bonding "$bonding"
[ -n "$bridge_loop_avoidance" ] && batctl meshif "$iface" bridge_loop_avoidance "$bridge_loop_avoidance" 2>&-
[ -n "$distributed_arp_table" ] && batctl meshif "$iface" distributed_arp_table "$distributed_arp_table" 2>&-
[ -n "$fragmentation" ] && batctl meshif "$iface" fragmentation "$fragmentation"
case "$gw_mode" in
server)
if [ -n "$gw_bandwidth" ]; then
batctl meshif "$iface" gw_mode "server" "$gw_bandwidth"
else
batctl meshif "$iface" gw_mode "server"
fi
;;
client)
if [ -n "$gw_sel_class" ]; then
batctl meshif "$iface" gw_mode "client" "$gw_sel_class"
else
batctl meshif "$iface" gw_mode "client"
fi
;;
*)
batctl meshif "$iface" gw_mode "off"
;;
esac
[ -n "$hop_penalty" ] && batctl meshif "$iface" hop_penalty "$hop_penalty"
[ -n "$isolation_mark" ] && batctl meshif "$iface" isolation_mark "$isolation_mark"
[ -n "$multicast_fanout" ] && batctl meshif "$iface" multicast_fanout "$multicast_fanout"
[ -n "$multicast_mode" ] && batctl meshif "$iface" multicast_mode "$multicast_mode" 2>&-
[ -n "$network_coding" ] && batctl meshif "$iface" network_coding "$network_coding" 2>&-
[ -n "$log_level" ] && batctl meshif "$iface" loglevel "$log_level" 2>&-
[ -n "$orig_interval" ] && batctl meshif "$iface" orig_interval "$orig_interval"
[ -n "$routing_algo" ] || routing_algo="BATMAN_IV"
echo "$routing_algo" > "/sys/module/batman_adv/parameters/routing_algo"
echo "$mesh" > "/sys/class/net/$iface/batman_adv/mesh_iface"
proto_init_update "$iface" 1
proto_send_update "$config"
}
proto_batadv_teardown() {
local config="$1"
local iface="$config"
local iface="$2"
batctl meshif "$iface" interface destroy
echo "none" > "/sys/class/net/$iface/batman_adv/mesh_iface" || true
}
add_protocol batadv

View file

@ -1,53 +0,0 @@
#!/bin/sh
[ -n "$INCLUDE_ONLY" ] || {
. /lib/functions.sh
. ../netifd-proto.sh
init_proto "$@"
}
proto_batadv_hardif_init_config() {
proto_config_add_int 'elp_interval'
proto_config_add_int 'hop_penalty'
proto_config_add_string "master"
proto_config_add_string 'throughput_override'
}
proto_batadv_hardif_setup() {
local config="$1"
local iface="$2"
local elp_interval
local hop_penalty
local master
local throughput_override
json_get_vars elp_interval
json_get_vars hop_penalty
json_get_vars master
json_get_vars throughput_override
( proto_add_host_dependency "$config" '' "$master" )
batctl meshif "$master" interface -M add "$iface"
[ -n "$elp_interval" ] && batctl hardif "$iface" elp_interval "$elp_interval"
[ -n "$hop_penalty" ] && batctl hardif "$iface" hop_penalty "$hop_penalty"
[ -n "$throughput_override" ] && batctl hardif "$iface" throughput_override "$throughput_override"
proto_init_update "$iface" 1
proto_send_update "$config"
}
proto_batadv_hardif_teardown() {
local config="$1"
local iface="$2"
local master
json_get_vars master
batctl meshif "$master" interface -M del "$iface" || true
}
add_protocol batadv_hardif

12
batman-adv/files/lib/netifd/proto/batadv_vlan.sh Executable file → Normal file
View file

@ -5,25 +5,25 @@
init_proto "$@"
proto_batadv_vlan_init_config() {
proto_config_add_boolean 'ap_isolation:bool'
proto_config_add_string "ap_isolation"
}
proto_batadv_vlan_setup() {
local config="$1"
local iface="$2"
# VLAN specific variables
local device="${iface%.*}"
local vid="${iface#*.}"
# batadv_vlan options
local ap_isolation
json_get_vars ap_isolation
[ -n "$ap_isolation" ] && batctl vlan "$iface" ap_isolation "$ap_isolation"
echo "$ap_isolation" > "/sys/class/net/${device}/mesh/vlan${vid}/ap_isolation"
proto_init_update "$iface" 1
proto_send_update "$config"
}
proto_batadv_vlan_teardown() {
local cfg="$1"
}
add_protocol batadv_vlan

View file

@ -1,274 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Fri, 6 May 2022 22:03:29 +0200
Subject: Revert "batman-adv: Migrate to linux/container_of.h"
The original patch requires Linux 5.16.0 or a mac80211 compat header with this
name. But the mac80211 package is currently not providing this header and
OpenWrt main is still using older Linux kernel versions for some targets.
This reverts commit 043ae5634bdfd4c4dd8b95a22890752495080bb5.
--- a/compat-include/linux/container_of.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * This file contains macros for maintaining compatibility with older versions
- * of the Linux kernel.
- */
-
-#ifndef _NET_BATMAN_ADV_COMPAT_LINUX_CONTAINER_OF_H_
-#define _NET_BATMAN_ADV_COMPAT_LINUX_CONTAINER_OF_H_
-
-#include <linux/version.h>
-#if LINUX_VERSION_IS_GEQ(5, 16, 0)
-#include_next <linux/container_of.h>
-#else
-#include <linux/kernel.h>
-#endif
-
-#endif /* _NET_BATMAN_ADV_COMPAT_LINUX_CONTAINER_OF_H_ */
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -13,13 +13,13 @@
#include <linux/bug.h>
#include <linux/byteorder/generic.h>
#include <linux/cache.h>
-#include <linux/container_of.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/gfp.h>
#include <linux/if_ether.h>
#include <linux/init.h>
#include <linux/jiffies.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -10,13 +10,13 @@
#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/byteorder/generic.h>
-#include <linux/container_of.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/gfp.h>
#include <linux/if_ether.h>
#include <linux/jiffies.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/minmax.h>
#include <linux/netdevice.h>
--- a/net/batman-adv/bat_v_ogm.c
+++ b/net/batman-adv/bat_v_ogm.c
@@ -9,12 +9,12 @@
#include <linux/atomic.h>
#include <linux/byteorder/generic.h>
-#include <linux/container_of.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/gfp.h>
#include <linux/if_ether.h>
#include <linux/jiffies.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -10,7 +10,6 @@
#include <linux/atomic.h>
#include <linux/byteorder/generic.h>
#include <linux/compiler.h>
-#include <linux/container_of.h>
#include <linux/crc16.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -11,7 +11,6 @@
#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/byteorder/generic.h>
-#include <linux/container_of.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/gfp.h>
@@ -21,6 +20,7 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/jiffies.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/netlink.h>
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -9,7 +9,6 @@
#include <linux/atomic.h>
#include <linux/byteorder/generic.h>
-#include <linux/container_of.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/gfp.h>
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -10,12 +10,12 @@
#include <linux/atomic.h>
#include <linux/byteorder/generic.h>
#include <linux/compiler.h>
-#include <linux/container_of.h>
#include <linux/errno.h>
#include <linux/gfp.h>
#include <linux/if.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/limits.h>
#include <linux/list.h>
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -10,7 +10,6 @@
#include <linux/atomic.h>
#include <linux/build_bug.h>
#include <linux/byteorder/generic.h>
-#include <linux/container_of.h>
#include <linux/crc32c.h>
#include <linux/device.h>
#include <linux/errno.h>
--- a/net/batman-adv/multicast.c
+++ b/net/batman-adv/multicast.c
@@ -11,7 +11,6 @@
#include <linux/bitops.h>
#include <linux/bug.h>
#include <linux/byteorder/generic.h>
-#include <linux/container_of.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/gfp.h>
--- a/net/batman-adv/network-coding.c
+++ b/net/batman-adv/network-coding.c
@@ -11,7 +11,6 @@
#include <linux/bitops.h>
#include <linux/byteorder/generic.h>
#include <linux/compiler.h>
-#include <linux/container_of.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/gfp.h>
@@ -20,6 +19,7 @@
#include <linux/init.h>
#include <linux/jhash.h>
#include <linux/jiffies.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
--- a/net/batman-adv/originator.c
+++ b/net/batman-adv/originator.c
@@ -8,11 +8,11 @@
#include "main.h"
#include <linux/atomic.h>
-#include <linux/container_of.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/gfp.h>
#include <linux/jiffies.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
--- a/net/batman-adv/send.c
+++ b/net/batman-adv/send.c
@@ -10,13 +10,13 @@
#include <linux/atomic.h>
#include <linux/bug.h>
#include <linux/byteorder/generic.h>
-#include <linux/container_of.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
#include <linux/gfp.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/jiffies.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/netdevice.h>
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -11,7 +11,6 @@
#include <linux/byteorder/generic.h>
#include <linux/cache.h>
#include <linux/compiler.h>
-#include <linux/container_of.h>
#include <linux/cpumask.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
@@ -20,6 +19,7 @@
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/jiffies.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -12,13 +12,13 @@
#include <linux/byteorder/generic.h>
#include <linux/cache.h>
#include <linux/compiler.h>
-#include <linux/container_of.h>
#include <linux/err.h>
#include <linux/etherdevice.h>
#include <linux/gfp.h>
#include <linux/if_ether.h>
#include <linux/init.h>
#include <linux/jiffies.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/kthread.h>
#include <linux/limits.h>
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -13,7 +13,6 @@
#include <linux/byteorder/generic.h>
#include <linux/cache.h>
#include <linux/compiler.h>
-#include <linux/container_of.h>
#include <linux/crc32c.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
@@ -22,6 +21,7 @@
#include <linux/init.h>
#include <linux/jhash.h>
#include <linux/jiffies.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
--- a/net/batman-adv/tvlv.c
+++ b/net/batman-adv/tvlv.c
@@ -7,10 +7,10 @@
#include "main.h"
#include <linux/byteorder/generic.h>
-#include <linux/container_of.h>
#include <linux/etherdevice.h>
#include <linux/gfp.h>
#include <linux/if_ether.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>

View file

@ -0,0 +1,43 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Wed, 9 May 2018 21:07:40 +0200
Subject: batman-adv: add compat hacks
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 69c0d85bceb3e0a1915e37d278110ee2655c4571..53b329d24461819b4cf0d4118cfa5b0eb8d7261b 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -19,7 +19,7 @@
#include "main.h"
#include <linux/atomic.h>
-#include <linux/build_bug.h>
+#include <linux/bug.h>
#include <linux/byteorder/generic.h>
#include <linux/crc32c.h>
#include <linux/errno.h>
diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
index 11520de96ccb1a87183e9666066e21731538ccd9..9af0a44dce74e7ead7f2c29ec4d49156bf4c9dd7 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -20,7 +20,7 @@
#include "main.h"
#include <linux/atomic.h>
-#include <linux/build_bug.h>
+#include <linux/bug.h>
#include <linux/byteorder/generic.h>
#include <linux/cache.h>
#include <linux/compiler.h>
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 0225616d5771d0986127322142fc591780fc25b0..91b9a0aaaa2e6fe59b5e4ea2e57b7be375618059 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -21,7 +21,7 @@
#include <linux/atomic.h>
#include <linux/bitops.h>
-#include <linux/build_bug.h>
+#include <linux/bug.h>
#include <linux/byteorder/generic.h>
#include <linux/cache.h>
#include <linux/compiler.h>

View file

@ -0,0 +1,72 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Wed, 9 May 2018 21:07:40 +0200
Subject: batman-adv: Avoid race in TT TVLV allocator helper
The functions batadv_tt_prepare_tvlv_local_data and
batadv_tt_prepare_tvlv_global_data are responsible for preparing a buffer
which can be used to store the TVLV container for TT and add the VLAN
information to it.
This will be done in three phases:
1. count the number of VLANs and their entries
2. allocate the buffer using the counters from the previous step and limits
from the caller (parameter tt_len)
3. insert the VLAN information to the buffer
The step 1 and 3 operate on a list which contains the VLANs. The access to
these lists must be protected with an appropriate lock or otherwise they
might operate on on different entries. This could for example happen when
another context is adding VLAN entries to this list.
This could lead to a buffer overflow in these functions when enough entries
were added between step 1 and 3 to the VLAN lists that the buffer room for
the entries (*tt_change) is smaller then the now required extra buffer for
new VLAN entries.
Fixes: 21a57f6e7a3b ("batman-adv: make the TT CRC logic VLAN specific")
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/286be89a33497ba9000aa5c2960f1f4114953522
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 91b9a0aaaa2e6fe59b5e4ea2e57b7be375618059..2511adb79936782c96ed397265418421b69f617d 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -862,7 +862,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
struct batadv_orig_node_vlan *vlan;
u8 *tt_change_ptr;
- rcu_read_lock();
+ spin_lock_bh(&orig_node->vlan_list_lock);
hlist_for_each_entry_rcu(vlan, &orig_node->vlan_list, list) {
num_vlan++;
num_entries += atomic_read(&vlan->tt.num_entries);
@@ -900,7 +900,7 @@ batadv_tt_prepare_tvlv_global_data(struct batadv_orig_node *orig_node,
*tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
out:
- rcu_read_unlock();
+ spin_unlock_bh(&orig_node->vlan_list_lock);
return tvlv_len;
}
@@ -936,7 +936,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
u8 *tt_change_ptr;
int change_offset;
- rcu_read_lock();
+ spin_lock_bh(&bat_priv->softif_vlan_list_lock);
hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
num_vlan++;
num_entries += atomic_read(&vlan->tt.num_entries);
@@ -974,7 +974,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
*tt_change = (struct batadv_tvlv_tt_change *)tt_change_ptr;
out:
- rcu_read_unlock();
+ spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
return tvlv_len;
}

View file

@ -1,19 +0,0 @@
From: Alexandru Gagniuc <mr.nuke.me@gmail.com>
Date: Thu, 6 Apr 2023 18:05:50 -0500
Subject: fix batadv_is_cfg80211_netdev
Replace CONFIG_CFG80211 with CPTCFG_CFG80211, which is the correct
macro to use when building under backports.
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -308,8 +308,7 @@ static bool batadv_is_cfg80211_netdev(st
{
if (!net_device)
return false;
-
-#if IS_ENABLED(CONFIG_CFG80211)
+#if IS_ENABLED(CPTCFG_CFG80211)
/* cfg80211 drivers have to set ieee80211_ptr */
if (net_device->ieee80211_ptr)
return true;

View file

@ -1,97 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Fri, 2 Feb 2024 22:49:00 +0100
Subject: Revert "batman-adv: Switch to linux/sprintf.h"
The original patch requires Linux 6.6.0 or a mac80211 compat header with this
name. But the mac80211 package is currently not providing this header and
OpenWrt main is still using older Linux kernel versions for some targets.
This reverts commit f0fb49c5ab70dfa064f0aa8d1c5d84f65e8cbc86.
--- a/compat-include/linux/sprintf.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * This file contains macros for maintaining compatibility with older versions
- * of the Linux kernel.
- */
-
-#ifndef _NET_BATMAN_ADV_COMPAT_LINUX_SPRINTF_H_
-#define _NET_BATMAN_ADV_COMPAT_LINUX_SPRINTF_H_
-
-#include <linux/version.h>
-#if LINUX_VERSION_IS_GEQ(6, 6, 0)
-#include_next <linux/sprintf.h>
-#else
-#include <linux/kernel.h>
-#endif
-
-#endif /* _NET_BATMAN_ADV_COMPAT_LINUX_SPRINTF_H_ */
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -19,6 +19,7 @@
#include <linux/if_vlan.h>
#include <linux/jhash.h>
#include <linux/jiffies.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
@@ -29,7 +30,6 @@
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <linux/sprintf.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/workqueue.h>
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -17,6 +17,7 @@
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
+#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/lockdep.h>
@@ -27,7 +28,6 @@
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <linux/sprintf.h>
#include <linux/stddef.h>
#include <linux/udp.h>
#include <net/sock.h>
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -32,7 +32,6 @@
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <linux/sprintf.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/workqueue.h>
--- a/net/batman-adv/multicast.c
+++ b/net/batman-adv/multicast.c
@@ -24,6 +24,7 @@
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/jiffies.h>
+#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/lockdep.h>
#include <linux/netdevice.h>
@@ -34,7 +35,6 @@
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
-#include <linux/sprintf.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/types.h>

View file

@ -0,0 +1,177 @@
From: Linus Lüssing <linus.luessing@c0d3.blue>
Date: Thu, 10 May 2018 19:44:28 +0200
Subject: batman-adv: Fix TT sync flags for intermediate TT responses
The previous TT sync fix so far only fixed TT responses issued by the
target node directly. So far, TT responses issued by intermediate nodes
still lead to the wrong flags being added, leading to CRC mismatches.
This behaviour was observed at Freifunk Hannover in a 800 nodes setup
where a considerable amount of nodes were still infected with 'WI'
TT flags even with (most) nodes having the previous TT sync fix applied.
I was able to reproduce the issue with intermediate TT responses in a
four node test setup and this patch fixes this issue by ensuring to
use the per originator instead of the summarized, OR'd ones.
Fixes: fa614fd04692 ("batman-adv: fix tt_global_entries flags update")
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/d65daee8617b29c1ddcc949ce3a5ec24f7a1e1af
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 2511adb79936782c96ed397265418421b69f617d..09bc1ed9fb59c1f76a4227f158d3ac8b73cbd32b 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1538,6 +1538,8 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
* handled by a given originator
* @entry: the TT global entry to check
* @orig_node: the originator to search in the list
+ * @flags: a pointer to store TT flags for the given @entry received
+ * from @orig_node
*
* find out if an orig_node is already in the list of a tt_global_entry.
*
@@ -1545,7 +1547,8 @@ batadv_tt_global_orig_entry_find(const struct batadv_tt_global_entry *entry,
*/
static bool
batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
- const struct batadv_orig_node *orig_node)
+ const struct batadv_orig_node *orig_node,
+ u8 *flags)
{
struct batadv_tt_orig_list_entry *orig_entry;
bool found = false;
@@ -1553,6 +1556,10 @@ batadv_tt_global_entry_has_orig(const struct batadv_tt_global_entry *entry,
orig_entry = batadv_tt_global_orig_entry_find(entry, orig_node);
if (orig_entry) {
found = true;
+
+ if (flags)
+ *flags = orig_entry->flags;
+
batadv_tt_orig_list_entry_put(orig_entry);
}
@@ -1731,7 +1738,7 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
if (!(common->flags & BATADV_TT_CLIENT_TEMP))
goto out;
if (batadv_tt_global_entry_has_orig(tt_global_entry,
- orig_node))
+ orig_node, NULL))
goto out_remove;
batadv_tt_global_del_orig_list(tt_global_entry);
goto add_orig_entry;
@@ -2880,23 +2887,46 @@ batadv_tt_req_node_new(struct batadv_priv *bat_priv,
}
/**
- * batadv_tt_local_valid() - verify that given tt entry is a valid one
+ * batadv_tt_local_valid() - verify local tt entry and get flags
* @entry_ptr: to be checked local tt entry
* @data_ptr: not used but definition required to satisfy the callback prototype
+ * @flags: a pointer to store TT flags for this client to
+ *
+ * Checks the validity of the given local TT entry. If it is, then the provided
+ * flags pointer is updated.
*
* Return: true if the entry is a valid, false otherwise.
*/
-static bool batadv_tt_local_valid(const void *entry_ptr, const void *data_ptr)
+static bool batadv_tt_local_valid(const void *entry_ptr,
+ const void *data_ptr,
+ u8 *flags)
{
const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
if (tt_common_entry->flags & BATADV_TT_CLIENT_NEW)
return false;
+
+ if (flags)
+ *flags = tt_common_entry->flags;
+
return true;
}
+/**
+ * batadv_tt_global_valid() - verify global tt entry and get flags
+ * @entry_ptr: to be checked global tt entry
+ * @data_ptr: an orig_node object (may be NULL)
+ * @flags: a pointer to store TT flags for this client to
+ *
+ * Checks the validity of the given global TT entry. If it is, then the provided
+ * flags pointer is updated either with the common (summed) TT flags if data_ptr
+ * is NULL or the specific, per originator TT flags otherwise.
+ *
+ * Return: true if the entry is a valid, false otherwise.
+ */
static bool batadv_tt_global_valid(const void *entry_ptr,
- const void *data_ptr)
+ const void *data_ptr,
+ u8 *flags)
{
const struct batadv_tt_common_entry *tt_common_entry = entry_ptr;
const struct batadv_tt_global_entry *tt_global_entry;
@@ -2910,7 +2940,8 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
struct batadv_tt_global_entry,
common);
- return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node);
+ return batadv_tt_global_entry_has_orig(tt_global_entry, orig_node,
+ flags);
}
/**
@@ -2920,25 +2951,34 @@ static bool batadv_tt_global_valid(const void *entry_ptr,
* @hash: hash table containing the tt entries
* @tt_len: expected tvlv tt data buffer length in number of bytes
* @tvlv_buff: pointer to the buffer to fill with the TT data
- * @valid_cb: function to filter tt change entries
+ * @valid_cb: function to filter tt change entries and to return TT flags
* @cb_data: data passed to the filter function as argument
+ *
+ * Fills the tvlv buff with the tt entries from the specified hash. If valid_cb
+ * is not provided then this becomes a no-op.
*/
static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
struct batadv_hashtable *hash,
void *tvlv_buff, u16 tt_len,
bool (*valid_cb)(const void *,
- const void *),
+ const void *,
+ u8 *flags),
void *cb_data)
{
struct batadv_tt_common_entry *tt_common_entry;
struct batadv_tvlv_tt_change *tt_change;
struct hlist_head *head;
u16 tt_tot, tt_num_entries = 0;
+ u8 flags;
+ bool ret;
u32 i;
tt_tot = batadv_tt_entries(tt_len);
tt_change = (struct batadv_tvlv_tt_change *)tvlv_buff;
+ if (!valid_cb)
+ return;
+
rcu_read_lock();
for (i = 0; i < hash->size; i++) {
head = &hash->table[i];
@@ -2948,11 +2988,12 @@ static void batadv_tt_tvlv_generate(struct batadv_priv *bat_priv,
if (tt_tot == tt_num_entries)
break;
- if ((valid_cb) && (!valid_cb(tt_common_entry, cb_data)))
+ ret = valid_cb(tt_common_entry, cb_data, &flags);
+ if (!ret)
continue;
ether_addr_copy(tt_change->addr, tt_common_entry->addr);
- tt_change->flags = tt_common_entry->flags;
+ tt_change->flags = flags;
tt_change->vid = htons(tt_common_entry->vid);
memset(tt_change->reserved, 0,
sizeof(tt_change->reserved));

View file

@ -1,69 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Fri, 2 Feb 2024 22:49:48 +0100
Subject: Revert "batman-adv: Switch to linux/array_size.h"
The original patch requires Linux 6.7.0 or a mac80211 compat header with this
name. But the mac80211 package is currently not providing this header and
OpenWrt main is still using older Linux kernel versions for some targets.
This reverts commit f33d7f724675544a36b24c77f8d4b95d41252ae2.
--- a/compat-include/linux/array_size.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/* Copyright (C) B.A.T.M.A.N. contributors:
- *
- * Marek Lindner, Simon Wunderlich
- *
- * This file contains macros for maintaining compatibility with older versions
- * of the Linux kernel.
- */
-
-#ifndef _NET_BATMAN_ADV_COMPAT_LINUX_ARRAY_SIZE_H_
-#define _NET_BATMAN_ADV_COMPAT_LINUX_ARRAY_SIZE_H_
-
-#include <linux/version.h>
-#if LINUX_VERSION_IS_GEQ(6, 7, 0)
-#include_next <linux/array_size.h>
-#else
-#include <linux/kernel.h>
-#endif
-
-#endif /* _NET_BATMAN_ADV_COMPAT_LINUX_ARRAY_SIZE_H_ */
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -6,7 +6,6 @@
#include "main.h"
-#include <linux/array_size.h>
#include <linux/atomic.h>
#include <linux/build_bug.h>
#include <linux/byteorder/generic.h>
@@ -20,6 +19,7 @@
#include <linux/init.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
+#include <linux/kernel.h>
#include <linux/kobject.h>
#include <linux/kref.h>
#include <linux/list.h>
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -7,7 +7,6 @@
#include "netlink.h"
#include "main.h"
-#include <linux/array_size.h>
#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/bug.h>
@@ -21,6 +20,7 @@
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
#include <linux/init.h>
+#include <linux/kernel.h>
#include <linux/limits.h>
#include <linux/list.h>
#include <linux/minmax.h>

View file

@ -0,0 +1,73 @@
From: Marek Lindner <mareklindner@neomailbox.ch>
Date: Sat, 12 May 2018 00:23:07 +0800
Subject: batman-adv: prevent TT request storms by not sending inconsistent TT TLVLs
A translation table TVLV changset sent with an OGM consists
of a number of headers (one per VLAN) plus the changeset
itself (addition and/or deletion of entries).
The per-VLAN headers are used by OGM recipients for consistency
checks. Said consistency check might determine that a full
translation table request is needed to restore consistency. If
the TT sender adds per-VLAN headers of empty VLANs into the OGM,
recipients are led to believe to have reached an inconsistent
state and thus request a full table update. The full table does
not contain empty VLANs (due to missing entries) the cycle
restarts when the next OGM is issued.
Consequently, when the translation table TVLV headers are
composed, empty VLANs are to be excluded.
Fixes: 21a57f6e7a3b ("batman-adv: make the TT CRC logic VLAN specific")
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/e4687b4be274da6180fc15b327419851fb681ec9
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 09bc1ed9fb59c1f76a4227f158d3ac8b73cbd32b..dfd484d73f8e569bc60e153ea6ca244ea5757d5c 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -931,15 +931,20 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
struct batadv_tvlv_tt_vlan_data *tt_vlan;
struct batadv_softif_vlan *vlan;
u16 num_vlan = 0;
- u16 num_entries = 0;
+ u16 vlan_entries = 0;
+ u16 total_entries = 0;
u16 tvlv_len;
u8 *tt_change_ptr;
int change_offset;
spin_lock_bh(&bat_priv->softif_vlan_list_lock);
hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
+ vlan_entries = atomic_read(&vlan->tt.num_entries);
+ if (vlan_entries < 1)
+ continue;
+
num_vlan++;
- num_entries += atomic_read(&vlan->tt.num_entries);
+ total_entries += vlan_entries;
}
change_offset = sizeof(**tt_data);
@@ -947,7 +952,7 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
/* if tt_len is negative, allocate the space needed by the full table */
if (*tt_len < 0)
- *tt_len = batadv_tt_len(num_entries);
+ *tt_len = batadv_tt_len(total_entries);
tvlv_len = *tt_len;
tvlv_len += change_offset;
@@ -964,6 +969,10 @@ batadv_tt_prepare_tvlv_local_data(struct batadv_priv *bat_priv,
tt_vlan = (struct batadv_tvlv_tt_vlan_data *)(*tt_data + 1);
hlist_for_each_entry_rcu(vlan, &bat_priv->softif_vlan_list, list) {
+ vlan_entries = atomic_read(&vlan->tt.num_entries);
+ if (vlan_entries < 1)
+ continue;
+
tt_vlan->vid = htons(vlan->vid);
tt_vlan->crc = htonl(vlan->tt.crc);

View file

@ -0,0 +1,26 @@
From: Antonio Quartulli <a@unstable.cc>
Date: Sat, 12 May 2018 03:02:44 +0800
Subject: batman-adv: don't implement skb_postpush_rcsum() for linux >=4.4.47
skb_postpush_rcsum() has been implemented in 4.4.47 therefore
our compat code has to be changed to prevent this function to
be implemented when using those kernels.
Signed-off-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/b4693d107e0869bf11956fd2d3be4fd0a8671b46
diff --git a/compat-include/linux/skbuff.h b/compat-include/linux/skbuff.h
index 6f73946496ac15f2fdb856357f16e4e2d8a6e6cd..371bb561eecaf605a5c96f9417546f6bb817724d 100644
--- a/compat-include/linux/skbuff.h
+++ b/compat-include/linux/skbuff.h
@@ -77,7 +77,7 @@ struct sk_buff *skb_checksum_trimmed(struct sk_buff *skb,
#endif /* < KERNEL_VERSION(4, 2, 0) */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0)
+#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 4, 47)
static inline void skb_postpush_rcsum(struct sk_buff *skb,
const void *start, unsigned int len)

View file

@ -0,0 +1,44 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sat, 2 Jun 2018 17:26:34 +0200
Subject: batman-adv: Fix bat_ogm_iv best gw refcnt after netlink dump
A reference for the best gateway is taken when the list of gateways in the
mesh is sent via netlink. This is necessary to check whether the currently
dumped entry is the currently selected gateway or not. This information is
then transferred as flag BATADV_ATTR_FLAG_BEST.
After the comparison of the current entry is done,
batadv_iv_gw_dump_entry() has to decrease the reference counter again.
Otherwise the reference will be held and thus prevents a proper shutdown of
the batman-adv interfaces (and some of the interfaces enslaved in it).
Fixes: fa3228924152 ("batman-adv: add B.A.T.M.A.N. IV bat_gw_dump implementations")
Reported-by: Andreas Ziegler <dev@andreas-ziegler.de>
Tested-by: Andreas Ziegler <dev@andreas-ziegler.de>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/46360d203c627e71a27d1f8f551c819c7f2353fd
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c
index be09a98838252f4f0c23cec0625930cf896cd0ff..73bf6a93a3cf1141a34657bf1284893199e04db9 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -2732,7 +2732,7 @@ static int batadv_iv_gw_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
{
struct batadv_neigh_ifinfo *router_ifinfo = NULL;
struct batadv_neigh_node *router;
- struct batadv_gw_node *curr_gw;
+ struct batadv_gw_node *curr_gw = NULL;
int ret = 0;
void *hdr;
@@ -2780,6 +2780,8 @@ static int batadv_iv_gw_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
ret = 0;
out:
+ if (curr_gw)
+ batadv_gw_node_put(curr_gw);
if (router_ifinfo)
batadv_neigh_ifinfo_put(router_ifinfo);
if (router)

View file

@ -0,0 +1,42 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sat, 2 Jun 2018 17:26:35 +0200
Subject: batman-adv: Fix bat_v best gw refcnt after netlink dump
A reference for the best gateway is taken when the list of gateways in the
mesh is sent via netlink. This is necessary to check whether the currently
dumped entry is the currently selected gateway or not. This information is
then transferred as flag BATADV_ATTR_FLAG_BEST.
After the comparison of the current entry is done,
batadv_v_gw_dump_entry() has to decrease the reference counter again.
Otherwise the reference will be held and thus prevents a proper shutdown of
the batman-adv interfaces (and some of the interfaces enslaved in it).
Fixes: 15315a94ad98 ("batman-adv: add B.A.T.M.A.N. V bat_gw_dump implementations")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/2b422b5808183d1084b450b89d9a085a13dd6d2c
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c
index ec93337ee2597738e46b87dd72724d5becf3f48e..6baec4e68898c6e992e7522d2ee8c78ce62a1b08 100644
--- a/net/batman-adv/bat_v.c
+++ b/net/batman-adv/bat_v.c
@@ -927,7 +927,7 @@ static int batadv_v_gw_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
{
struct batadv_neigh_ifinfo *router_ifinfo = NULL;
struct batadv_neigh_node *router;
- struct batadv_gw_node *curr_gw;
+ struct batadv_gw_node *curr_gw = NULL;
int ret = 0;
void *hdr;
@@ -995,6 +995,8 @@ static int batadv_v_gw_dump_entry(struct sk_buff *msg, u32 portid, u32 seq,
ret = 0;
out:
+ if (curr_gw)
+ batadv_gw_node_put(curr_gw);
if (router_ifinfo)
batadv_neigh_ifinfo_put(router_ifinfo);
if (router)

View file

@ -0,0 +1,106 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Fri, 1 Jun 2018 19:24:23 +0200
Subject: batman-adv: Fix debugfs path for renamed hardif
batman-adv is creating special debugfs directories in the init
net_namespace for each valid hard-interface (net_device). But it is
possible to rename a net_device to a completely different name then the
original one.
It can therefore happen that a user registers a new net_device which gets
the name "wlan0" assigned by default. batman-adv is also adding a new
directory under $debugfs/batman-adv/ with the name "wlan0".
The user then decides to rename this device to "wl_pri" and registers a
different device. The kernel may now decide to use the name "wlan0" again
for this new device. batman-adv will detect it as a valid net_device and
tries to create a directory with the name "wlan0" under
$debugfs/batman-adv/. But there already exists one with this name under
this path and thus this fails. batman-adv will detect a problem and
rollback the registering of this device.
batman-adv must therefore take care of renaming the debugfs directories
for hard-interfaces whenever it detects such a net_device rename.
Fixes: 3c926a01c8e8 ("batman-adv: add debugfs structure for information per interface")
Reported-by: John Soros <sorosj@gmail.com>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/127086f503f6495518b95455efebee33d328f335
diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c
index 4229b01ac7b54008e023df0ed6546a6d541498ba..7e5de7b9f6d53b846cebfa95bf694a20c640b2d6 100644
--- a/net/batman-adv/debugfs.c
+++ b/net/batman-adv/debugfs.c
@@ -19,6 +19,7 @@
#include "debugfs.h"
#include "main.h"
+#include <linux/dcache.h>
#include <linux/debugfs.h>
#include <linux/err.h>
#include <linux/errno.h>
@@ -343,6 +344,25 @@ int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface)
return -ENOMEM;
}
+/**
+ * batadv_debugfs_rename_hardif() - Fix debugfs path for renamed hardif
+ * @hard_iface: hard interface which was renamed
+ */
+void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface)
+{
+ const char *name = hard_iface->net_dev->name;
+ struct dentry *dir;
+ struct dentry *d;
+
+ dir = hard_iface->debug_dir;
+ if (!dir)
+ return;
+
+ d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name);
+ if (!d)
+ pr_err("Can't rename debugfs dir to %s\n", name);
+}
+
/**
* batadv_debugfs_del_hardif() - delete the base directory for a hard interface
* in debugfs.
diff --git a/net/batman-adv/debugfs.h b/net/batman-adv/debugfs.h
index 37b069698b04b369e68e4e8a31c3ac01575b0178..8538a7a75e937f50f8efdbf2fe879b4ac8dafadb 100644
--- a/net/batman-adv/debugfs.h
+++ b/net/batman-adv/debugfs.h
@@ -32,6 +32,7 @@ void batadv_debugfs_destroy(void);
int batadv_debugfs_add_meshif(struct net_device *dev);
void batadv_debugfs_del_meshif(struct net_device *dev);
int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface);
+void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface);
void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface);
#else
@@ -59,6 +60,11 @@ int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface)
return 0;
}
+static inline
+void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface)
+{
+}
+
static inline
void batadv_debugfs_del_hardif(struct batadv_hard_iface *hard_iface)
{
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index c405d15befd60bdabf9f50813c3bee446238d539..dc2763b1110727cc5dee62d555dd7c7b50f3b463 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -1051,6 +1051,9 @@ static int batadv_hard_if_event(struct notifier_block *this,
if (batadv_is_wifi_hardif(hard_iface))
hard_iface->num_bcasts = BATADV_NUM_BCASTS_WIRELESS;
break;
+ case NETDEV_CHANGENAME:
+ batadv_debugfs_rename_hardif(hard_iface);
+ break;
default:
break;
}

View file

@ -0,0 +1,134 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Fri, 1 Jun 2018 19:24:24 +0200
Subject: batman-adv: Fix debugfs path for renamed softif
batman-adv is creating special debugfs directories in the init
net_namespace for each created soft-interface (batadv net_device). But it
is possible to rename a net_device to a completely different name then the
original one.
It can therefore happen that a user registers a new batadv net_device with
the name "bat0". batman-adv is then also adding a new directory under
$debugfs/batman-adv/ with the name "wlan0".
The user then decides to rename this device to "bat1" and registers a
different batadv device with the name "bat0". batman-adv will then try to
create a directory with the name "bat0" under $debugfs/batman-adv/ again.
But there already exists one with this name under this path and thus this
fails. batman-adv will detect a problem and rollback the registering of
this device.
batman-adv must therefore take care of renaming the debugfs directories for
soft-interfaces whenever it detects such a net_device rename.
Fixes: 230202d4b530 ("batman-adv: Move device for icmp injection to debugfs")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/3f2237bb191cd17654a4d5a5badfd6e7379c4b37
diff --git a/net/batman-adv/debugfs.c b/net/batman-adv/debugfs.c
index 7e5de7b9f6d53b846cebfa95bf694a20c640b2d6..87479c60670ebfbe2ad3df17130f1289d657df7b 100644
--- a/net/batman-adv/debugfs.c
+++ b/net/batman-adv/debugfs.c
@@ -433,6 +433,26 @@ int batadv_debugfs_add_meshif(struct net_device *dev)
return -ENOMEM;
}
+/**
+ * batadv_debugfs_rename_meshif() - Fix debugfs path for renamed softif
+ * @dev: net_device which was renamed
+ */
+void batadv_debugfs_rename_meshif(struct net_device *dev)
+{
+ struct batadv_priv *bat_priv = netdev_priv(dev);
+ const char *name = dev->name;
+ struct dentry *dir;
+ struct dentry *d;
+
+ dir = bat_priv->debug_dir;
+ if (!dir)
+ return;
+
+ d = debugfs_rename(dir->d_parent, dir, dir->d_parent, name);
+ if (!d)
+ pr_err("Can't rename debugfs dir to %s\n", name);
+}
+
/**
* batadv_debugfs_del_meshif() - Remove interface dependent debugfs entries
* @dev: netdev struct of the soft interface
diff --git a/net/batman-adv/debugfs.h b/net/batman-adv/debugfs.h
index 8538a7a75e937f50f8efdbf2fe879b4ac8dafadb..08a592ffbee5203ac4994fc49bf9c187c2e66f8e 100644
--- a/net/batman-adv/debugfs.h
+++ b/net/batman-adv/debugfs.h
@@ -30,6 +30,7 @@ struct net_device;
void batadv_debugfs_init(void);
void batadv_debugfs_destroy(void);
int batadv_debugfs_add_meshif(struct net_device *dev);
+void batadv_debugfs_rename_meshif(struct net_device *dev);
void batadv_debugfs_del_meshif(struct net_device *dev);
int batadv_debugfs_add_hardif(struct batadv_hard_iface *hard_iface);
void batadv_debugfs_rename_hardif(struct batadv_hard_iface *hard_iface);
@@ -50,6 +51,10 @@ static inline int batadv_debugfs_add_meshif(struct net_device *dev)
return 0;
}
+static inline void batadv_debugfs_rename_meshif(struct net_device *dev)
+{
+}
+
static inline void batadv_debugfs_del_meshif(struct net_device *dev)
{
}
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index dc2763b1110727cc5dee62d555dd7c7b50f3b463..2f0d42f2f913e74cf10c0c6ce89320434994cac5 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -989,6 +989,32 @@ void batadv_hardif_remove_interfaces(void)
rtnl_unlock();
}
+/**
+ * batadv_hard_if_event_softif() - Handle events for soft interfaces
+ * @event: NETDEV_* event to handle
+ * @net_dev: net_device which generated an event
+ *
+ * Return: NOTIFY_* result
+ */
+static int batadv_hard_if_event_softif(unsigned long event,
+ struct net_device *net_dev)
+{
+ struct batadv_priv *bat_priv;
+
+ switch (event) {
+ case NETDEV_REGISTER:
+ batadv_sysfs_add_meshif(net_dev);
+ bat_priv = netdev_priv(net_dev);
+ batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
+ break;
+ case NETDEV_CHANGENAME:
+ batadv_debugfs_rename_meshif(net_dev);
+ break;
+ }
+
+ return NOTIFY_DONE;
+}
+
static int batadv_hard_if_event(struct notifier_block *this,
unsigned long event, void *ptr)
{
@@ -997,12 +1023,8 @@ static int batadv_hard_if_event(struct notifier_block *this,
struct batadv_hard_iface *primary_if = NULL;
struct batadv_priv *bat_priv;
- if (batadv_softif_is_valid(net_dev) && event == NETDEV_REGISTER) {
- batadv_sysfs_add_meshif(net_dev);
- bat_priv = netdev_priv(net_dev);
- batadv_softif_create_vlan(bat_priv, BATADV_NO_FLAGS);
- return NOTIFY_DONE;
- }
+ if (batadv_softif_is_valid(net_dev))
+ return batadv_hard_if_event_softif(event, net_dev);
hard_iface = batadv_hardif_get_by_netdev(net_dev);
if (!hard_iface && (event == NETDEV_REGISTER ||

View file

@ -0,0 +1,34 @@
From: Linus Lüssing <linus.luessing@c0d3.blue>
Date: Thu, 7 Jun 2018 00:46:23 +0200
Subject: batman-adv: Avoid storing non-TT-sync flags on singular entries too
Since commit 382d020fe3fa ("batman-adv: fix TT sync flag inconsistencies")
TT sync flags and TT non-sync'd flags are supposed to be stored
separately.
The previous patch missed to apply this separation on a TT entry with
only a single TT orig entry.
This is a minor fix because with only a single TT orig entry the DDoS
issue the former patch solves does not apply.
Fixes: 382d020fe3fa ("batman-adv: fix TT sync flag inconsistencies")
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/beb6246b2339852b6a429ae9259a8eb30a685041
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index dfd484d73f8e569bc60e153ea6ca244ea5757d5c..8b0f30457a2eda3c0791da9c8876fc1768170d76 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1705,7 +1705,8 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
ether_addr_copy(common->addr, tt_addr);
common->vid = vid;
- common->flags = flags;
+ common->flags = flags & (~BATADV_TT_SYNC_MASK);
+
tt_global_entry->roam_at = 0;
/* node must store current time in case of roaming. This is
* needed to purge this entry out on timeout (if nobody claims

View file

@ -0,0 +1,43 @@
From: Linus Lüssing <linus.luessing@c0d3.blue>
Date: Thu, 7 Jun 2018 00:46:24 +0200
Subject: batman-adv: Fix multicast TT issues with bogus ROAM flags
When a (broken) node wrongly sends multicast TT entries with a ROAM
flag then this causes any receiving node to drop all entries for the
same multicast MAC address announced by other nodes, leading to
packet loss.
Fix this DoS vector by only storing TT sync flags. For multicast TT
non-sync'ing flag bits like ROAM are unused so far anyway.
Fixes: 405cc1e5a81e ("batman-adv: Modified forwarding behaviour for multicast packets")
Reported-by: Leonardo Mörlein <me@irrelefant.net>
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/c7054ffae0c3b08bb4bef3cffee1e0a543e14096
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 8b0f30457a2eda3c0791da9c8876fc1768170d76..9efbdd6348c4d69c525b3e0574d2b24db838c086 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1705,7 +1705,8 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
ether_addr_copy(common->addr, tt_addr);
common->vid = vid;
- common->flags = flags & (~BATADV_TT_SYNC_MASK);
+ if (!is_multicast_ether_addr(common->addr))
+ common->flags = flags & (~BATADV_TT_SYNC_MASK);
tt_global_entry->roam_at = 0;
/* node must store current time in case of roaming. This is
@@ -1769,7 +1770,8 @@ static bool batadv_tt_global_add(struct batadv_priv *bat_priv,
* TT_CLIENT_TEMP, therefore they have to be copied in the
* client entry
*/
- common->flags |= flags & (~BATADV_TT_SYNC_MASK);
+ if (!is_multicast_ether_addr(common->addr))
+ common->flags |= flags & (~BATADV_TT_SYNC_MASK);
/* If there is the BATADV_TT_CLIENT_ROAM flag set, there is only
* one originator left in the list and we previously received a

View file

@ -0,0 +1,32 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Fri, 31 Aug 2018 15:08:44 +0200
Subject: batman-adv: Avoid probe ELP information leak
The probe ELPs for WiFi interfaces are expanded to contain at least
BATADV_ELP_MIN_PROBE_SIZE bytes. This is usually a lot more than the
number of bytes which the template ELP packet requires.
These extra padding bytes were not initialized and thus could contain data
which were previously stored at the same location. It is therefore required
to set it to some predefined or random values to avoid leaking private
information from the system transmitting these kind of packets.
Fixes: bedcadfaa92b ("batman-adv: ELP - send unicast ELP packets for throughput sampling")
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/6c876e572f592c31132a55b5fb8427e168e5fb3c
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index 28687493599f5ba10b8813c18d803582210bc292..371028f82a0669e86155fee39ba955cbbde48e60 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -228,7 +228,7 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh)
* the packet to be exactly of that size to make the link
* throughput estimation effective.
*/
- skb_put(skb, probe_len - hard_iface->bat_v.elp_skb->len);
+ skb_put_zero(skb, probe_len - hard_iface->bat_v.elp_skb->len);
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Sending unicast (probe) ELP packet on interface %s to %pM\n",

View file

@ -0,0 +1,42 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Fri, 31 Aug 2018 16:46:47 +0200
Subject: batman-adv: Fix segfault when writing to throughput_override
The per hardif sysfs file "batman_adv/throughput_override" prints the
resulting change as info text when the users writes to this file. It uses
the helper function batadv_info to add it at the same time to the kernel
ring buffer and to the batman-adv debug log (when CONFIG_BATMAN_ADV_DEBUG
is enabled).
The function batadv_info requires as first parameter the batman-adv softif
net_device. This parameter is then used to find the private buffer which
contains the debug log for this batman-adv interface. But
batadv_store_throughput_override used as first argument the slave
net_device. This slave device doesn't have the batadv_priv private data
which is access by batadv_info.
Writing to this file with CONFIG_BATMAN_ADV_DEBUG enabled can either lead
to a segfault or to memory corruption.
Fixes: c513176e4b7a ("batman-adv: add throughput override attribute to hard_ifaces")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/ddf99b78e255530cbadc0f67656a549e19520280
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index f2eef43bd2ec5b798ba552ff14eedcfa734b39d6..3a76e8970c025ca6917d6cd15d1382f685cd3532 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -1090,8 +1090,9 @@ static ssize_t batadv_store_throughput_override(struct kobject *kobj,
if (old_tp_override == tp_override)
goto out;
- batadv_info(net_dev, "%s: Changing from: %u.%u MBit to: %u.%u MBit\n",
- "throughput_override",
+ batadv_info(hard_iface->soft_iface,
+ "%s: %s: Changing from: %u.%u MBit to: %u.%u MBit\n",
+ "throughput_override", net_dev->name,
old_tp_override / 10, old_tp_override % 10,
tp_override / 10, tp_override % 10);

View file

@ -0,0 +1,105 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Fri, 31 Aug 2018 16:56:29 +0200
Subject: batman-adv: Fix segfault when writing to sysfs elp_interval
The per hardif sysfs file "batman_adv/elp_interval" is using the generic
functions to store/show uint values. The helper __batadv_store_uint_attr
requires the softif net_device as parameter to print the resulting change
as info text when the users writes to this file. It uses the helper
function batadv_info to add it at the same time to the kernel ring buffer
and to the batman-adv debug log (when CONFIG_BATMAN_ADV_DEBUG is enabled).
The function batadv_info requires as first parameter the batman-adv softif
net_device. This parameter is then used to find the private buffer which
contains the debug log for this batman-adv interface. But
batadv_store_throughput_override used as first argument the slave
net_device. This slave device doesn't have the batadv_priv private data
which is access by batadv_info.
Writing to this file with CONFIG_BATMAN_ADV_DEBUG enabled can either lead
to a segfault or to memory corruption.
Fixes: ec46535b8275 ("batman-adv: Add hard_iface specific sysfs wrapper macros for UINT")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/848be9859b0109a6e428f92f21f2e660153b1c75
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index 3a76e8970c025ca6917d6cd15d1382f685cd3532..09427fc6494a157554d8b19f3481a878a9f97bba 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -188,7 +188,8 @@ ssize_t batadv_store_##_name(struct kobject *kobj, \
\
return __batadv_store_uint_attr(buff, count, _min, _max, \
_post_func, attr, \
- &bat_priv->_var, net_dev); \
+ &bat_priv->_var, net_dev, \
+ NULL); \
}
#define BATADV_ATTR_SIF_SHOW_UINT(_name, _var) \
@@ -262,7 +263,9 @@ ssize_t batadv_store_##_name(struct kobject *kobj, \
\
length = __batadv_store_uint_attr(buff, count, _min, _max, \
_post_func, attr, \
- &hard_iface->_var, net_dev); \
+ &hard_iface->_var, \
+ hard_iface->soft_iface, \
+ net_dev); \
\
batadv_hardif_put(hard_iface); \
return length; \
@@ -356,10 +359,12 @@ __batadv_store_bool_attr(char *buff, size_t count,
static int batadv_store_uint_attr(const char *buff, size_t count,
struct net_device *net_dev,
+ struct net_device *slave_dev,
const char *attr_name,
unsigned int min, unsigned int max,
atomic_t *attr)
{
+ char ifname[IFNAMSIZ + 3] = "";
unsigned long uint_val;
int ret;
@@ -385,8 +390,11 @@ static int batadv_store_uint_attr(const char *buff, size_t count,
if (atomic_read(attr) == uint_val)
return count;
- batadv_info(net_dev, "%s: Changing from: %i to: %lu\n",
- attr_name, atomic_read(attr), uint_val);
+ if (slave_dev)
+ snprintf(ifname, sizeof(ifname), "%s: ", slave_dev->name);
+
+ batadv_info(net_dev, "%s: %sChanging from: %i to: %lu\n",
+ attr_name, ifname, atomic_read(attr), uint_val);
atomic_set(attr, uint_val);
return count;
@@ -397,12 +405,13 @@ static ssize_t __batadv_store_uint_attr(const char *buff, size_t count,
void (*post_func)(struct net_device *),
const struct attribute *attr,
atomic_t *attr_store,
- struct net_device *net_dev)
+ struct net_device *net_dev,
+ struct net_device *slave_dev)
{
int ret;
- ret = batadv_store_uint_attr(buff, count, net_dev, attr->name, min, max,
- attr_store);
+ ret = batadv_store_uint_attr(buff, count, net_dev, slave_dev,
+ attr->name, min, max, attr_store);
if (post_func && ret)
post_func(net_dev);
@@ -571,7 +580,7 @@ static ssize_t batadv_store_gw_sel_class(struct kobject *kobj,
return __batadv_store_uint_attr(buff, count, 1, BATADV_TQ_MAX_VALUE,
batadv_post_gw_reselect, attr,
&bat_priv->gw.sel_class,
- bat_priv->soft_iface);
+ bat_priv->soft_iface, NULL);
}
static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,

View file

@ -0,0 +1,42 @@
From: Marek Lindner <mareklindner@neomailbox.ch>
Date: Fri, 7 Sep 2018 05:45:54 +0800
Subject: batman-adv: fix backbone_gw refcount on queue_work() failure
The backbone_gw refcounter is to be decreased by the queued work and
currently is never decreased if the queue_work() call fails.
Fix by checking the queue_work() return value and decrease refcount
if necessary.
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/24d83a50421c1c5d39cd9c015516a1a293ae8d0c
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index a2de5a44bd41bf5c3d521d29b72e0b225a3ace05..58c093caf49e804c1e11426959d70e79f1729d41 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -1772,6 +1772,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
{
struct batadv_bla_backbone_gw *backbone_gw;
struct ethhdr *ethhdr;
+ bool ret;
ethhdr = eth_hdr(skb);
@@ -1795,8 +1796,13 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
if (unlikely(!backbone_gw))
return true;
- queue_work(batadv_event_workqueue, &backbone_gw->report_work);
- /* backbone_gw is unreferenced in the report work function function */
+ ret = queue_work(batadv_event_workqueue, &backbone_gw->report_work);
+
+ /* backbone_gw is unreferenced in the report work function function
+ * if queue_work() call was successful
+ */
+ if (!ret)
+ batadv_backbone_gw_put(backbone_gw);
return true;
}

View file

@ -0,0 +1,40 @@
From: Marek Lindner <mareklindner@neomailbox.ch>
Date: Fri, 7 Sep 2018 05:45:55 +0800
Subject: batman-adv: fix hardif_neigh refcount on queue_work() failure
The hardif_neigh refcounter is to be decreased by the queued work and
currently is never decreased if the queue_work() call fails.
Fix by checking the queue_work() return value and decrease refcount
if necessary.
Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/85100b602c127cecf1bcfd620d20eb867d685df2
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index 371028f82a0669e86155fee39ba955cbbde48e60..83b46654449df72ceda6ca3177f72e7faf0603ab 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -255,6 +255,7 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
struct batadv_priv *bat_priv;
struct sk_buff *skb;
u32 elp_interval;
+ bool ret;
bat_v = container_of(work, struct batadv_hard_iface_bat_v, elp_wq.work);
hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v);
@@ -316,8 +317,11 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
* may sleep and that is not allowed in an rcu protected
* context. Therefore schedule a task for that.
*/
- queue_work(batadv_event_workqueue,
- &hardif_neigh->bat_v.metric_work);
+ ret = queue_work(batadv_event_workqueue,
+ &hardif_neigh->bat_v.metric_work);
+
+ if (!ret)
+ batadv_hardif_neigh_put(hardif_neigh);
}
rcu_read_unlock();

View file

@ -0,0 +1,78 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 6 Sep 2018 14:35:24 +0200
Subject: batman-adv: Prevent duplicated gateway_node entry
The function batadv_gw_node_add is responsible for adding new gw_node to
the gateway_list. It is expecting that the caller already checked that
there is not already an entry with the same key or not.
But the lock for the list is only held when the list is really modified.
This could lead to duplicated entries because another context could create
an entry with the same key between the check and the list manipulation.
The check and the manipulation of the list must therefore be in the same
locked code section.
Fixes: bc3538cabac5 ("batman-adv: adding gateway functionality")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/69b3ca714eba608fe79a51ccd89ce7050ee0b770
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 8b198ee798c910b40997ed9ca867fc931c53dcc3..140c61a3f1ecfec4fe23c5ddca19e18e2e86fd56 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -32,6 +32,7 @@
#include <linux/kernel.h>
#include <linux/kref.h>
#include <linux/list.h>
+#include <linux/lockdep.h>
#include <linux/netdevice.h>
#include <linux/netlink.h>
#include <linux/rculist.h>
@@ -348,6 +349,9 @@ void batadv_gw_check_election(struct batadv_priv *bat_priv,
* @bat_priv: the bat priv with all the soft interface information
* @orig_node: originator announcing gateway capabilities
* @gateway: announced bandwidth information
+ *
+ * Has to be called with the appropriate locks being acquired
+ * (gw.list_lock).
*/
static void batadv_gw_node_add(struct batadv_priv *bat_priv,
struct batadv_orig_node *orig_node,
@@ -355,6 +359,8 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
{
struct batadv_gw_node *gw_node;
+ lockdep_assert_held(&bat_priv->gw.list_lock);
+
if (gateway->bandwidth_down == 0)
return;
@@ -369,10 +375,8 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
- spin_lock_bh(&bat_priv->gw.list_lock);
kref_get(&gw_node->refcount);
hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.gateway_list);
- spin_unlock_bh(&bat_priv->gw.list_lock);
batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
"Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n",
@@ -428,11 +432,14 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
{
struct batadv_gw_node *gw_node, *curr_gw = NULL;
+ spin_lock_bh(&bat_priv->gw.list_lock);
gw_node = batadv_gw_node_get(bat_priv, orig_node);
if (!gw_node) {
batadv_gw_node_add(bat_priv, orig_node, gateway);
+ spin_unlock_bh(&bat_priv->gw.list_lock);
goto out;
}
+ spin_unlock_bh(&bat_priv->gw.list_lock);
if (gw_node->bandwidth_down == ntohl(gateway->bandwidth_down) &&
gw_node->bandwidth_up == ntohl(gateway->bandwidth_up))

View file

@ -0,0 +1,87 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 6 Sep 2018 14:35:25 +0200
Subject: batman-adv: Prevent duplicated nc_node entry
The function batadv_nc_get_nc_node is responsible for adding new nc_nodes
to the in_coding_list and out_coding_list. It first checks whether the
entry already is in the list or not. If it is, then the creation of a new
entry is aborted.
But the lock for the list is only held when the list is really modified.
This could lead to duplicated entries because another context could create
an entry with the same key between the check and the list manipulation.
The check and the manipulation of the list must therefore be in the same
locked code section.
Fixes: 3ed7ada3f0bb ("batman-adv: network coding - detect coding nodes and remove these after timeout")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/bab8447ad1850b25188f9652c0c52f8e58acd656
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c
index c3578444f3cbe759a5385ac460ccb9d41ae1c4de..34caf129a9bf5531360f798be6a7059bad26a50f 100644
--- a/net/batman-adv/network-coding.c
+++ b/net/batman-adv/network-coding.c
@@ -854,24 +854,6 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv,
spinlock_t *lock; /* Used to lock list selected by "int in_coding" */
struct list_head *list;
- /* Check if nc_node is already added */
- nc_node = batadv_nc_find_nc_node(orig_node, orig_neigh_node, in_coding);
-
- /* Node found */
- if (nc_node)
- return nc_node;
-
- nc_node = kzalloc(sizeof(*nc_node), GFP_ATOMIC);
- if (!nc_node)
- return NULL;
-
- /* Initialize nc_node */
- INIT_LIST_HEAD(&nc_node->list);
- kref_init(&nc_node->refcount);
- ether_addr_copy(nc_node->addr, orig_node->orig);
- kref_get(&orig_neigh_node->refcount);
- nc_node->orig_node = orig_neigh_node;
-
/* Select ingoing or outgoing coding node */
if (in_coding) {
lock = &orig_neigh_node->in_coding_list_lock;
@@ -881,13 +863,34 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv,
list = &orig_neigh_node->out_coding_list;
}
+ spin_lock_bh(lock);
+
+ /* Check if nc_node is already added */
+ nc_node = batadv_nc_find_nc_node(orig_node, orig_neigh_node, in_coding);
+
+ /* Node found */
+ if (nc_node)
+ goto unlock;
+
+ nc_node = kzalloc(sizeof(*nc_node), GFP_ATOMIC);
+ if (!nc_node)
+ goto unlock;
+
+ /* Initialize nc_node */
+ INIT_LIST_HEAD(&nc_node->list);
+ kref_init(&nc_node->refcount);
+ ether_addr_copy(nc_node->addr, orig_node->orig);
+ kref_get(&orig_neigh_node->refcount);
+ nc_node->orig_node = orig_neigh_node;
+
batadv_dbg(BATADV_DBG_NC, bat_priv, "Adding nc_node %pM -> %pM\n",
nc_node->addr, nc_node->orig_node->orig);
/* Add nc_node to orig_node */
- spin_lock_bh(lock);
kref_get(&nc_node->refcount);
list_add_tail_rcu(&nc_node->list, list);
+
+unlock:
spin_unlock_bh(lock);
return nc_node;

View file

@ -0,0 +1,78 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 6 Sep 2018 14:35:26 +0200
Subject: batman-adv: Prevent duplicated softif_vlan entry
The function batadv_softif_vlan_get is responsible for adding new
softif_vlan to the softif_vlan_list. It first checks whether the entry
already is in the list or not. If it is, then the creation of a new entry
is aborted.
But the lock for the list is only held when the list is really modified.
This could lead to duplicated entries because another context could create
an entry with the same key between the check and the list manipulation.
The check and the manipulation of the list must therefore be in the same
locked code section.
Fixes: 952cebb57518 ("batman-adv: add per VLAN interface attribute framework")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/023d3f64207e8b6a6e6d0718d98e239c5545ef0c
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index edeffcb9f3a24e1b53c2b4d705fb260717ac09c4..79d6ab78359db9c6a5df14e2e204c611ab134dfc 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -574,15 +574,20 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
struct batadv_softif_vlan *vlan;
int err;
+ spin_lock_bh(&bat_priv->softif_vlan_list_lock);
+
vlan = batadv_softif_vlan_get(bat_priv, vid);
if (vlan) {
batadv_softif_vlan_put(vlan);
+ spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
return -EEXIST;
}
vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC);
- if (!vlan)
+ if (!vlan) {
+ spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
return -ENOMEM;
+ }
vlan->bat_priv = bat_priv;
vlan->vid = vid;
@@ -590,17 +595,23 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
atomic_set(&vlan->ap_isolation, 0);
- err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
- if (err) {
- kfree(vlan);
- return err;
- }
-
- spin_lock_bh(&bat_priv->softif_vlan_list_lock);
kref_get(&vlan->refcount);
hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list);
spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
+ /* batadv_sysfs_add_vlan cannot be in the spinlock section due to the
+ * sleeping behavior of the sysfs functions and the fs_reclaim lock
+ */
+ err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
+ if (err) {
+ /* ref for the function */
+ batadv_softif_vlan_put(vlan);
+
+ /* ref for the list */
+ batadv_softif_vlan_put(vlan);
+ return err;
+ }
+
/* add a new TT local entry. This one will be marked with the NOPURGE
* flag
*/

View file

@ -0,0 +1,56 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 6 Sep 2018 14:35:27 +0200
Subject: batman-adv: Prevent duplicated global TT entry
The function batadv_tt_global_orig_entry_add is responsible for adding new
tt_orig_list_entry to the orig_list. It first checks whether the entry
already is in the list or not. If it is, then the creation of a new entry
is aborted.
But the lock for the list is only held when the list is really modified.
This could lead to duplicated entries because another context could create
an entry with the same key between the check and the list manipulation.
The check and the manipulation of the list must therefore be in the same
locked code section.
Fixes: c5eb5bb30321 ("batman-adv: add reference counting for type batadv_tt_orig_list_entry")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/79097255a1a3e1bd1949be309af941181fbc7b36
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 9efbdd6348c4d69c525b3e0574d2b24db838c086..7502cb54c152d06d78c88d9f8fb841cada9f3b5d 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1613,6 +1613,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
{
struct batadv_tt_orig_list_entry *orig_entry;
+ spin_lock_bh(&tt_global->list_lock);
+
orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
if (orig_entry) {
/* refresh the ttvn: the current value could be a bogus one that
@@ -1635,11 +1637,9 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
orig_entry->flags = flags;
kref_init(&orig_entry->refcount);
- spin_lock_bh(&tt_global->list_lock);
kref_get(&orig_entry->refcount);
hlist_add_head_rcu(&orig_entry->list,
&tt_global->orig_list);
- spin_unlock_bh(&tt_global->list_lock);
atomic_inc(&tt_global->orig_list_count);
sync_flags:
@@ -1647,6 +1647,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
out:
if (orig_entry)
batadv_tt_orig_list_entry_put(orig_entry);
+
+ spin_unlock_bh(&tt_global->list_lock);
}
/**

View file

@ -0,0 +1,56 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Thu, 6 Sep 2018 14:35:28 +0200
Subject: batman-adv: Prevent duplicated tvlv handler
The function batadv_tvlv_handler_register is responsible for adding new
tvlv_handler to the handler_list. It first checks whether the entry
already is in the list or not. If it is, then the creation of a new entry
is aborted.
But the lock for the list is only held when the list is really modified.
This could lead to duplicated entries because another context could create
an entry with the same key between the check and the list manipulation.
The check and the manipulation of the list must therefore be in the same
locked code section.
Fixes: 0b6aa0d43767 ("batman-adv: tvlv - basic infrastructure")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Acked-by: Marek Lindner <mareklindner@neomailbox.ch>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/acabad79e01740525cf4ff8ce6e9a210b683d420
diff --git a/net/batman-adv/tvlv.c b/net/batman-adv/tvlv.c
index a637458205d16bf838f796383d8cc15ac861801b..40e69c9346d22c09481544b8b4dec56cad88b64a 100644
--- a/net/batman-adv/tvlv.c
+++ b/net/batman-adv/tvlv.c
@@ -529,15 +529,20 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
{
struct batadv_tvlv_handler *tvlv_handler;
+ spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
+
tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version);
if (tvlv_handler) {
+ spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
batadv_tvlv_handler_put(tvlv_handler);
return;
}
tvlv_handler = kzalloc(sizeof(*tvlv_handler), GFP_ATOMIC);
- if (!tvlv_handler)
+ if (!tvlv_handler) {
+ spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
return;
+ }
tvlv_handler->ogm_handler = optr;
tvlv_handler->unicast_handler = uptr;
@@ -547,7 +552,6 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
kref_init(&tvlv_handler->refcount);
INIT_HLIST_NODE(&tvlv_handler->list);
- spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
kref_get(&tvlv_handler->refcount);
hlist_add_head_rcu(&tvlv_handler->list, &bat_priv->tvlv.handler_list);
spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);

View file

@ -0,0 +1,52 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Tue, 30 Oct 2018 12:17:10 +0100
Subject: batman-adv: Use explicit tvlv padding for ELP packets
The announcement messages of batman-adv COMPAT_VERSION 15 have the
possibility to announce additional information via a dynamic TVLV part.
This part is optional for the ELP packets and currently not parsed by the
Linux implementation. Still out-of-tree versions are using it to transport
things like neighbor hashes to optimize the rebroadcast behavior.
Since the ELP broadcast packets are smaller than the minimal ethernet
packet, it often has to be padded. This is often done (as specified in
RFC894) with octets of zero and thus work perfectly fine with the TVLV
part (making it a zero length and thus empty). But not all ethernet
compatible hardware seems to follow this advice. To avoid ambiguous
situations when parsing the TVLV header, just force the 4 bytes (TVLV
length + padding) after the required ELP header to zero.
Fixes: a4b88af77e28 ("batman-adv: ELP - adding basic infrastructure")
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/974337ee9773c4bd0a2d5c322306cf2bea445e11
diff --git a/net/batman-adv/bat_v_elp.c b/net/batman-adv/bat_v_elp.c
index 83b46654449df72ceda6ca3177f72e7faf0603ab..9aa3c7b2e9bad6c50b2939b6dbf5a9a2e713b93b 100644
--- a/net/batman-adv/bat_v_elp.c
+++ b/net/batman-adv/bat_v_elp.c
@@ -339,19 +339,21 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
*/
int batadv_v_elp_iface_enable(struct batadv_hard_iface *hard_iface)
{
+ static const size_t tvlv_padding = sizeof(__be32);
struct batadv_elp_packet *elp_packet;
unsigned char *elp_buff;
u32 random_seqno;
size_t size;
int res = -ENOMEM;
- size = ETH_HLEN + NET_IP_ALIGN + BATADV_ELP_HLEN;
+ size = ETH_HLEN + NET_IP_ALIGN + BATADV_ELP_HLEN + tvlv_padding;
hard_iface->bat_v.elp_skb = dev_alloc_skb(size);
if (!hard_iface->bat_v.elp_skb)
goto out;
skb_reserve(hard_iface->bat_v.elp_skb, ETH_HLEN + NET_IP_ALIGN);
- elp_buff = skb_put_zero(hard_iface->bat_v.elp_skb, BATADV_ELP_HLEN);
+ elp_buff = skb_put_zero(hard_iface->bat_v.elp_skb,
+ BATADV_ELP_HLEN + tvlv_padding);
elp_packet = (struct batadv_elp_packet *)elp_buff;
elp_packet->packet_type = BATADV_ELP;

View file

@ -0,0 +1,41 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Wed, 7 Nov 2018 23:09:12 +0100
Subject: batman-adv: Expand merged fragment buffer for full packet
The complete size ("total_size") of the fragmented packet is stored in the
fragment header and in the size of the fragment chain. When the fragments
are ready for merge, the skbuff's tail of the first fragment is expanded to
have enough room after the data pointer for at least total_size. This means
that it gets expanded by total_size - first_skb->len.
But this is ignoring the fact that after expanding the buffer, the fragment
header is pulled by from this buffer. Assuming that the tailroom of the
buffer was already 0, the buffer after the data pointer of the skbuff is
now only total_size - len(fragment_header) large. When the merge function
is then processing the remaining fragments, the code to copy the data over
to the merged skbuff will cause an skb_over_panic when it tries to actually
put enough data to fill the total_size bytes of the packet.
The size of the skb_pull must therefore also be taken into account when the
buffer's tailroom is expanded.
Fixes: 9b3eab61754d ("batman-adv: Receive fragmented packets and merge")
Reported-by: Martin Weinelt <martin@darmstadt.freifunk.net>
Co-authored-by: Linus Lüssing <linus.luessing@c0d3.blue>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: other, https://patchwork.open-mesh.org/patch/17616/
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c
index 0fddc17106bd8a0e3f064fee9adba7c226f34682..5b71a289d04fc80de6c20e7a24d621727c77825a 100644
--- a/net/batman-adv/fragmentation.c
+++ b/net/batman-adv/fragmentation.c
@@ -275,7 +275,7 @@ batadv_frag_merge_packets(struct hlist_head *chain)
kfree(entry);
packet = (struct batadv_frag_packet *)skb_out->data;
- size = ntohs(packet->total_size);
+ size = ntohs(packet->total_size) + hdr_size;
/* Make room for the rest of the fragments. */
if (pskb_expand_head(skb_out, 0, size - skb_out->len, GFP_ATOMIC) < 0) {

View file

@ -0,0 +1,45 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sun, 30 Dec 2018 12:46:01 +0100
Subject: batman-adv: Avoid WARN on net_device without parent in netns
It is not allowed to use WARN* helpers on potential incorrect input from
the user or transient problems because systems configured as panic_on_warn
will reboot due to such a problem.
A NULL return value of __dev_get_by_index can be caused by various problems
which can either be related to the system configuration or problems
(incorrectly returned network namespaces) in other (virtual) net_device
drivers. batman-adv should not cause a (harmful) WARN in this situation and
instead only report it via a simple message.
Fixes: 3d48811b27f5 ("batman-adv: prevent using any virtual device created on batman-adv as hard-interface")
Reported-by: syzbot+c764de0fcfadca9a8595@syzkaller.appspotmail.com
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/59ad04405be86f648fd83d81d2fd0a78f215a43b
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index 2f0d42f2f913e74cf10c0c6ce89320434994cac5..08690d06b7be2b25ca3f009394763c7083c70644 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -20,7 +20,6 @@
#include "main.h"
#include <linux/atomic.h>
-#include <linux/bug.h>
#include <linux/byteorder/generic.h>
#include <linux/errno.h>
#include <linux/gfp.h>
@@ -179,8 +178,10 @@ static bool batadv_is_on_batman_iface(const struct net_device *net_dev)
parent_dev = __dev_get_by_index((struct net *)parent_net,
dev_get_iflink(net_dev));
/* if we got a NULL parent_dev there is something broken.. */
- if (WARN(!parent_dev, "Cannot find parent device"))
+ if (!parent_dev) {
+ pr_err("Cannot find parent device\n");
return false;
+ }
if (batadv_mutual_parents(net_dev, net, parent_dev, parent_net))
return false;

View file

@ -0,0 +1,36 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Mon, 31 Dec 2018 22:46:09 +0100
Subject: batman-adv: Force mac header to start of data on xmit
The caller of ndo_start_xmit may not already have called
skb_reset_mac_header. The returned value of skb_mac_header/eth_hdr
therefore can be in the wrong position and even outside the current skbuff.
This for example happens when the user binds to the device using a
PF_PACKET-SOCK_RAW with enabled qdisc-bypass:
int opt = 4;
setsockopt(sock, SOL_PACKET, PACKET_QDISC_BYPASS, &opt, sizeof(opt));
Since eth_hdr is used all over the codebase, the batadv_interface_tx
function must always take care of resetting it.
Fixes: fe28a94c01e1 ("batman-adv: receive packets directly using skbs")
Reported-by: syzbot+9d7405c7faa390e60b4e@syzkaller.appspotmail.com
Reported-by: syzbot+7d20bc3f1ddddc0f9079@syzkaller.appspotmail.com
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/74c4b0c50f19f986752ee18ed393732f4eed7a66
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index 79d6ab78359db9c6a5df14e2e204c611ab134dfc..d3f540ba2a1388a8aa693a539d01d6a1cad95b44 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -221,6 +221,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
netif_trans_update(soft_iface);
vid = batadv_get_vid(skb, 0);
+
+ skb_reset_mac_header(skb);
ethhdr = eth_hdr(skb);
switch (ntohs(ethhdr->h_proto)) {

View file

@ -0,0 +1,95 @@
From: Eric Dumazet <edumazet@google.com>
Date: Mon, 11 Feb 2019 14:41:22 -0800
Subject: batman-adv: fix uninit-value in batadv_interface_tx()
KMSAN reported batadv_interface_tx() was possibly using a
garbage value [1]
batadv_get_vid() does have a pskb_may_pull() call
but batadv_interface_tx() does not actually make sure
this did not fail.
[1]
BUG: KMSAN: uninit-value in batadv_interface_tx+0x908/0x1e40 net/batman-adv/soft-interface.c:231
CPU: 0 PID: 10006 Comm: syz-executor469 Not tainted 4.20.0-rc7+ #5
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+0x173/0x1d0 lib/dump_stack.c:113
kmsan_report+0x12e/0x2a0 mm/kmsan/kmsan.c:613
__msan_warning+0x82/0xf0 mm/kmsan/kmsan_instr.c:313
batadv_interface_tx+0x908/0x1e40 net/batman-adv/soft-interface.c:231
__netdev_start_xmit include/linux/netdevice.h:4356 [inline]
netdev_start_xmit include/linux/netdevice.h:4365 [inline]
xmit_one net/core/dev.c:3257 [inline]
dev_hard_start_xmit+0x607/0xc40 net/core/dev.c:3273
__dev_queue_xmit+0x2e42/0x3bc0 net/core/dev.c:3843
dev_queue_xmit+0x4b/0x60 net/core/dev.c:3876
packet_snd net/packet/af_packet.c:2928 [inline]
packet_sendmsg+0x8306/0x8f30 net/packet/af_packet.c:2953
sock_sendmsg_nosec net/socket.c:621 [inline]
sock_sendmsg net/socket.c:631 [inline]
__sys_sendto+0x8c4/0xac0 net/socket.c:1788
__do_sys_sendto net/socket.c:1800 [inline]
__se_sys_sendto+0x107/0x130 net/socket.c:1796
__x64_sys_sendto+0x6e/0x90 net/socket.c:1796
do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:291
entry_SYSCALL_64_after_hwframe+0x63/0xe7
RIP: 0033:0x441889
Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 bb 10 fc ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007ffdda6fd468 EFLAGS: 00000216 ORIG_RAX: 000000000000002c
RAX: ffffffffffffffda RBX: 0000000000000002 RCX: 0000000000441889
RDX: 000000000000000e RSI: 00000000200000c0 RDI: 0000000000000003
RBP: 0000000000000003 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000216 R12: 00007ffdda6fd4c0
R13: 00007ffdda6fd4b0 R14: 0000000000000000 R15: 0000000000000000
Uninit was created at:
kmsan_save_stack_with_flags mm/kmsan/kmsan.c:204 [inline]
kmsan_internal_poison_shadow+0x92/0x150 mm/kmsan/kmsan.c:158
kmsan_kmalloc+0xa6/0x130 mm/kmsan/kmsan_hooks.c:176
kmsan_slab_alloc+0xe/0x10 mm/kmsan/kmsan_hooks.c:185
slab_post_alloc_hook mm/slab.h:446 [inline]
slab_alloc_node mm/slub.c:2759 [inline]
__kmalloc_node_track_caller+0xe18/0x1030 mm/slub.c:4383
__kmalloc_reserve net/core/skbuff.c:137 [inline]
__alloc_skb+0x309/0xa20 net/core/skbuff.c:205
alloc_skb include/linux/skbuff.h:998 [inline]
alloc_skb_with_frags+0x1c7/0xac0 net/core/skbuff.c:5220
sock_alloc_send_pskb+0xafd/0x10e0 net/core/sock.c:2083
packet_alloc_skb net/packet/af_packet.c:2781 [inline]
packet_snd net/packet/af_packet.c:2872 [inline]
packet_sendmsg+0x661a/0x8f30 net/packet/af_packet.c:2953
sock_sendmsg_nosec net/socket.c:621 [inline]
sock_sendmsg net/socket.c:631 [inline]
__sys_sendto+0x8c4/0xac0 net/socket.c:1788
__do_sys_sendto net/socket.c:1800 [inline]
__se_sys_sendto+0x107/0x130 net/socket.c:1796
__x64_sys_sendto+0x6e/0x90 net/socket.c:1796
do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:291
entry_SYSCALL_64_after_hwframe+0x63/0xe7
Fixes: 48628bb9419f ("batman-adv: softif bridge loop avoidance")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: syzbot <syzkaller@googlegroups.com>
Cc: Marek Lindner <mareklindner@neomailbox.ch>
Cc: Simon Wunderlich <sw@simonwunderlich.de>
Cc: Antonio Quartulli <a@unstable.cc>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/35482922b38bb5f5b03b0e92bc58cec2b7c77cdf
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index d3f540ba2a1388a8aa693a539d01d6a1cad95b44..97e28907a0acbb3d64d8ceebf7b1df13dc396300 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -227,6 +227,8 @@ static int batadv_interface_tx(struct sk_buff *skb,
switch (ntohs(ethhdr->h_proto)) {
case ETH_P_8021Q:
+ if (!pskb_may_pull(skb, sizeof(*vhdr)))
+ goto dropped;
vhdr = vlan_eth_hdr(skb);
/* drop batman-in-batman packets to prevent loops */

View file

@ -0,0 +1,65 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sat, 23 Feb 2019 15:09:04 +0100
Subject: batman-adv: Reduce claim hash refcnt only for removed entry
The batadv_hash_remove is a function which searches the hashtable for an
entry using a needle, a hashtable bucket selection function and a compare
function. It will lock the bucket list and delete an entry when the compare
function matches it with the needle. It returns the pointer to the
hlist_node which matches or NULL when no entry matches the needle.
The batadv_bla_del_claim is not itself protected in anyway to avoid that
any other function is modifying the hashtable between the search for the
entry and the call to batadv_hash_remove. It can therefore happen that the
entry either doesn't exist anymore or an entry was deleted which is not the
same object as the needle. In such an situation, the reference counter (for
the reference stored in the hashtable) must not be reduced for the needle.
Instead the reference counter of the actually removed entry has to be
reduced.
Otherwise the reference counter will underflow and the object might be
freed before all its references were dropped. The kref helpers reported
this problem as:
refcount_t: underflow; use-after-free.
Fixes: a9ce0dc43e2c ("batman-adv: add basic bridge loop avoidance code")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/3a7af70ae7c4209324dbb08b91e013c17108bdd6
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index 58c093caf49e804c1e11426959d70e79f1729d41..0842080a71f4ac89b3fbebc4b95c6c27d1cc4254 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -803,6 +803,8 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
const u8 *mac, const unsigned short vid)
{
struct batadv_bla_claim search_claim, *claim;
+ struct batadv_bla_claim *claim_removed_entry;
+ struct hlist_node *claim_removed_node;
ether_addr_copy(search_claim.addr, mac);
search_claim.vid = vid;
@@ -813,10 +815,18 @@ static void batadv_bla_del_claim(struct batadv_priv *bat_priv,
batadv_dbg(BATADV_DBG_BLA, bat_priv, "%s(): %pM, vid %d\n", __func__,
mac, batadv_print_vid(vid));
- batadv_hash_remove(bat_priv->bla.claim_hash, batadv_compare_claim,
- batadv_choose_claim, claim);
- batadv_claim_put(claim); /* reference from the hash is gone */
+ claim_removed_node = batadv_hash_remove(bat_priv->bla.claim_hash,
+ batadv_compare_claim,
+ batadv_choose_claim, claim);
+ if (!claim_removed_node)
+ goto free_claim;
+ /* reference from the hash is gone */
+ claim_removed_entry = hlist_entry(claim_removed_node,
+ struct batadv_bla_claim, hash_entry);
+ batadv_claim_put(claim_removed_entry);
+
+free_claim:
/* don't need the reference from hash_find() anymore */
batadv_claim_put(claim);
}

View file

@ -0,0 +1,69 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sat, 23 Feb 2019 15:09:05 +0100
Subject: batman-adv: Reduce tt_local hash refcnt only for removed entry
The batadv_hash_remove is a function which searches the hashtable for an
entry using a needle, a hashtable bucket selection function and a compare
function. It will lock the bucket list and delete an entry when the compare
function matches it with the needle. It returns the pointer to the
hlist_node which matches or NULL when no entry matches the needle.
The batadv_tt_local_remove is not itself protected in anyway to avoid that
any other function is modifying the hashtable between the search for the
entry and the call to batadv_hash_remove. It can therefore happen that the
entry either doesn't exist anymore or an entry was deleted which is not the
same object as the needle. In such an situation, the reference counter (for
the reference stored in the hashtable) must not be reduced for the needle.
Instead the reference counter of the actually removed entry has to be
reduced.
Otherwise the reference counter will underflow and the object might be
freed before all its references were dropped. The kref helpers reported
this problem as:
refcount_t: underflow; use-after-free.
Fixes: af912d77181f ("batman-adv: protect tt_local_entry from concurrent delete events")
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/0c86a0511e97de502276900c5d6f22b09e042d21
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 7502cb54c152d06d78c88d9f8fb841cada9f3b5d..d2ecfdbdc64956b238f0554b4c354df9a9e9f26a 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -1332,9 +1332,10 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr,
unsigned short vid, const char *message,
bool roaming)
{
+ struct batadv_tt_local_entry *tt_removed_entry;
struct batadv_tt_local_entry *tt_local_entry;
u16 flags, curr_flags = BATADV_NO_FLAGS;
- void *tt_entry_exists;
+ struct hlist_node *tt_removed_node;
tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
if (!tt_local_entry)
@@ -1363,15 +1364,18 @@ u16 batadv_tt_local_remove(struct batadv_priv *bat_priv, const u8 *addr,
*/
batadv_tt_local_event(bat_priv, tt_local_entry, BATADV_TT_CLIENT_DEL);
- tt_entry_exists = batadv_hash_remove(bat_priv->tt.local_hash,
+ tt_removed_node = batadv_hash_remove(bat_priv->tt.local_hash,
batadv_compare_tt,
batadv_choose_tt,
&tt_local_entry->common);
- if (!tt_entry_exists)
+ if (!tt_removed_node)
goto out;
- /* extra call to free the local tt entry */
- batadv_tt_local_entry_put(tt_local_entry);
+ /* drop reference of remove hash entry */
+ tt_removed_entry = hlist_entry(tt_removed_node,
+ struct batadv_tt_local_entry,
+ common.hash_entry);
+ batadv_tt_local_entry_put(tt_removed_entry);
out:
if (tt_local_entry)

View file

@ -0,0 +1,66 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sat, 23 Feb 2019 15:09:06 +0100
Subject: batman-adv: Reduce tt_global hash refcnt only for removed entry
The batadv_hash_remove is a function which searches the hashtable for an
entry using a needle, a hashtable bucket selection function and a compare
function. It will lock the bucket list and delete an entry when the compare
function matches it with the needle. It returns the pointer to the
hlist_node which matches or NULL when no entry matches the needle.
The batadv_tt_global_free is not itself protected in anyway to avoid that
any other function is modifying the hashtable between the search for the
entry and the call to batadv_hash_remove. It can therefore happen that the
entry either doesn't exist anymore or an entry was deleted which is not the
same object as the needle. In such an situation, the reference counter (for
the reference stored in the hashtable) must not be reduced for the needle.
Instead the reference counter of the actually removed entry has to be
reduced.
Otherwise the reference counter will underflow and the object might be
freed before all its references were dropped. The kref helpers reported
this problem as:
refcount_t: underflow; use-after-free.
Fixes: 7bad46397eff ("batman-adv: protect the local and the global trans-tables with rcu")
Reported-by: Martin Weinelt <martin@linuxlounge.net>
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/bd6df24da0063fe50828c287d05bdc1876f4f6cc
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index d2ecfdbdc64956b238f0554b4c354df9a9e9f26a..554fd886e652c7c206ff43a5627d342ccbcc2123 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -616,14 +616,26 @@ static void batadv_tt_global_free(struct batadv_priv *bat_priv,
struct batadv_tt_global_entry *tt_global,
const char *message)
{
+ struct batadv_tt_global_entry *tt_removed_entry;
+ struct hlist_node *tt_removed_node;
+
batadv_dbg(BATADV_DBG_TT, bat_priv,
"Deleting global tt entry %pM (vid: %d): %s\n",
tt_global->common.addr,
batadv_print_vid(tt_global->common.vid), message);
- batadv_hash_remove(bat_priv->tt.global_hash, batadv_compare_tt,
- batadv_choose_tt, &tt_global->common);
- batadv_tt_global_entry_put(tt_global);
+ tt_removed_node = batadv_hash_remove(bat_priv->tt.global_hash,
+ batadv_compare_tt,
+ batadv_choose_tt,
+ &tt_global->common);
+ if (!tt_removed_node)
+ return;
+
+ /* drop reference of remove hash entry */
+ tt_removed_entry = hlist_entry(tt_removed_node,
+ struct batadv_tt_global_entry,
+ common.hash_entry);
+ batadv_tt_global_entry_put(tt_removed_entry);
}
/**

View file

@ -0,0 +1,103 @@
From: Linus Lüssing <linus.luessing@c0d3.blue>
Date: Wed, 24 Apr 2019 03:19:14 +0200
Subject: batman-adv: mcast: fix multicast tt/tvlv worker locking
Syzbot has reported some issues with the locking assumptions made for
the multicast tt/tvlv worker: It was able to trigger the WARN_ON() in
batadv_mcast_mla_tt_retract() and batadv_mcast_mla_tt_add().
While hard/not reproduceable for us so far it seems that the
delayed_work_pending() we use might not be quite safe from reordering.
Therefore this patch adds an explicit, new spinlock to protect the
update of the mla_list and flags in bat_priv and then removes the
WARN_ON(delayed_work_pending()).
Reported-by: syzbot+83f2d54ec6b7e417e13f@syzkaller.appspotmail.com
Reported-by: syzbot+050927a651272b145a5d@syzkaller.appspotmail.com
Reported-by: syzbot+979ffc89b87309b1b94b@syzkaller.appspotmail.com
Reported-by: syzbot+f9f3f388440283da2965@syzkaller.appspotmail.com
Fixes: 40b384052672 ("batman-adv: Use own timer for multicast TT and TVLV updates")
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/b736cf8119cfbc9d95fef90c8832fdec6e8f29c7
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c
index 53b329d24461819b4cf0d4118cfa5b0eb8d7261b..0286c651468443197434ccf0fcf25aaa66a0c7e9 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -160,6 +160,7 @@ int batadv_mesh_init(struct net_device *soft_iface)
spin_lock_init(&bat_priv->tt.commit_lock);
spin_lock_init(&bat_priv->gw.list_lock);
#ifdef CONFIG_BATMAN_ADV_MCAST
+ spin_lock_init(&bat_priv->mcast.mla_lock);
spin_lock_init(&bat_priv->mcast.want_lists_lock);
#endif
spin_lock_init(&bat_priv->tvlv.container_list_lock);
diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c
index a35f597e8c8bf4f15ad0f01aff29849d2bebe36f..39640d3d6fbdf8244344db6e79f2d769eb0972d9 100644
--- a/net/batman-adv/multicast.c
+++ b/net/batman-adv/multicast.c
@@ -325,8 +325,6 @@ static void batadv_mcast_mla_list_free(struct hlist_head *mcast_list)
* translation table except the ones listed in the given mcast_list.
*
* If mcast_list is NULL then all are retracted.
- *
- * Do not call outside of the mcast worker! (or cancel mcast worker first)
*/
static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,
struct hlist_head *mcast_list)
@@ -334,8 +332,6 @@ static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,
struct batadv_hw_addr *mcast_entry;
struct hlist_node *tmp;
- WARN_ON(delayed_work_pending(&bat_priv->mcast.work));
-
hlist_for_each_entry_safe(mcast_entry, tmp, &bat_priv->mcast.mla_list,
list) {
if (mcast_list &&
@@ -359,8 +355,6 @@ static void batadv_mcast_mla_tt_retract(struct batadv_priv *bat_priv,
*
* Adds multicast listener announcements from the given mcast_list to the
* translation table if they have not been added yet.
- *
- * Do not call outside of the mcast worker! (or cancel mcast worker first)
*/
static void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv,
struct hlist_head *mcast_list)
@@ -368,8 +362,6 @@ static void batadv_mcast_mla_tt_add(struct batadv_priv *bat_priv,
struct batadv_hw_addr *mcast_entry;
struct hlist_node *tmp;
- WARN_ON(delayed_work_pending(&bat_priv->mcast.work));
-
if (!mcast_list)
return;
@@ -658,7 +650,10 @@ static void batadv_mcast_mla_update(struct work_struct *work)
priv_mcast = container_of(delayed_work, struct batadv_priv_mcast, work);
bat_priv = container_of(priv_mcast, struct batadv_priv, mcast);
+ spin_lock(&bat_priv->mcast.mla_lock);
__batadv_mcast_mla_update(bat_priv);
+ spin_unlock(&bat_priv->mcast.mla_lock);
+
batadv_mcast_start_timer(bat_priv);
}
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 476b052ad9824d4cbcd6218dce40b603e3400fd2..6d07898d8d1a21007b3e68d5d2511b478110f659 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1215,6 +1215,11 @@ struct batadv_priv_mcast {
/** @num_disabled: number of nodes that have no mcast tvlv */
atomic_t num_disabled;
+ /**
+ * @mla_lock: a lock protecting mla_list and mla_flags
+ */
+ spinlock_t mla_lock;
+
/**
* @num_want_all_unsnoopables: number of nodes wanting unsnoopable IP
* traffic

View file

@ -0,0 +1,28 @@
From: Jeremy Sowden <jeremy@azazel.net>
Date: Tue, 21 May 2019 20:58:57 +0100
Subject: batman-adv: fix for leaked TVLV handler.
A handler for BATADV_TVLV_ROAM was being registered when the
translation-table was initialized, but not unregistered when the
translation-table was freed. Unregister it.
Fixes: 3de4e64df0f1 ("batman-adv: tvlv - convert roaming adv packet to use tvlv unicast packets")
Reported-by: syzbot+d454a826e670502484b8@syzkaller.appspotmail.com
Signed-off-by: Jeremy Sowden <jeremy@azazel.net>
Signed-off-by: Sven Eckelmann <sven@narfation.org
Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/87445d81c360a5f9833546114e98ffd2c1fd3a4d
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index 554fd886e652c7c206ff43a5627d342ccbcc2123..c29aadc5bd8b2020ba67779c517cc1e4ea9f6569 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -3821,6 +3821,8 @@ static void batadv_tt_purge(struct work_struct *work)
*/
void batadv_tt_free(struct batadv_priv *bat_priv)
{
+ batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_ROAM, 1);
+
batadv_tvlv_container_unregister(bat_priv, BATADV_TVLV_TT, 1);
batadv_tvlv_handler_unregister(bat_priv, BATADV_TVLV_TT, 1);

View file

@ -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);

View file

@ -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;
}
/**

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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 */

View file

@ -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;
};

View file

@ -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;
};
/**

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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);
}

View file

@ -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)

View file

@ -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);

View file

@ -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)

View file

@ -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);

View file

@ -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);

View file

@ -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;
}

View file

@ -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

View file

@ -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>

View file

@ -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))

View file

@ -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)

View file

@ -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);

View file

@ -1,121 +0,0 @@
/* Please avoid adding hacks here - instead add it to mac80211/backports.git */
#undef CONFIG_MODULE_STRIPPED
#include <linux/version.h> /* LINUX_VERSION_CODE */
#include <linux/types.h>
#if LINUX_VERSION_IS_LESS(6, 0, 0)
#define __vstring(item, fmt, ap) __dynamic_array(char, item, 256)
#define __assign_vstr(dst, fmt, va) \
WARN_ON_ONCE(vsnprintf(__get_dynamic_array(dst), 256, fmt, *va) >= 256)
#endif /* LINUX_VERSION_IS_LESS(6, 0, 0) */
#if LINUX_VERSION_IS_LESS(6, 2, 0)
#include <linux/random.h>
#define genl_split_ops genl_ops
static inline u32 batadv_get_random_u32_below(u32 ep_ro)
{
return prandom_u32_max(ep_ro);
}
#define get_random_u32_below batadv_get_random_u32_below
#endif /* LINUX_VERSION_IS_LESS(6, 2, 0) */
#if LINUX_VERSION_IS_LESS(6, 4, 0) && \
!(LINUX_VERSION_IS_GEQ(5, 10, 205) && LINUX_VERSION_IS_LESS(5, 11, 0)) && \
!(LINUX_VERSION_IS_GEQ(5, 15, 144) && LINUX_VERSION_IS_LESS(5, 16, 0)) && \
!(LINUX_VERSION_IS_GEQ(6, 1, 69) && LINUX_VERSION_IS_LESS(6, 2, 0))
#include <linux/if_vlan.h>
/* Prefer this version in TX path, instead of
* skb_reset_mac_header() + vlan_eth_hdr()
*/
static inline struct vlan_ethhdr *skb_vlan_eth_hdr(const struct sk_buff *skb)
{
return (struct vlan_ethhdr *)skb->data;
}
#endif /* LINUX_VERSION_IS_LESS(6, 4, 0) */
/* <DECLARE_EWMA> */
#include <linux/version.h>
#include_next <linux/average.h>
#include <linux/bug.h>
#ifdef DECLARE_EWMA
#undef DECLARE_EWMA
#endif /* DECLARE_EWMA */
/*
* Exponentially weighted moving average (EWMA)
*
* This implements a fixed-precision EWMA algorithm, with both the
* precision and fall-off coefficient determined at compile-time
* and built into the generated helper funtions.
*
* The first argument to the macro is the name that will be used
* for the struct and helper functions.
*
* The second argument, the precision, expresses how many bits are
* used for the fractional part of the fixed-precision values.
*
* The third argument, the weight reciprocal, determines how the
* new values will be weighed vs. the old state, new values will
* get weight 1/weight_rcp and old values 1-1/weight_rcp. Note
* that this parameter must be a power of two for efficiency.
*/
#define DECLARE_EWMA(name, _precision, _weight_rcp) \
struct ewma_##name { \
unsigned long internal; \
}; \
static inline void ewma_##name##_init(struct ewma_##name *e) \
{ \
BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
/* \
* Even if you want to feed it just 0/1 you should have \
* some bits for the non-fractional part... \
*/ \
BUILD_BUG_ON((_precision) > 30); \
BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
e->internal = 0; \
} \
static inline unsigned long \
ewma_##name##_read(struct ewma_##name *e) \
{ \
BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
BUILD_BUG_ON((_precision) > 30); \
BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
return e->internal >> (_precision); \
} \
static inline void ewma_##name##_add(struct ewma_##name *e, \
unsigned long val) \
{ \
unsigned long internal = READ_ONCE(e->internal); \
unsigned long weight_rcp = ilog2(_weight_rcp); \
unsigned long precision = _precision; \
\
BUILD_BUG_ON(!__builtin_constant_p(_precision)); \
BUILD_BUG_ON(!__builtin_constant_p(_weight_rcp)); \
BUILD_BUG_ON((_precision) > 30); \
BUILD_BUG_ON_NOT_POWER_OF_2(_weight_rcp); \
\
WRITE_ONCE(e->internal, internal ? \
(((internal << weight_rcp) - internal) + \
(val << precision)) >> weight_rcp : \
(val << precision)); \
}
/* </DECLARE_EWMA> */

View file

@ -6,14 +6,15 @@
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=batmand
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://git.open-mesh.org/batmand.git
PKG_SOURCE_URL:=git://git.open-mesh.org/batmand.git
PKG_REV:=b67a7087b51d7a5e90d27ac39116d1f57257c86e
PKG_VERSION:=1440
PKG_RELEASE:=1
PKG_RELEASE:=0
PKG_LICENSE:=GPL-2.0
PKG_SOURCE_VERSION:=$(PKG_REV)
@ -22,13 +23,19 @@ PKG_SOURCE:=$(PKG_SOURCE_SUBDIR).tar.gz
PKG_MIRROR_HASH:=ceb8e0e399f79b1b663594fcf9642e1efc40e696a7604daf709c77da9b6ec52f
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_SOURCE_SUBDIR)
PKG_BUILD_PARALLEL:=1
PKG_EXTRA_CFLAGS=-DDEBUG_MALLOC -DMEMORY_USAGE -DPROFILE_DATA -DREVISION_VERSION=\"\ rv$(PKG_REV)\" -D_GNU_SOURCE
PKG_KMOD_BUILD_DIR:=$(PKG_BUILD_DIR)/linux/modules
include $(INCLUDE_DIR)/package.mk
define Package/batmand
define Package/batmand/Default
URL:=https://www.open-mesh.org/
MAINTAINER:=Corinna "Elektra" Aichele <onelektra@gmx.net>
endef
define Package/batmand
$(call Package/batmand/Default)
SECTION:=net
CATEGORY:=Network
SUBMENU:=Routing and Redirection
@ -40,16 +47,61 @@ define Package/batmand/description
B.A.T.M.A.N. layer 3 routing daemon
endef
MAKE_FLAGS += \
EXTRA_CFLAGS='-DDEBUG_MALLOC -DMEMORY_USAGE -DPROFILE_DATA -DREVISION_VERSION=\"\ rv$(PKG_REV)\" -D_GNU_SOURCE' \
define KernelPackage/batgat
$(call Package/batmand/Default)
SUBMENU:=Network Support
DEPENDS:=+batmand @BROKEN
TITLE:=B.A.T.M.A.N. gateway module
FILES:=$(PKG_KMOD_BUILD_DIR)/batgat.$(LINUX_KMOD_SUFFIX)
AUTOLOAD:=$(call AutoLoad,50,batgat)
endef
define KernelPackage/batgat/description
Kernel gateway module for B.A.T.M.A.N. for better tunnel performance
endef
MAKE_BATMAND_ARGS += \
EXTRA_CFLAGS='$(TARGET_CFLAGS) $(PKG_EXTRA_CFLAGS)' \
CCFLAGS="$(TARGET_CFLAGS)" \
OFLAGS="$(TARGET_CFLAGS)" \
REVISION="$(PKG_REV)" \
CC="$(TARGET_CC)" \
NODEBUG=1 \
UNAME="Linux" \
batmand
INSTALL_PREFIX="$(PKG_INSTALL_DIR)" \
STRIP="/bin/true" \
batmand install
MAKE_BATGAT_ARGS += \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
PATH="$(TARGET_PATH)" \
SUBDIRS="$(PKG_KMOD_BUILD_DIR)" \
LINUX_VERSION="$(LINUX_VERSION)" \
REVISION="$(PKG_REV)" modules
define Build/Configure
endef
ifneq ($(DEVELOPER)$(CONFIG_PACKAGE_batmand),)
BUILD_BATMAND := $(MAKE) -C $(PKG_BUILD_DIR) $(MAKE_BATMAND_ARGS)
endif
ifneq ($(DEVELOPER)$(CONFIG_PACKAGE_kmod-batgat),)
BUILD_BATGAT := $(MAKE) -C "$(LINUX_DIR)" $(MAKE_BATGAT_ARGS)
endif
define Build/Compile
$(BUILD_BATMAND)
cp $(PKG_KMOD_BUILD_DIR)/Makefile.kbuild $(PKG_KMOD_BUILD_DIR)/Makefile
$(BUILD_BATGAT)
endef
define Package/batmand/install
$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/config $(1)/etc/init.d
$(INSTALL_BIN) $(PKG_BUILD_DIR)/batmand $(1)/usr/sbin/
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/batmand $(1)/usr/sbin/
$(INSTALL_BIN) ./files/etc/init.d/batmand $(1)/etc/init.d
$(INSTALL_DATA) ./files/etc/config/batmand $(1)/etc/config
endef
@ -59,3 +111,4 @@ define Package/batmand/conffiles
endef
$(eval $(call BuildPackage,batmand))
$(eval $(call KernelPackage,batgat))

View file

@ -9,3 +9,4 @@ config batmand general
option policy_routing_script
option disable_client_nat
option disable_aggregation

View file

@ -1,42 +1,25 @@
#!/bin/sh /etc/rc.common
START=90
USE_PROCD=1
batmand_start() {
local config="$1"
local batman_args
local interface
local hnas
local gateway_class
local originator_interval
local preferred_gateway
local routing_class
local visualisation_srv
local local policy_routing_script
local disable_client_nat
local disable_aggregation
[ "$config" = "general" ] || return 1
config_get interface "$config" interface
start () {
interface=$(uci get batmand.general.interface)
if [ "$interface" = "" ]; then
echo $1 Error, you must specify at least a network interface
return 1
exit
fi
config_get hnas "$config" hna
config_get gateway_class "$config" gateway_class
config_get originator_interval "$config" originator_interval
config_get preferred_gateway "$config" preferred_gateway
config_get routing_class "$config" routing_class
config_get visualisation_srv "$config" visualisation_srv
config_get policy_routing_script "$config" policy_routing_script
config_get disable_client_nat "$config" disable_client_nat
config_get disable_aggregation "$config" disable_aggregation
hnas=$(uci get batmand.general.hna)
gateway_class=$(uci get batmand.general.gateway_class)
originator_interval=$(uci get batmand.general.originator_interval)
preferred_gateway=$(uci get batmand.general.preferred_gateway)
routing_class=$(uci get batmand.general.routing_class)
visualisation_srv=$(uci get batmand.general.visualisation_srv)
policy_routing_script=$(uci get batmand.general.policy_routing_script)
disable_client_nat=$(uci get batmand.general.disable_client_nat)
disable_aggregation=$(uci get batmand.general.disable_aggregation)
batman_args=""
for hna in $hnas; do
for hna in $hnas
do
batman_args=${batman_args}'-a '$hna' '
done
@ -72,20 +55,12 @@ batmand_start() {
batman_args=${batman_args}'--disable-aggregation '
fi
procd_open_instance "${config}"
procd_set_param command /usr/sbin/batmand
procd_append_param command --no-detach
procd_append_param command ${batman_args}
procd_append_param command ${interface}
procd_set_param netdev ${interface}
procd_close_instance
batman_args=${batman_args}$interface
batmand $batman_args >/dev/null 2>&1
}
start_service() {
config_load "batmand"
config_foreach batmand_start batmand
stop () {
killall batmand
}
service_triggers() {
procd_add_reload_trigger "batmand"
}

View file

@ -1,66 +0,0 @@
From: Sven Eckelmann <sven@narfation.org>
Date: Sun, 1 Dec 2013 14:39:00 +0100
Subject: Allow one to disable forking to background in debug_mode 0
---
posix/init.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
--- a/posix/init.c
+++ b/posix/init.c
@@ -44,6 +44,7 @@
#define IOCSETDEV 1
int8_t stop;
+int no_detach = 0;
@@ -159,6 +160,7 @@ void apply_init_args( int argc, char *ar
{"purge-timeout", required_argument, 0, 'q'},
{"disable-aggregation", no_argument, 0, 'x'},
{"disable-client-nat", no_argument, 0, 'z'},
+ {"no-detach", no_argument, 0, 'D'},
{0, 0, 0, 0}
};
@@ -169,7 +171,7 @@ void apply_init_args( int argc, char *ar
if ( strstr( SOURCE_VERSION, "-" ) != NULL )
printf( "WARNING: You are using the unstable batman branch. If you are interested in *using* batman get the latest stable release !\n" );
- while ( ( optchar = getopt_long( argc, argv, "a:A:bcd:hHio:g:p:r:s:vV", long_options, &option_index ) ) != -1 ) {
+ while ( ( optchar = getopt_long( argc, argv, "a:A:bcd:hHio:g:p:r:s:vVD", long_options, &option_index ) ) != -1 ) {
switch ( optchar ) {
@@ -381,6 +383,11 @@ void apply_init_args( int argc, char *ar
found_args++;
break;
+ case 'D':
+ no_detach = 1;
+ found_args++;
+ break;
+
case 'h':
default:
usage();
@@ -539,12 +546,14 @@ void apply_init_args( int argc, char *ar
/* daemonize */
if (debug_level == 0) {
- if (my_daemon() < 0) {
+ if (!no_detach) {
+ if (my_daemon() < 0) {
- printf("Error - can't fork to background: %s\n", strerror(errno));
- restore_defaults();
- exit(EXIT_FAILURE);
+ printf("Error - can't fork to background: %s\n", strerror(errno));
+ restore_defaults();
+ exit(EXIT_FAILURE);
+ }
}
openlog("batmand", LOG_PID, LOG_DAEMON);

Some files were not shown because too many files have changed in this diff Show more