[B.A.T.M.A.N.] batman-adv and/or batmand porting effort to FreeBSD
by Mahdi Mokhtari
Hi,
After some time of playing with the B.A.T.M.A.N protocol and
net-interface on OpenWRT and Debian I was thinking to use it with
the servers I use everyday (and maybe on routers/appliances I have
nanoBSD on).
So I started an effort...
(As a background) I already ported some applications to FreeBSD [and I'm
maintaining them] and
also I did work already on the Linux emulation layer of FreeBSD (FreeBSD
has a Linux syscall-emulation and Linux-KPI layers).
So my approach (as naturally I didn't expect the build of batman-adv.ko
to be successful as is),
was based on the approach that we [at FreeBSD] did to port Linux's
drm... <https://github.com/FreeBSDDesktop/kms-drm>
I ended up in adding some header-files to FreeBSD Linux-KPI (like
average.h, percpu.h, ...).
Now I'm at a state that Netlink blocks me and I'm to determine next step :-)
[Which I don't assume it being trivial with my current approach]
So I'd like to ask:
1- Is it better approach to "rewrite" batman-adv.ko [at least
Netlink-ish (let's call "Linuxism") parts] than what I'm doing now?
2- Any other efforts are being done out there?
3- is batmand deprecated [So I should mainly focus on batman-adv.ko]?
4- any other comments do you have? :D
P.S. sorry if I'm not really good at starting conversation from scratch
and out-of-nowhere :D
but I hope by continuing the collaboration we can have better (more
enriched) FreeBSD and better (as in more portable) B.A.T.M.A.N :-)
--
Best regards, MMokhi.
3 years, 1 month
[B.A.T.M.A.N.] [PATCH v5 0/7] B.A.T.M.A.N. V - fallback to tp meter estimation if throughput otherwise not available
by Marek Lindner
Under normal circumstances B.A.T.M.A.N. V retrieves the neighbor
throughput values to populate its metric tables from the various
drivers such as WiFi throughput tables and Ethernet throughput..
Whenever the interface drivers do not export link throughput
information manual overrides become necessary. To further
automate and thus better support these setups, ELP may call the
batman-adv throughput meter to schedule a throughput estimation
to be used to populate the metric table.
v5:
* fix tp_vars refcount on queue_work() failure
* squash batadv_tp_start_work() into batadv_tp_start()
v4:
* read tp measurement result only once
v3:
* fix ELP tp meter result computation
* use batadv_has_timed_out() instead of custom implementation
* set ELP tp meter test duration to 1000ms in patch #6
* add comment explaining periodic scheduling
v2:
* added sysfs attribute to configure tp meter test duration
* fixed null pointer dereference in TP meter packet sending routine
* fixed storing the measured throughput in the correct variable
* checkpatch/kerneldoc/sparse/smatch cleanup
Antonio Quartulli (3):
batman-adv: tp_meter - prevent concurrent tp_meter sessions by using
workqueue
batman-adv: tp_meter - don't check for existing session
batman-adv: tp_meter - add option to perform one-hop test
Marek Lindner (4):
batman-adv: tp_meter - allow up to 10 queued sessions
batman-adv: tp_meter - add caller distinction
batman-adv: ELP - use tp meter to estimate the throughput if otherwise
not available
batman-adv: ELP - add throughput meter test duration attribute
.../ABI/testing/sysfs-class-net-batman-adv | 7 +
include/uapi/linux/batadv_packet.h | 2 +
net/batman-adv/bat_v.c | 1 +
net/batman-adv/bat_v_elp.c | 69 ++-
net/batman-adv/bat_v_elp.h | 21 +
net/batman-adv/main.c | 10 +-
net/batman-adv/main.h | 7 +-
net/batman-adv/netlink.c | 3 +-
net/batman-adv/routing.c | 6 +-
net/batman-adv/sysfs.c | 3 +
net/batman-adv/tp_meter.c | 484 +++++++++++-------
net/batman-adv/tp_meter.h | 11 +-
net/batman-adv/types.h | 36 ++
13 files changed, 453 insertions(+), 207 deletions(-)
--
2.18.0
3 years, 2 months
[B.A.T.M.A.N.] [PATCH] batman-adv: handle race condition for claims also in batadv_bla_rx
by Simon Wunderlich
From: Andreas Pape <apape(a)phoenixcontact.com>
Like in the case of the patch for batadv_bla_tx to handle a race
condition when claiming a mac address for bla, a similar situation
can occur when claiming is triggered via batadv_bla_rx. This patch
solves this with a similar approach as for batadv_bla_tx.
Signed-off-by: Andreas Pape <apape(a)phoenixcontact.com>
---
net/batman-adv/bridge_loop_avoidance.c | 31 ++++++++++++++++++++-----------
net/batman-adv/translation-table.c | 26 ++++++++++++++++++++++++++
net/batman-adv/translation-table.h | 3 +++
3 files changed, 49 insertions(+), 11 deletions(-)
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c
index d07e89e..cab8980 100644
--- a/net/batman-adv/bridge_loop_avoidance.c
+++ b/net/batman-adv/bridge_loop_avoidance.c
@@ -1847,19 +1847,28 @@ bool batadv_bla_rx(struct batadv_priv *bat_priv, struct sk_buff *skb,
if (!claim) {
/* possible optimization: race for a claim */
- /* No claim exists yet, claim it for us!
+ /* Make sure this packet is not looping back
+ * from our own backbone.
*/
- batadv_dbg(BATADV_DBG_BLA, bat_priv,
- "bla_rx(): Unclaimed MAC %pM found. Claim it. Local: %s\n",
- ethhdr->h_source,
- batadv_is_my_client(bat_priv,
- ethhdr->h_source, vid) ?
- "yes" : "no");
- batadv_handle_claim(bat_priv, primary_if,
- primary_if->net_dev->dev_addr,
- ethhdr->h_source, vid);
- goto allow;
+ if (batadv_tt_local_has_timed_out(bat_priv, ethhdr->h_source,
+ vid, 100)) {
+ /* No claim exists yet, claim it for us!
+ */
+ batadv_dbg(BATADV_DBG_BLA, bat_priv,
+ "bla_rx(): Unclaimed MAC %pM found. Claim it. Local: %s\n",
+ ethhdr->h_source,
+ batadv_is_my_client(bat_priv,
+ ethhdr->h_source, vid) ?
+ "yes" : "no");
+
+ batadv_handle_claim(bat_priv, primary_if,
+ primary_if->net_dev->dev_addr,
+ ethhdr->h_source, vid);
+ goto allow;
+ } else {
+ goto handled;
+ }
}
/* if it is our own claim ... */
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index e75b493..b908195 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -4380,3 +4380,29 @@ void batadv_tt_cache_destroy(void)
kmem_cache_destroy(batadv_tt_req_cache);
kmem_cache_destroy(batadv_tt_roam_cache);
}
+
+bool batadv_tt_local_has_timed_out(struct batadv_priv *bat_priv,
+ const u8 *addr, unsigned short vid,
+ unsigned int timeout)
+{
+ struct batadv_tt_local_entry *tt_local_entry;
+ bool ret = true;
+
+ tt_local_entry = batadv_tt_local_hash_find(bat_priv, addr, vid);
+ if (!tt_local_entry)
+ goto out;
+ /* Check if the client has been logically deleted (but is kept for
+ * consistency purpose)
+ */
+ if ((tt_local_entry->common.flags & BATADV_TT_CLIENT_PENDING) ||
+ (tt_local_entry->common.flags & BATADV_TT_CLIENT_ROAM))
+ goto out;
+ /* Check that the tt_local_entry has a certain age */
+ if (!batadv_has_timed_out(tt_local_entry->last_seen, timeout))
+ ret = false;
+
+out:
+ if (tt_local_entry)
+ batadv_tt_local_entry_put(tt_local_entry);
+ return ret;
+}
diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h
index 411d586..b05d0d8 100644
--- a/net/batman-adv/translation-table.h
+++ b/net/batman-adv/translation-table.h
@@ -65,5 +65,8 @@ bool batadv_tt_global_is_isolated(struct batadv_priv *bat_priv,
int batadv_tt_cache_init(void);
void batadv_tt_cache_destroy(void);
+bool batadv_tt_local_has_timed_out(struct batadv_priv *bat_priv,
+ const u8 *addr, unsigned short vid,
+ unsigned int timeout);
#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */
--
1.7.0.4
3 years, 7 months
[B.A.T.M.A.N.] [RFC maint v2] batman-adv: fix adding VLANs with partial state
by Marek Lindner
Whenever a new VLAN is created on top of batman virtual interfaces
the batman-adv kernel module creates internal structures to track
the status of said VLAN. Amongst other things, the MAC address of
the VLAN interface itself has to be stored.
Without this change a VLAN and its infrastructure could be created
while the interface MAC address is not stored without triggering
any error, thus creating issues in other parts of the code.
Prevent the VLAN from being created if the MAC address can not
be stored.
Fixes: 952cebb57518 ("batman-adv: add per VLAN interface attribute framework")
Signed-off-by: Marek Lindner <mareklindner(a)neomailbox.ch>
---
net/batman-adv/hard-interface.c | 2 +-
net/batman-adv/soft-interface.c | 105 ++++++++++++++++++++++++--------
net/batman-adv/soft-interface.h | 3 +-
3 files changed, 83 insertions(+), 27 deletions(-)
diff --git a/net/batman-adv/hard-interface.c b/net/batman-adv/hard-interface.c
index c405d15b..0b22cc4d 100644
--- a/net/batman-adv/hard-interface.c
+++ b/net/batman-adv/hard-interface.c
@@ -1000,7 +1000,7 @@ static int batadv_hard_if_event(struct notifier_block *this,
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);
+ batadv_softif_create_vlan_late(bat_priv, BATADV_NO_FLAGS);
return NOTIFY_DONE;
}
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index edeffcb9..728d9d40 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -563,16 +563,36 @@ struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv,
}
/**
- * batadv_softif_create_vlan() - allocate the needed resources for a new vlan
+ * batadv_softif_destroy_vlan() - remove and destroy a softif_vlan object
+ * @bat_priv: the bat priv with all the soft interface information
+ * @vlan: the object to remove
+ */
+static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv,
+ struct batadv_softif_vlan *vlan)
+{
+ /* explicitly remove the associated TT local entry because it is marked
+ * with the NOPURGE flag
+ */
+ batadv_tt_local_remove(bat_priv, bat_priv->soft_iface->dev_addr,
+ vlan->vid, "vlan interface destroyed", false);
+
+ batadv_sysfs_del_vlan(bat_priv, vlan);
+ batadv_softif_vlan_put(vlan);
+}
+
+/**
+ * batadv_softif_create_vlan_early() - allocate the needed resources for a new
+ * vlan, defer sysfs creation till later
* @bat_priv: the bat priv with all the soft interface information
* @vid: the VLAN identifier
*
* Return: 0 on success, a negative error otherwise.
*/
-int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
+static int batadv_softif_create_vlan_early(struct batadv_priv *bat_priv,
+ unsigned short vid)
{
struct batadv_softif_vlan *vlan;
- int err;
+ bool client_added;
vlan = batadv_softif_vlan_get(bat_priv, vid);
if (vlan) {
@@ -590,12 +610,6 @@ 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);
@@ -604,32 +618,63 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
/* add a new TT local entry. This one will be marked with the NOPURGE
* flag
*/
- batadv_tt_local_add(bat_priv->soft_iface,
- bat_priv->soft_iface->dev_addr, vid,
- BATADV_NULL_IFINDEX, BATADV_NO_MARK);
+ client_added = batadv_tt_local_add(bat_priv->soft_iface,
+ bat_priv->soft_iface->dev_addr, vid,
+ BATADV_NULL_IFINDEX, BATADV_NO_MARK);
/* don't return reference to new softif_vlan */
batadv_softif_vlan_put(vlan);
+ if (!client_added) {
+ batadv_softif_destroy_vlan(bat_priv, vlan);
+ return -ENOENT;
+ }
+
return 0;
}
/**
- * batadv_softif_destroy_vlan() - remove and destroy a softif_vlan object
+ * batadv_softif_create_vlan_late() - complete softif vlan creation with the
+ * sysfs entries
* @bat_priv: the bat priv with all the soft interface information
- * @vlan: the object to remove
+ * @vid: the VLAN identifier
+ *
+ * Return: 0 on success, a negative error otherwise.
*/
-static void batadv_softif_destroy_vlan(struct batadv_priv *bat_priv,
- struct batadv_softif_vlan *vlan)
+int batadv_softif_create_vlan_late(struct batadv_priv *bat_priv,
+ unsigned short vid)
{
- /* explicitly remove the associated TT local entry because it is marked
- * with the NOPURGE flag
- */
- batadv_tt_local_remove(bat_priv, bat_priv->soft_iface->dev_addr,
- vlan->vid, "vlan interface destroyed", false);
+ struct batadv_softif_vlan *vlan;
+ int ret;
+
+ vlan = batadv_softif_vlan_get(bat_priv, vid);
+ if (!vlan)
+ return -ENOENT;
+
+ ret = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
- batadv_sysfs_del_vlan(bat_priv, vlan);
batadv_softif_vlan_put(vlan);
+ return ret;
+}
+
+/**
+ * batadv_softif_create_vlan() - allocate the needed resources for a new vlan
+ * @bat_priv: the bat priv with all the soft interface information
+ * @vid: the VLAN identifier
+ *
+ * Return: 0 on success, a negative error otherwise.
+ */
+static int batadv_softif_create_vlan(struct batadv_priv *bat_priv,
+ unsigned short vid)
+{
+ int err;
+
+ err = batadv_softif_create_vlan_early(bat_priv, vid);
+ if (err)
+ return err;
+
+ err = batadv_softif_create_vlan_late(bat_priv, vid);
+ return err;
}
/**
@@ -648,6 +693,7 @@ static int batadv_interface_add_vid(struct net_device *dev, __be16 proto,
{
struct batadv_priv *bat_priv = netdev_priv(dev);
struct batadv_softif_vlan *vlan;
+ bool client_added;
int ret;
/* only 802.1Q vlans are supported.
@@ -683,9 +729,14 @@ static int batadv_interface_add_vid(struct net_device *dev, __be16 proto,
* flag. This must be added again, even if the vlan object already
* exists, because the entry was deleted by kill_vid()
*/
- batadv_tt_local_add(bat_priv->soft_iface,
- bat_priv->soft_iface->dev_addr, vid,
- BATADV_NULL_IFINDEX, BATADV_NO_MARK);
+ client_added = batadv_tt_local_add(bat_priv->soft_iface,
+ bat_priv->soft_iface->dev_addr, vid,
+ BATADV_NULL_IFINDEX, BATADV_NO_MARK);
+
+ if (!client_added) {
+ batadv_softif_destroy_vlan(bat_priv, vlan);
+ return -ENOENT;
+ }
return 0;
}
@@ -850,6 +901,10 @@ static int batadv_softif_init_late(struct net_device *dev)
if (ret < 0)
goto unreg_debugfs;
+ ret = batadv_softif_create_vlan_early(bat_priv, BATADV_NO_FLAGS);
+ if (ret < 0)
+ goto unreg_debugfs;
+
return 0;
unreg_debugfs:
diff --git a/net/batman-adv/soft-interface.h b/net/batman-adv/soft-interface.h
index daf87f07..b8a9a3c8 100644
--- a/net/batman-adv/soft-interface.h
+++ b/net/batman-adv/soft-interface.h
@@ -36,7 +36,8 @@ struct net_device *batadv_softif_create(struct net *net, const char *name);
void batadv_softif_destroy_sysfs(struct net_device *soft_iface);
bool batadv_softif_is_valid(const struct net_device *net_dev);
extern struct rtnl_link_ops batadv_link_ops;
-int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid);
+int batadv_softif_create_vlan_late(struct batadv_priv *bat_priv,
+ unsigned short vid);
void batadv_softif_vlan_put(struct batadv_softif_vlan *softif_vlan);
struct batadv_softif_vlan *batadv_softif_vlan_get(struct batadv_priv *bat_priv,
unsigned short vid);
--
2.17.0
3 years, 7 months
[B.A.T.M.A.N.] [PATCH 0/6] batman-adv: Add routeable multicast optimizations
by Linus Lüssing
The following patchset fills the next gaps in the multicast address
rules page by adding support for group-aware optimizations for
multicast addresses of scope greater than link-local. So far, only
link-local addresses were optimized as packets with routeable
addresses not only need to be forwarded to local multicast listeners
but also multicast routers.
"Handling rules depending on multicast address:" [0]
Before:
* Ipv4, link-local: supported without bridges
* IPv6, link-local: supported
* IPv4, routeable: support planned.
* IPv6, routeable: support planned.
After:
* Ipv4, link-local: supported without bridges
* IPv6, link-local: supported
* IPv4, routeable: supported without bridges.
* IPv6, routeable: supported.
The first patch is a fix for the maint branch addressing tickets #369
and #370.
Then patches 2 to 4 are basically some cleanups and restructuring of the
current code.
Patch 5 adds the detection of multicast routers and announces
that via two new flags in its multicast TVLV. TVLV receivers will
memorize this and fill lists similar to how we already do for the
WANT_ALL_IPV4/IPV6 flags. Currently the detection for bridged-in
IPv6 multicast routers is not quite what the RFC for multicast router
discovery suggests. But once the MRD implementation in the Linux bridge
has matured a bit, I'm going to swap this simplified approach with
tapping into the bridge once more, asking the bridge for the presence of
multicast routers on the link. (This will then also add support for
"IPv4, routeable, with bridges")
Finally, patch 6 implements the changes to the forwarding plane,
utilizing the new information we have gathered with patch 5.
Regards, Linus
[0]: https://www.open-mesh.org/projects/batman-adv/wiki/Multicast-optimization...
3 years, 9 months
[B.A.T.M.A.N.] [PATCH] batman-adv: introduce "noflood" broadcast flood prevention option
by Linus Lüssing
With DAT DHCP snooping, the gateway feature and multicast optimizations
in place in some scenarios broadcast flooding might not be strictly
necessary anymore to be able to establish IPv4/IPv6 communication.
Therefore this patch adds an option to disable broadcast flooding.
Larger mesh networks typically filter a variety of multicast packets via
ebtables/netfilter to clamp on overhead. With this option such firewall
rules can be relaxed so that such multicast packets are only dropped
if they cannot be handled by multicast-to-unicast, for instance.
"noflood" comes in two flavours: If set to 1 then flood prevention is
enabled for all multicast/broadcast packets except ICMPv6 and IGMP
(cautious mode). Or, if set to 2 then flood prevention is enabled for
all multicast/broadcast packets (aggressive mode). If set to 0 then
flood prevention is disabled.
"noflood" is disabled by default as there are still some things to take
care of to avoid breaking things (especially for the "aggressive mode").
Signed-off-by: Linus Lüssing <linus.luessing(a)c0d3.blue>
---
The initial approach was a "noflood"-mark which worked similar to the
isolation mark. Which allowed more flexibility so that the user could
mark specific packets to be excluded from broadcast flooding via
ebtables/netfilter. However, in practice skb-marking is not that easy to
configure and if misconfigured will break a network horribly. Which was
also a downside noted and discussed at BattleMesh v11.
This version now is a less flexible but therefore also simpler to use
variant.
[0]: https://git.open-mesh.org/batman-adv.git/shortlog/refs/heads/linus/nofloo...
[1]: https://github.com/freifunk-gluon/gluon/pull/1357
---
include/uapi/linux/batman_adv.h | 10 ++++
net/batman-adv/netlink.c | 10 ++++
net/batman-adv/soft-interface.c | 85 +++++++++++++++++++++++++++++++++
net/batman-adv/types.h | 6 +++
4 files changed, 111 insertions(+)
diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 67f46367..d68f8868 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -480,6 +480,16 @@ enum batadv_nl_attrs {
*/
BATADV_ATTR_MULTICAST_FANOUT,
+ /**
+ * @BATADV_ATTR_NOFLOOD: defines if and how strictly flooding prevention
+ * is configured. If the value is 0 then flood prevention is disabled.
+ * If the value is 1 then flood prevention is enabled for all multicast
+ * /broadcast packets excluding ICMPv6 and IGMP (cautious mode). If set
+ * to 2 then flood prevention is enabled for all multicast/broadcast
+ * packets (aggressive mode).
+ */
+ BATADV_ATTR_NOFLOOD,
+
/* add attributes above here, update the policy in netlink.c */
/**
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index e7907308..940a9c37 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -358,6 +358,10 @@ static int batadv_netlink_mesh_fill(struct sk_buff *msg,
atomic_read(&bat_priv->orig_interval)))
goto nla_put_failure;
+ if (nla_put_u8(msg, BATADV_ATTR_NOFLOOD,
+ atomic_read(&bat_priv->noflood)))
+ goto nla_put_failure;
+
if (primary_if)
batadv_hardif_put(primary_if);
@@ -614,6 +618,12 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
atomic_set(&bat_priv->orig_interval, orig_interval);
}
+ if (info->attrs[BATADV_ATTR_NOFLOOD]) {
+ attr = info->attrs[BATADV_ATTR_NOFLOOD];
+
+ atomic_set(&bat_priv->noflood, nla_get_u8(attr));
+ }
+
batadv_netlink_notify_mesh(bat_priv);
return 0;
diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c
index a7677e1d..680e3b03 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -18,6 +18,11 @@
#include <linux/gfp.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>
+#include <linux/igmp.h>
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/kref.h>
@@ -37,6 +42,7 @@
#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/types.h>
+#include <net/addrconf.h>
#include <uapi/linux/batadv_packet.h>
#include <uapi/linux/batman_adv.h>
@@ -176,6 +182,81 @@ static void batadv_interface_set_rx_mode(struct net_device *dev)
{
}
+/**
+ * batadv_softif_noflood_is_igmp() - check if a packet is IGMP
+ * @bat_priv: the bat priv with all the soft interface information
+ * @skb: the multicast/broadcast packet to check
+ *
+ * Return: True if the given skb is an IGMP packet, false otherwise.
+ */
+static bool batadv_softif_noflood_is_igmp(struct sk_buff *skb)
+{
+ int ret = ip_mc_check_igmp(skb);
+
+ if (ret == -ENOMEM || ret == -EINVAL)
+ return false;
+
+ /* ret == -ENOMSG => valid IPv6 header */
+ if (ret == -ENOMSG && ip_hdr(skb)->protocol != IPPROTO_IGMP)
+ return false;
+
+ /* it's IGMP */
+ return true;
+}
+
+/**
+ * batadv_softif_noflood_is_icmpv6() - check if a packet is ICMPv6
+ * @bat_priv: the bat priv with all the soft interface information
+ * @skb: the multicast/broadcast packet to check
+ *
+ * Return: True if the given skb is an ICMPv6 packet, false otherwise.
+ */
+static bool batadv_softif_noflood_is_icmpv6(struct sk_buff *skb)
+{
+ int ret = ipv6_mc_check_mld(skb);
+
+ if (ret == -ENOMEM || ret == -EINVAL)
+ return false;
+
+ /* ret == -ENOMSG => valid IPv6 header */
+ if (ret == -ENOMSG && ipv6_hdr(skb)->nexthdr != IPPROTO_ICMPV6)
+ return false;
+
+ /* it's ICMPv6 */
+ return true;
+}
+
+/**
+ * batadv_softif_check_noflood() - check if flood-prevention is enabled
+ * @bat_priv: the bat priv with all the soft interface information
+ * @skb: the multicast/broadcast packet to check
+ *
+ * Return: True if flood prevention is enabled for this packet type, false
+ * otherwise.
+ */
+static bool
+batadv_softif_check_noflood(struct batadv_priv *bat_priv, struct sk_buff *skb)
+{
+ int ret = atomic_read(&bat_priv->noflood);
+
+ /* disabled */
+ if (!ret)
+ return false;
+ /* aggressive mode */
+ else if (ret == 2)
+ return true;
+
+ /* exclude ICMPv6 and IGMP from "noflood" */
+ switch (ntohs(eth_hdr(skb)->h_proto)) {
+ case ETH_P_IP:
+ return !batadv_softif_noflood_is_igmp(skb);
+ case ETH_P_IPV6:
+ return !batadv_softif_noflood_is_icmpv6(skb);
+ default:
+ return true;
+ }
+}
+
static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
struct net_device *soft_iface)
{
@@ -326,6 +407,9 @@ static netdev_tx_t batadv_interface_tx(struct sk_buff *skb,
if (batadv_dat_snoop_outgoing_arp_request(bat_priv, skb))
brd_delay = msecs_to_jiffies(ARP_REQ_DELAY);
+ if (batadv_softif_check_noflood(bat_priv, skb))
+ goto dropped;
+
if (batadv_skb_head_push(skb, sizeof(*bcast_packet)) < 0)
goto dropped;
@@ -823,6 +907,7 @@ static int batadv_softif_init_late(struct net_device *dev)
atomic_set(&bat_priv->log_level, 0);
#endif
atomic_set(&bat_priv->fragmentation, 1);
+ atomic_set(&bat_priv->noflood, 0);
atomic_set(&bat_priv->packet_size_max, ETH_DATA_LEN);
atomic_set(&bat_priv->bcast_queue_left, BATADV_BCAST_QUEUE_LEN);
atomic_set(&bat_priv->batman_queue_left, BATADV_BATMAN_QUEUE_LEN);
diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h
index 357ca119..f3f96f02 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1575,6 +1575,12 @@ struct batadv_priv {
atomic_t log_level;
#endif
+ /**
+ * @noflood: option indicating whether to drop packets that would
+ * be flooded through the mesh otherwise
+ */
+ atomic_t noflood;
+
/**
* @isolation_mark: the skb->mark value used to match packets for AP
* isolation
--
2.20.1
3 years, 9 months
[PATCH] batman-adv: genetlink: optionally validate strictly/dumps
by Sven Eckelmann
From: Johannes Berg <johannes.berg(a)intel.com>
Add options to strictly validate messages and dump messages,
sometimes perhaps validating dump messages non-strictly may
be required, so add an option for that as well.
Since none of this can really be applied to existing commands,
set the options everwhere using the following spatch:
@@
identifier ops;
expression X;
@@
struct genl_ops ops[] = {
...,
{
.cmd = X,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
...
},
...
};
For new commands one should just not copy the .validate 'opt-out'
flags and thus get strict validation.
Signed-off-by: Johannes Berg <johannes.berg(a)intel.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
[sven(a)narfation.org: Add compat code]
Signed-off-by: Sven Eckelmann <sven(a)narfation.org>
---
compat-include/net/genetlink.h | 46 ++++++++++++++++++++++++++++++----
net/batman-adv/netlink.c | 18 +++++++++++++
2 files changed, 59 insertions(+), 5 deletions(-)
diff --git a/compat-include/net/genetlink.h b/compat-include/net/genetlink.h
index 7d17a705..fbfdb733 100644
--- a/compat-include/net/genetlink.h
+++ b/compat-include/net/genetlink.h
@@ -33,6 +33,25 @@ void batadv_genl_dump_check_consistent(struct netlink_callback *cb,
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 2, 0)
+enum genl_validate_flags {
+ GENL_DONT_VALIDATE_STRICT = BIT(0),
+ GENL_DONT_VALIDATE_DUMP = BIT(1),
+ GENL_DONT_VALIDATE_DUMP_STRICT = BIT(2),
+};
+
+struct batadv_genl_ops {
+ int (*doit)(struct sk_buff *skb,
+ struct genl_info *info);
+ int (*start)(struct netlink_callback *cb);
+ int (*dumpit)(struct sk_buff *skb,
+ struct netlink_callback *cb);
+ int (*done)(struct netlink_callback *cb);
+ u8 cmd;
+ u8 internal_flags;
+ u8 flags;
+ u8 validate;
+};
+
struct batadv_genl_family {
/* data handled by the actual kernel */
struct genl_family family;
@@ -50,7 +69,7 @@ struct batadv_genl_family {
struct genl_info *info);
void (*post_doit)(const struct genl_ops *ops, struct sk_buff *skb,
struct genl_info *info);
- const struct genl_ops *ops;
+ const struct batadv_genl_ops *ops;
const struct genl_multicast_group *mcgrps;
unsigned int n_ops;
unsigned int n_mcgrps;
@@ -63,8 +82,6 @@ struct batadv_genl_family {
struct genl_ops *copy_ops;
};
-#define genl_family batadv_genl_family
-
static inline int batadv_genl_register_family(struct batadv_genl_family *family)
{
struct genl_ops *ops;
@@ -82,12 +99,20 @@ static inline int batadv_genl_register_family(struct batadv_genl_family *family)
family->family.n_mcgrps = family->n_mcgrps;
family->family.module = family->module;
- ops = kmemdup(family->ops, sizeof(*ops) * family->n_ops, GFP_KERNEL);
+ ops = kzalloc(sizeof(*ops) * family->n_ops, GFP_KERNEL);
if (!ops)
return -ENOMEM;
- for (i = 0; i < family->family.n_ops; i++)
+ for (i = 0; i < family->family.n_ops; i++) {
+ ops[i].doit = family->ops[i].doit;
+ ops[i].start = family->ops[i].start;
+ ops[i].dumpit = family->ops[i].dumpit;
+ ops[i].done = family->ops[i].done;
+ ops[i].cmd = family->ops[i].cmd;
+ ops[i].internal_flags = family->ops[i].internal_flags;
+ ops[i].flags = family->ops[i].flags;
ops[i].policy = family->policy;
+ }
family->family.ops = ops;
family->copy_ops = ops;
@@ -95,6 +120,17 @@ static inline int batadv_genl_register_family(struct batadv_genl_family *family)
return genl_register_family(&family->family);
}
+typedef struct genl_ops batadv_genl_ops_old;
+
+#define batadv_pre_doit(__x, __y, __z) \
+ batadv_pre_doit(const batadv_genl_ops_old *ops, __y, __z)
+
+#define batadv_post_doit(__x, __y, __z) \
+ batadv_post_doit(const batadv_genl_ops_old *ops, __y, __z)
+
+#define genl_ops batadv_genl_ops
+#define genl_family batadv_genl_family
+
#define genl_register_family(family) \
batadv_genl_register_family((family))
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index e7907308..a67720fa 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -1343,29 +1343,34 @@ static void batadv_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
static const struct genl_ops batadv_netlink_ops[] = {
{
.cmd = BATADV_CMD_GET_MESH,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
/* can be retrieved by unprivileged users */
.doit = batadv_netlink_get_mesh,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_TP_METER,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_tp_meter_start,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_TP_METER_CANCEL,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_tp_meter_cancel,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_GET_ROUTING_ALGOS,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_algo_dump,
},
{
.cmd = BATADV_CMD_GET_HARDIF,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
/* can be retrieved by unprivileged users */
.dumpit = batadv_netlink_dump_hardif,
.doit = batadv_netlink_get_hardif,
@@ -1374,57 +1379,68 @@ static const struct genl_ops batadv_netlink_ops[] = {
},
{
.cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_tt_local_dump,
},
{
.cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_tt_global_dump,
},
{
.cmd = BATADV_CMD_GET_ORIGINATORS,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_orig_dump,
},
{
.cmd = BATADV_CMD_GET_NEIGHBORS,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_hardif_neigh_dump,
},
{
.cmd = BATADV_CMD_GET_GATEWAYS,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_gw_dump,
},
{
.cmd = BATADV_CMD_GET_BLA_CLAIM,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_bla_claim_dump,
},
{
.cmd = BATADV_CMD_GET_BLA_BACKBONE,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_bla_backbone_dump,
},
{
.cmd = BATADV_CMD_GET_DAT_CACHE,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_dat_cache_dump,
},
{
.cmd = BATADV_CMD_GET_MCAST_FLAGS,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_mcast_flags_dump,
},
{
.cmd = BATADV_CMD_SET_MESH,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_set_mesh,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_SET_HARDIF,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_set_hardif,
.internal_flags = BATADV_FLAG_NEED_MESH |
@@ -1432,6 +1448,7 @@ static const struct genl_ops batadv_netlink_ops[] = {
},
{
.cmd = BATADV_CMD_GET_VLAN,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
/* can be retrieved by unprivileged users */
.doit = batadv_netlink_get_vlan,
.internal_flags = BATADV_FLAG_NEED_MESH |
@@ -1439,6 +1456,7 @@ static const struct genl_ops batadv_netlink_ops[] = {
},
{
.cmd = BATADV_CMD_SET_VLAN,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_set_vlan,
.internal_flags = BATADV_FLAG_NEED_MESH |
--
2.20.1
3 years, 9 months
[B.A.T.M.A.N.] [RFC] batman-adv: genetlink: optionally validate strictly/dumps
by Sven Eckelmann
From: Johannes Berg <johannes.berg(a)intel.com>
Add options to strictly validate messages and dump messages,
sometimes perhaps validating dump messages non-strictly may
be required, so add an option for that as well.
Since none of this can really be applied to existing commands,
set the options everwhere using the following spatch:
@@
identifier ops;
expression X;
@@
struct genl_ops ops[] = {
...,
{
.cmd = X,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
...
},
...
};
For new commands one should just not copy the .validate 'opt-out'
flags and thus get strict validation.
Signed-off-by: Johannes Berg <johannes.berg(a)intel.com>
Signed-off-by: David S. Miller <davem(a)davemloft.net>
Signed-off-by: Sven Eckelmann <sven(a)narfation.org>
---
This patch was already applied upstream as
ef6243acb4782df587a4d7d6c310fa5b5d82684b but compat code is missing for it.
net/batman-adv/netlink.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index e7907308..a67720fa 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -1343,29 +1343,34 @@ static void batadv_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
static const struct genl_ops batadv_netlink_ops[] = {
{
.cmd = BATADV_CMD_GET_MESH,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
/* can be retrieved by unprivileged users */
.doit = batadv_netlink_get_mesh,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_TP_METER,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_tp_meter_start,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_TP_METER_CANCEL,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_tp_meter_cancel,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_GET_ROUTING_ALGOS,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_algo_dump,
},
{
.cmd = BATADV_CMD_GET_HARDIF,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
/* can be retrieved by unprivileged users */
.dumpit = batadv_netlink_dump_hardif,
.doit = batadv_netlink_get_hardif,
@@ -1374,57 +1379,68 @@ static const struct genl_ops batadv_netlink_ops[] = {
},
{
.cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_tt_local_dump,
},
{
.cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_tt_global_dump,
},
{
.cmd = BATADV_CMD_GET_ORIGINATORS,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_orig_dump,
},
{
.cmd = BATADV_CMD_GET_NEIGHBORS,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_hardif_neigh_dump,
},
{
.cmd = BATADV_CMD_GET_GATEWAYS,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_gw_dump,
},
{
.cmd = BATADV_CMD_GET_BLA_CLAIM,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_bla_claim_dump,
},
{
.cmd = BATADV_CMD_GET_BLA_BACKBONE,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_bla_backbone_dump,
},
{
.cmd = BATADV_CMD_GET_DAT_CACHE,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_dat_cache_dump,
},
{
.cmd = BATADV_CMD_GET_MCAST_FLAGS,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.dumpit = batadv_mcast_flags_dump,
},
{
.cmd = BATADV_CMD_SET_MESH,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_set_mesh,
.internal_flags = BATADV_FLAG_NEED_MESH,
},
{
.cmd = BATADV_CMD_SET_HARDIF,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_set_hardif,
.internal_flags = BATADV_FLAG_NEED_MESH |
@@ -1432,6 +1448,7 @@ static const struct genl_ops batadv_netlink_ops[] = {
},
{
.cmd = BATADV_CMD_GET_VLAN,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
/* can be retrieved by unprivileged users */
.doit = batadv_netlink_get_vlan,
.internal_flags = BATADV_FLAG_NEED_MESH |
@@ -1439,6 +1456,7 @@ static const struct genl_ops batadv_netlink_ops[] = {
},
{
.cmd = BATADV_CMD_SET_VLAN,
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.flags = GENL_ADMIN_PERM,
.doit = batadv_netlink_set_vlan,
.internal_flags = BATADV_FLAG_NEED_MESH |
--
2.20.1
3 years, 9 months
[B.A.T.M.A.N.] [PATCH v2] batctl: Add noflood command
by Linus Lüssing
Adds support for the new 'noflood' setting in batman-adv.
Signed-off-by: Linus Lüssing <linus.luessing(a)c0d3.blue>
---
Changelog v2:
* added noflood.c
---
Makefile | 1 +
README.rst | 10 +++++
batman_adv.h | 10 +++++
man/batctl.8 | 7 ++++
noflood.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 129 insertions(+)
create mode 100644 noflood.c
diff --git a/Makefile b/Makefile
index df8b7b9..6a363d7 100755
--- a/Makefile
+++ b/Makefile
@@ -61,6 +61,7 @@ $(eval $(call add_command,multicast_mode,y))
$(eval $(call add_command,nc_nodes,y))
$(eval $(call add_command,neighbors,y))
$(eval $(call add_command,network_coding,y))
+$(eval $(call add_command,noflood,y))
$(eval $(call add_command,orig_interval,y))
$(eval $(call add_command,originators,y))
$(eval $(call add_command,ping,y))
diff --git a/README.rst b/README.rst
index 03ea5e5..67d42f6 100644
--- a/README.rst
+++ b/README.rst
@@ -571,6 +571,16 @@ Usage::
* Example 4: ``batctl mark 0x0f``
+batctl noflood
+=======================
+
+display or modify noflood setting (<disabled>|<cautious>|<aggressive>)
+
+Usage::
+
+ batctl noflood|nf [0|1|2]
+
+
batctl translocal
=================
diff --git a/batman_adv.h b/batman_adv.h
index 67f4636..ea2ffda 100644
--- a/batman_adv.h
+++ b/batman_adv.h
@@ -480,6 +480,16 @@ enum batadv_nl_attrs {
*/
BATADV_ATTR_MULTICAST_FANOUT,
+ /**
+ * @BATADV_ATTR_NOFLOOD: defines if and how strictly flooding prevention
+ * is configured. If the value is 0 then flood prevention is disabled.
+ * If the value is 1 then flood prevention is enabled for all multicast
+ * /broadcast packets excluding ICMPv6 and IGMP (cautious mode). If set
+ * to 2 then flood prevention is enabled for all multicast/broadcast
+ * packets (aggressive mode).
+ */
+ BATADV_ATTR_NOFLOOD,
+
/* add attributes above here, update the policy in netlink.c */
/**
diff --git a/man/batctl.8 b/man/batctl.8
index 8d7332a..7518f9c 100644
--- a/man/batctl.8
+++ b/man/batctl.8
@@ -116,6 +116,13 @@ If no parameter is given the current multicast fanout setting is displayed. Othe
the multicast fanout. The multicast fanout defines the maximum number of packet copies that may be generated for a
multicast-to-unicast conversion. Once this limit is exceeded distribution will fall back to broadcast.
.br
+.IP "\fBnoflood\fP|\fBnf\fP [\fB0|1|2\fP]"
+If no parameter is given the current noflood setting is displayed. Otherwise the parameter is used to set the
+the noflood option. The noflood option defines if and how strictly flooding prevention is configured. If the value is
+0 then flood prevention is disabled. If the value is 1 then flood prevention is enabled for all multicast/broadcast
+packets excluding ICMPv6 and IGMP (cautious mode). If set to 2 then flood prevention is enabled for all multicast/broadcast
+packets (aggressive mode).
+.br
.IP "\fBloglevel\fP|\fBll\fP [\fBlevel\fP[ \fBlevel\fP[ \fBlevel\fP]] \fB...\fP]"
If no parameter is given the current log level settings are displayed otherwise the parameter(s) is/are used to set the log
level. Level 'none' disables all verbose logging. Level 'batman' enables messages related to routing / flooding / broadcasting.
diff --git a/noflood.c b/noflood.c
new file mode 100644
index 0000000..c60063c
--- /dev/null
+++ b/noflood.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2009-2019 B.A.T.M.A.N. contributors:
+ *
+ * Linus Lüssing <linus.luessing(a)c0d3.blue>
+ *
+ * License-Filename: LICENSES/preferred/GPL-2.0
+ */
+
+#include <errno.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "main.h"
+#include "sys.h"
+
+static struct noflood_data {
+ uint32_t noflood;
+} noflood;
+
+static int parse_noflood(struct state *state, int argc, char *argv[])
+{
+ struct settings_data *settings = state->cmd->arg;
+ struct noflood_data *data = settings->data;
+ char *endptr;
+
+ if (argc != 2) {
+ fprintf(stderr, "Error - incorrect number of arguments (expected 1)\n");
+ return -EINVAL;
+ }
+
+ data->noflood = strtoul(argv[1], &endptr, 0);
+ if (!endptr || *endptr != '\0') {
+ fprintf(stderr, "Error - the supplied argument is invalid: %s\n", argv[1]);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int print_noflood(struct nl_msg *msg, void *arg)
+{
+ struct nlattr *attrs[BATADV_ATTR_MAX + 1];
+ struct nlmsghdr *nlh = nlmsg_hdr(msg);
+ struct genlmsghdr *ghdr;
+ int *result = arg;
+
+ if (!genlmsg_valid_hdr(nlh, 0))
+ return NL_OK;
+
+ ghdr = nlmsg_data(nlh);
+
+ if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0),
+ genlmsg_len(ghdr), batadv_netlink_policy)) {
+ return NL_OK;
+ }
+
+ if (!attrs[BATADV_ATTR_NOFLOOD])
+ return NL_OK;
+
+ printf("%u\n", nla_get_u8(attrs[BATADV_ATTR_NOFLOOD]));
+
+ *result = 0;
+ return NL_STOP;
+}
+
+static int get_noflood(struct state *state)
+{
+ return sys_simple_nlquery(state, BATADV_CMD_GET_MESH,
+ NULL, print_noflood);
+}
+
+static int set_attrs_noflood(struct nl_msg *msg, void *arg)
+{
+ struct state *state = arg;
+ struct settings_data *settings = state->cmd->arg;
+ struct noflood_data *data = settings->data;
+
+ nla_put_u8(msg, BATADV_ATTR_NOFLOOD, data->noflood);
+
+ return 0;
+}
+
+static int set_noflood(struct state *state)
+{
+ return sys_simple_nlquery(state, BATADV_CMD_SET_MESH,
+ set_attrs_noflood, NULL);
+}
+
+static struct settings_data batctl_settings_noflood = {
+ .sysfs_name = NULL,
+ .data = &noflood,
+ .parse = parse_noflood,
+ .netlink_get = get_noflood,
+ .netlink_set = set_noflood,
+};
+
+COMMAND_NAMED(SUBCOMMAND, noflood, "nf", handle_sys_setting,
+ COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK,
+ &batctl_settings_noflood,
+ "[0|1|2] \tdisplay or modify noflood setting (<disabled>|<cautious>|<aggressive>)");
--
2.20.1
3 years, 9 months
[B.A.T.M.A.N.] [PATCH] batctl: Add noflood command
by Linus Lüssing
Adds support for the new 'noflood' setting in batman-adv.
Signed-off-by: Linus Lüssing <linus.luessing(a)c0d3.blue>
---
Makefile | 1 +
README.rst | 10 ++++++++++
batman_adv.h | 10 ++++++++++
man/batctl.8 | 7 +++++++
4 files changed, 28 insertions(+)
diff --git a/Makefile b/Makefile
index df8b7b9..6a363d7 100755
--- a/Makefile
+++ b/Makefile
@@ -61,6 +61,7 @@ $(eval $(call add_command,multicast_mode,y))
$(eval $(call add_command,nc_nodes,y))
$(eval $(call add_command,neighbors,y))
$(eval $(call add_command,network_coding,y))
+$(eval $(call add_command,noflood,y))
$(eval $(call add_command,orig_interval,y))
$(eval $(call add_command,originators,y))
$(eval $(call add_command,ping,y))
diff --git a/README.rst b/README.rst
index 03ea5e5..67d42f6 100644
--- a/README.rst
+++ b/README.rst
@@ -571,6 +571,16 @@ Usage::
* Example 4: ``batctl mark 0x0f``
+batctl noflood
+=======================
+
+display or modify noflood setting (<disabled>|<cautious>|<aggressive>)
+
+Usage::
+
+ batctl noflood|nf [0|1|2]
+
+
batctl translocal
=================
diff --git a/batman_adv.h b/batman_adv.h
index 67f4636..ea2ffda 100644
--- a/batman_adv.h
+++ b/batman_adv.h
@@ -480,6 +480,16 @@ enum batadv_nl_attrs {
*/
BATADV_ATTR_MULTICAST_FANOUT,
+ /**
+ * @BATADV_ATTR_NOFLOOD: defines if and how strictly flooding prevention
+ * is configured. If the value is 0 then flood prevention is disabled.
+ * If the value is 1 then flood prevention is enabled for all multicast
+ * /broadcast packets excluding ICMPv6 and IGMP (cautious mode). If set
+ * to 2 then flood prevention is enabled for all multicast/broadcast
+ * packets (aggressive mode).
+ */
+ BATADV_ATTR_NOFLOOD,
+
/* add attributes above here, update the policy in netlink.c */
/**
diff --git a/man/batctl.8 b/man/batctl.8
index 8d7332a..7518f9c 100644
--- a/man/batctl.8
+++ b/man/batctl.8
@@ -116,6 +116,13 @@ If no parameter is given the current multicast fanout setting is displayed. Othe
the multicast fanout. The multicast fanout defines the maximum number of packet copies that may be generated for a
multicast-to-unicast conversion. Once this limit is exceeded distribution will fall back to broadcast.
.br
+.IP "\fBnoflood\fP|\fBnf\fP [\fB0|1|2\fP]"
+If no parameter is given the current noflood setting is displayed. Otherwise the parameter is used to set the
+the noflood option. The noflood option defines if and how strictly flooding prevention is configured. If the value is
+0 then flood prevention is disabled. If the value is 1 then flood prevention is enabled for all multicast/broadcast
+packets excluding ICMPv6 and IGMP (cautious mode). If set to 2 then flood prevention is enabled for all multicast/broadcast
+packets (aggressive mode).
+.br
.IP "\fBloglevel\fP|\fBll\fP [\fBlevel\fP[ \fBlevel\fP[ \fBlevel\fP]] \fB...\fP]"
If no parameter is given the current log level settings are displayed otherwise the parameter(s) is/are used to set the log
level. Level 'none' disables all verbose logging. Level 'batman' enables messages related to routing / flooding / broadcasting.
--
2.20.1
3 years, 9 months