All of lore.kernel.org
 help / color / mirror / Atom feed
* [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2
@ 2018-12-07 13:58 Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 01/19] batman-adv: Move common genl doit code pre/post hooks Sven Eckelmann
                   ` (18 more replies)
  0 siblings, 19 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n

Hi,

Jiri Pirko called the batman-adv configuration interface a while back "a
huge mistake" [1] and suggested genl as alternative. The first
reimplementation [2] (based on the team/devlink design) was rejected. This
second implementation is now using a nl80211-like design. The objects
which can now be modified/queried are:

* mesh/soft-interface (BATADV_CMD_GET_MESH/BATADV_CMD_SET_MESH)
* slave/hard-interface (BATADV_CMD_GET_HARDIF/BATADV_CMD_SET_HARDIF)
* vlan (BATADV_CMD_GET_VLAN/BATADV_CMD_SET_VLAN)

Such a set messages automatically triggers a *_SET_* "reply" via the config
multicast group. The same behavior was also added to the sysfs interface.

I would like to ask the other developers to check whether their configuration
values are represented correctly. And please also check whether the current
implementation might collide with some other features which you might have
in your pipeline.

v3:
* correctly assign kernel-doc for BATADV_GW_MODE_CLIENT
* fix validation check for gw.sel_class
* fix setting of BATADV_ATTR_ORIG_INTERVAL
* Cc the (most likely) responsible developers for each setting to more
  directly ask them for feedback
v2:
* rewrite everything in a more nl80211-like message/attribute format.

Kind regards,
        Sven

[1] https://www.open-mesh.org/issues/300
[2] https://patchwork.open-mesh.org/cover/17610/

Sven Eckelmann (19):
  batman-adv: Move common genl doit code pre/post hooks
  batman-adv: Prepare framework for mesh genl config
  batman-adv: Prepare framework for hardif genl config
  batman-adv: Prepare framework for vlan genl config
  batman-adv: Add aggregated_ogms mesh genl configuration
  batman-adv: Add ap_isolation mesh/vlan genl configuration
  batman-adv: Add bonding mesh genl configuration
  batman-adv: Add bridge_loop_avoidance mesh genl configuration
  batman-adv: Add distributed_arp_table mesh genl configuration
  batman-adv: Add fragmentation mesh genl configuration
  batman-adv: Add gateway mesh genl configuration
  batman-adv: Add hop_penalty mesh genl configuration
  batman-adv: Add log_level mesh genl configuration
  batman-adv: Add multicast_mode mesh genl configuration
  batman-adv: Add network_coding mesh genl configuration
  batman-adv: Add orig_interval mesh genl configuration
  batman-adv: Add elp_interval hardif genl configuration
  batman-adv: Add throughput_override hardif genl configuration
  batman-adv: Trigger genl notification on sysfs config change

 include/uapi/linux/batman_adv.h |  188 +++++-
 net/batman-adv/gateway_client.c |    1 -
 net/batman-adv/gateway_common.c |    1 +
 net/batman-adv/gateway_common.h |    6 -
 net/batman-adv/netlink.c        | 1074 +++++++++++++++++++++++++++----
 net/batman-adv/netlink.h        |    6 +
 net/batman-adv/soft-interface.c |    2 +-
 net/batman-adv/sysfs.c          |   64 +-
 8 files changed, 1195 insertions(+), 147 deletions(-)

-- 
2.19.2


^ permalink raw reply	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 01/19] batman-adv: Move common genl doit code pre/post hooks
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-30 16:57   ` Linus Lüssing
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 02/19] batman-adv: Prepare framework for mesh genl config Sven Eckelmann
                   ` (17 subsequent siblings)
  18 siblings, 1 reply; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n

The commit ff4c92d85c6f ("genetlink: introduce pre_doit/post_doit hooks")
intoduced a mechanism to run specific code for doit hooks before/after the
hooks are run. Since all doit hooks are requiring the batadv softif, it
should be retrieved/freed in these helpers to simplify the code.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 net/batman-adv/netlink.c | 140 +++++++++++++++++++++++++++------------
 1 file changed, 97 insertions(+), 43 deletions(-)

diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 2dc3304c..b20801a3 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -20,8 +20,10 @@
 #include "main.h"
 
 #include <linux/atomic.h>
+#include <linux/bitops.h>
 #include <linux/byteorder/generic.h>
 #include <linux/cache.h>
+#include <linux/err.h>
 #include <linux/errno.h>
 #include <linux/export.h>
 #include <linux/genetlink.h>
@@ -54,6 +56,8 @@
 #include "tp_meter.h"
 #include "translation-table.h"
 
+struct net;
+
 struct genl_family batadv_netlink_family;
 
 /* multicast groups */
@@ -61,6 +65,18 @@ enum batadv_netlink_multicast_groups {
 	BATADV_NL_MCGRP_TPMETER,
 };
 
+/**
+ * enum batadv_genl_ops_flags - flags for genl_ops's internal_flags
+ */
+enum batadv_genl_ops_flags {
+	/**
+	 * @BATADV_FLAG_NEED_MESH: request requires valid soft interface in
+	 *  attribute BATADV_ATTR_MESH_IFINDEX and expects a pointer to it to be
+	 *  safed in info->user_ptr[0]
+	 */
+	BATADV_FLAG_NEED_MESH = BIT(0),
+};
+
 static const struct genl_multicast_group batadv_netlink_mcgrps[] = {
 	[BATADV_NL_MCGRP_TPMETER] = { .name = BATADV_NL_MCAST_GROUP_TPMETER },
 };
@@ -329,40 +345,24 @@ int batadv_netlink_tpmeter_notify(struct batadv_priv *bat_priv, const u8 *dst,
 static int
 batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info)
 {
-	struct net *net = genl_info_net(info);
-	struct net_device *soft_iface;
-	struct batadv_priv *bat_priv;
+	struct batadv_priv *bat_priv = info->user_ptr[0];
 	struct sk_buff *msg = NULL;
 	u32 test_length;
 	void *msg_head;
-	int ifindex;
 	u32 cookie;
 	u8 *dst;
 	int ret;
 
-	if (!info->attrs[BATADV_ATTR_MESH_IFINDEX])
-		return -EINVAL;
-
 	if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS])
 		return -EINVAL;
 
 	if (!info->attrs[BATADV_ATTR_TPMETER_TEST_TIME])
 		return -EINVAL;
 
-	ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]);
-	if (!ifindex)
-		return -EINVAL;
-
 	dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]);
 
 	test_length = nla_get_u32(info->attrs[BATADV_ATTR_TPMETER_TEST_TIME]);
 
-	soft_iface = dev_get_by_index(net, ifindex);
-	if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
-		ret = -ENODEV;
-		goto out;
-	}
-
 	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
 	if (!msg) {
 		ret = -ENOMEM;
@@ -377,15 +377,11 @@ batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info)
 		goto out;
 	}
 
-	bat_priv = netdev_priv(soft_iface);
 	batadv_tp_start(bat_priv, dst, test_length, &cookie);
 
 	ret = batadv_netlink_tp_meter_put(msg, cookie);
 
  out:
-	if (soft_iface)
-		dev_put(soft_iface);
-
 	if (ret) {
 		if (msg)
 			nlmsg_free(msg);
@@ -406,38 +402,17 @@ batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info)
 static int
 batadv_netlink_tp_meter_cancel(struct sk_buff *skb, struct genl_info *info)
 {
-	struct net *net = genl_info_net(info);
-	struct net_device *soft_iface;
-	struct batadv_priv *bat_priv;
-	int ifindex;
+	struct batadv_priv *bat_priv = info->user_ptr[0];
 	u8 *dst;
 	int ret = 0;
 
-	if (!info->attrs[BATADV_ATTR_MESH_IFINDEX])
-		return -EINVAL;
-
 	if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS])
 		return -EINVAL;
 
-	ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]);
-	if (!ifindex)
-		return -EINVAL;
-
 	dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]);
 
-	soft_iface = dev_get_by_index(net, ifindex);
-	if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
-		ret = -ENODEV;
-		goto out;
-	}
-
-	bat_priv = netdev_priv(soft_iface);
 	batadv_tp_stop(bat_priv, dst, BATADV_TP_REASON_CANCEL);
 
-out:
-	if (soft_iface)
-		dev_put(soft_iface);
-
 	return ret;
 }
 
@@ -545,6 +520,81 @@ batadv_netlink_dump_hardifs(struct sk_buff *msg, struct netlink_callback *cb)
 	return msg->len;
 }
 
+/**
+ * batadv_get_softif_from_info() - Retrieve soft interface from genl attributes
+ * @net: the applicable net namespace
+ * @info: receiver information
+ *
+ * Return: Pointer to soft interface on success, error pointer on error
+ */
+static struct batadv_priv *
+batadv_get_softif_from_info(struct net *net, struct genl_info *info)
+{
+	struct net_device *soft_iface;
+	int ifindex;
+
+	if (!info->attrs[BATADV_ATTR_MESH_IFINDEX])
+		return ERR_PTR(-EINVAL);
+
+	ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]);
+
+	soft_iface = dev_get_by_index(net, ifindex);
+	if (!soft_iface)
+		return ERR_PTR(-ENODEV);
+
+	if (!batadv_softif_is_valid(soft_iface))
+		goto err_put_softif;
+
+	return netdev_priv(soft_iface);
+
+err_put_softif:
+	dev_put(soft_iface);
+
+	return ERR_PTR(-EINVAL);
+}
+
+/**
+ * batadv_pre_doit() - Prepare batman-adv genl doit request
+ * @ops: requested netlink operation
+ * @skb: Netlink message with request data
+ * @info: receiver information
+ *
+ * Return: 0 on success or negative error number in case of failure
+ */
+static int batadv_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
+			   struct genl_info *info)
+{
+	struct batadv_priv *bat_priv;
+
+	if (ops->internal_flags & BATADV_FLAG_NEED_MESH) {
+		bat_priv = batadv_get_softif_from_info(genl_info_net(info),
+						       info);
+		if (IS_ERR(bat_priv))
+			return PTR_ERR(bat_priv);
+
+		info->user_ptr[0] = bat_priv;
+	}
+
+	return 0;
+}
+
+/**
+ * batadv_post_doit() - End batman-adv genl doit request
+ * @ops: requested netlink operation
+ * @skb: Netlink message with request data
+ * @info: receiver information
+ */
+static void batadv_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
+			     struct genl_info *info)
+{
+	struct batadv_priv *bat_priv;
+
+	if (ops->internal_flags & BATADV_FLAG_NEED_MESH && info->user_ptr[0]) {
+		bat_priv = info->user_ptr[0];
+		dev_put(bat_priv->soft_iface);
+	}
+}
+
 static const struct genl_ops batadv_netlink_ops[] = {
 	{
 		.cmd = BATADV_CMD_GET_MESH_INFO,
@@ -557,12 +607,14 @@ static const struct genl_ops batadv_netlink_ops[] = {
 		.flags = GENL_ADMIN_PERM,
 		.policy = batadv_netlink_policy,
 		.doit = batadv_netlink_tp_meter_start,
+		.internal_flags = BATADV_FLAG_NEED_MESH,
 	},
 	{
 		.cmd = BATADV_CMD_TP_METER_CANCEL,
 		.flags = GENL_ADMIN_PERM,
 		.policy = batadv_netlink_policy,
 		.doit = batadv_netlink_tp_meter_cancel,
+		.internal_flags = BATADV_FLAG_NEED_MESH,
 	},
 	{
 		.cmd = BATADV_CMD_GET_ROUTING_ALGOS,
@@ -639,6 +691,8 @@ struct genl_family batadv_netlink_family __ro_after_init = {
 	.version = 1,
 	.maxattr = BATADV_ATTR_MAX,
 	.netnsok = true,
+	.pre_doit = batadv_pre_doit,
+	.post_doit = batadv_post_doit,
 	.module = THIS_MODULE,
 	.ops = batadv_netlink_ops,
 	.n_ops = ARRAY_SIZE(batadv_netlink_ops),
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 02/19] batman-adv: Prepare framework for mesh genl config
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 01/19] batman-adv: Move common genl doit code pre/post hooks Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-31 11:09   ` Linus Lüssing
  2019-01-07 18:49   ` Linus Lüssing
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 03/19] batman-adv: Prepare framework for hardif " Sven Eckelmann
                   ` (16 subsequent siblings)
  18 siblings, 2 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n

The batman-adv configuration interface was implemented solely using sysfs.
This approach was condemned by non-batadv developers as "huge mistake".
Instead a netlink/genl based implementation was suggested.

The main objects for this configuration is the mesh/soft-interface object.
Its actual object in memory already contains most of the available
configuration settings. The genl interface reflects this by allowing to
get/set it using the mesh specific commands.

The BATADV_CMD_GET_MESH_INFO (or short version BATADV_CMD_GET_MESH) is
reused as get command because it already provides the content of other
information from the mesh/soft-interface which are not yet configuration
specific.

The set command BATADV_CMD_SET_MESH will also notify interested userspace
listeners of the "config" mcast group using the BATADV_CMD_SET_MESH command
message type that settings might have been changed and what the current
values are.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 include/uapi/linux/batman_adv.h |  16 +++-
 net/batman-adv/netlink.c        | 159 +++++++++++++++++++-------------
 2 files changed, 110 insertions(+), 65 deletions(-)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 324a0e11..2d6a175e 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -27,6 +27,7 @@
 
 #define BATADV_NL_NAME "batadv"
 
+#define BATADV_NL_MCAST_GROUP_CONFIG	"config"
 #define BATADV_NL_MCAST_GROUP_TPMETER	"tpmeter"
 
 /**
@@ -372,10 +373,14 @@ enum batadv_nl_commands {
 	BATADV_CMD_UNSPEC,
 
 	/**
-	 * @BATADV_CMD_GET_MESH_INFO: Query basic information about batman-adv
-	 * device
+	 * @BATADV_CMD_GET_MESH: Get attributes from softif/mesh
 	 */
-	BATADV_CMD_GET_MESH_INFO,
+	BATADV_CMD_GET_MESH,
+
+	/**
+	 * @BATADV_CMD_GET_MESH_INFO: Alias for @BATADV_CMD_GET_MESH
+	 */
+	BATADV_CMD_GET_MESH_INFO = BATADV_CMD_GET_MESH,
 
 	/**
 	 * @BATADV_CMD_TP_METER: Start a tp meter session
@@ -443,6 +448,11 @@ enum batadv_nl_commands {
 	 */
 	BATADV_CMD_GET_MCAST_FLAGS,
 
+	/**
+	 * @BATADV_CMD_SET_MESH: Set attributes for softif/mesh
+	 */
+	BATADV_CMD_SET_MESH,
+
 	/* add new commands above here */
 
 	/**
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index b20801a3..d89761f8 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -62,6 +62,7 @@ struct genl_family batadv_netlink_family;
 
 /* multicast groups */
 enum batadv_netlink_multicast_groups {
+	BATADV_NL_MCGRP_CONFIG,
 	BATADV_NL_MCGRP_TPMETER,
 };
 
@@ -78,6 +79,7 @@ enum batadv_genl_ops_flags {
 };
 
 static const struct genl_multicast_group batadv_netlink_mcgrps[] = {
+	[BATADV_NL_MCGRP_CONFIG] = { .name = BATADV_NL_MCAST_GROUP_CONFIG },
 	[BATADV_NL_MCGRP_TPMETER] = { .name = BATADV_NL_MCAST_GROUP_TPMETER },
 };
 
@@ -138,20 +140,29 @@ batadv_netlink_get_ifindex(const struct nlmsghdr *nlh, int attrtype)
 }
 
 /**
- * batadv_netlink_mesh_info_put() - fill in generic information about mesh
- *  interface
- * @msg: netlink message to be sent back
- * @soft_iface: interface for which the data should be taken
+ * batadv_netlink_mesh_put() - Fill message with mesh attributes
+ * @msg: Netlink message to dump into
+ * @bat_priv: the bat priv with all the soft interface information
+ * @cmd: type of message to generate
+ * @portid: Port making netlink request
+ * @seq: sequence number for message
+ * @flags: Additional flags for message
  *
- * Return: 0 on success, < 0 on error
+ * Return: 0 on success or negative error number in case of failure
  */
-static int
-batadv_netlink_mesh_info_put(struct sk_buff *msg, struct net_device *soft_iface)
+static int batadv_netlink_mesh_put(struct sk_buff *msg,
+				   struct batadv_priv *bat_priv,
+				   enum batadv_nl_commands cmd,
+				   u32 portid, u32 seq, int flags)
 {
-	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
+	struct net_device *soft_iface = bat_priv->soft_iface;
 	struct batadv_hard_iface *primary_if = NULL;
 	struct net_device *hard_iface;
-	int ret = -ENOBUFS;
+	void *hdr;
+
+	hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd);
+	if (!hdr)
+		return -ENOBUFS;
 
 	if (nla_put_string(msg, BATADV_ATTR_VERSION, BATADV_SOURCE_VERSION) ||
 	    nla_put_string(msg, BATADV_ATTR_ALGO_NAME,
@@ -162,16 +173,16 @@ batadv_netlink_mesh_info_put(struct sk_buff *msg, struct net_device *soft_iface)
 		    soft_iface->dev_addr) ||
 	    nla_put_u8(msg, BATADV_ATTR_TT_TTVN,
 		       (u8)atomic_read(&bat_priv->tt.vn)))
-		goto out;
+		goto nla_put_failure;
 
 #ifdef CONFIG_BATMAN_ADV_BLA
 	if (nla_put_u16(msg, BATADV_ATTR_BLA_CRC,
 			ntohs(bat_priv->bla.claim_dest.group)))
-		goto out;
+		goto nla_put_failure;
 #endif
 
 	if (batadv_mcast_mesh_info_put(msg, bat_priv))
-		goto out;
+		goto nla_put_failure;
 
 	primary_if = batadv_primary_if_get_selected(bat_priv);
 	if (primary_if && primary_if->if_status == BATADV_IF_ACTIVE) {
@@ -183,77 +194,94 @@ batadv_netlink_mesh_info_put(struct sk_buff *msg, struct net_device *soft_iface)
 				   hard_iface->name) ||
 		    nla_put(msg, BATADV_ATTR_HARD_ADDRESS, ETH_ALEN,
 			    hard_iface->dev_addr))
-			goto out;
+			goto nla_put_failure;
 	}
 
-	ret = 0;
+	batadv_hardif_put(primary_if);
 
- out:
+	genlmsg_end(msg, hdr);
+	return 0;
+
+nla_put_failure:
 	if (primary_if)
 		batadv_hardif_put(primary_if);
 
-	return ret;
+	genlmsg_cancel(msg, hdr);
+	return -EMSGSIZE;
 }
 
 /**
- * batadv_netlink_get_mesh_info() - handle incoming BATADV_CMD_GET_MESH_INFO
- *  netlink request
- * @skb: received netlink message
- * @info: receiver information
+ * batadv_netlink_notify_mesh() - send softif attributes to listener
+ * @bat_priv: the bat priv with all the soft interface information
  *
  * Return: 0 on success, < 0 on error
  */
-static int
-batadv_netlink_get_mesh_info(struct sk_buff *skb, struct genl_info *info)
+static int batadv_netlink_notify_mesh(struct batadv_priv *bat_priv)
 {
-	struct net *net = genl_info_net(info);
-	struct net_device *soft_iface;
-	struct sk_buff *msg = NULL;
-	void *msg_head;
-	int ifindex;
+	struct sk_buff *msg;
 	int ret;
 
-	if (!info->attrs[BATADV_ATTR_MESH_IFINDEX])
-		return -EINVAL;
-
-	ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]);
-	if (!ifindex)
-		return -EINVAL;
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
 
-	soft_iface = dev_get_by_index(net, ifindex);
-	if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
-		ret = -ENODEV;
-		goto out;
+	ret = batadv_netlink_mesh_put(msg, bat_priv, BATADV_CMD_SET_MESH,
+				      0, 0, 0);
+	if (ret < 0) {
+		nlmsg_free(msg);
+		return ret;
 	}
 
-	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
-	if (!msg) {
-		ret = -ENOMEM;
-		goto out;
-	}
+	genlmsg_multicast_netns(&batadv_netlink_family,
+				dev_net(bat_priv->soft_iface), msg, 0,
+				BATADV_NL_MCGRP_CONFIG, GFP_KERNEL);
 
-	msg_head = genlmsg_put(msg, info->snd_portid, info->snd_seq,
-			       &batadv_netlink_family, 0,
-			       BATADV_CMD_GET_MESH_INFO);
-	if (!msg_head) {
-		ret = -ENOBUFS;
-		goto out;
-	}
+	return 0;
+}
 
-	ret = batadv_netlink_mesh_info_put(msg, soft_iface);
+/**
+ * batadv_netlink_get_mesh() - Get softif attributes
+ * @skb: Netlink message with request data
+ * @info: receiver information
+ *
+ * Return: 0 on success or negative error number in case of failure
+ */
+static int batadv_netlink_get_mesh(struct sk_buff *skb, struct genl_info *info)
+{
+	struct batadv_priv *bat_priv = info->user_ptr[0];
+	struct sk_buff *msg;
+	int ret;
 
- out:
-	if (soft_iface)
-		dev_put(soft_iface);
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
 
-	if (ret) {
-		if (msg)
-			nlmsg_free(msg);
+	ret = batadv_netlink_mesh_put(msg, bat_priv, BATADV_CMD_GET_MESH,
+				      info->snd_portid, info->snd_seq, 0);
+	if (ret < 0) {
+		nlmsg_free(msg);
 		return ret;
 	}
 
-	genlmsg_end(msg, msg_head);
-	return genlmsg_reply(msg, info);
+	ret = genlmsg_reply(msg, info);
+
+	return ret;
+}
+
+/**
+ * batadv_netlink_set_mesh() - Set softif attributes
+ * @skb: Netlink message with request data
+ * @info: receiver information
+ *
+ * Return: 0 on success or negative error number in case of failure
+ */
+static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
+{
+	struct batadv_priv *bat_priv = info->user_ptr[0];
+
+	batadv_netlink_notify_mesh(bat_priv);
+
+	return 0;
 }
 
 /**
@@ -597,10 +625,11 @@ 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_INFO,
-		.flags = GENL_ADMIN_PERM,
+		.cmd = BATADV_CMD_GET_MESH,
+		/* can be retrieved by unprivileged users */
 		.policy = batadv_netlink_policy,
-		.doit = batadv_netlink_get_mesh_info,
+		.doit = batadv_netlink_get_mesh,
+		.internal_flags = BATADV_FLAG_NEED_MESH,
 	},
 	{
 		.cmd = BATADV_CMD_TP_METER,
@@ -682,7 +711,13 @@ static const struct genl_ops batadv_netlink_ops[] = {
 		.policy = batadv_netlink_policy,
 		.dumpit = batadv_mcast_flags_dump,
 	},
-
+	{
+		.cmd = BATADV_CMD_SET_MESH,
+		.flags = GENL_ADMIN_PERM,
+		.policy = batadv_netlink_policy,
+		.doit = batadv_netlink_set_mesh,
+		.internal_flags = BATADV_FLAG_NEED_MESH,
+	},
 };
 
 struct genl_family batadv_netlink_family __ro_after_init = {
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 03/19] batman-adv: Prepare framework for hardif genl config
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 01/19] batman-adv: Move common genl doit code pre/post hooks Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 02/19] batman-adv: Prepare framework for mesh genl config Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-31 11:59   ` Linus Lüssing
  2019-01-04  0:39   ` Linus Lüssing
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 04/19] batman-adv: Prepare framework for vlan " Sven Eckelmann
                   ` (15 subsequent siblings)
  18 siblings, 2 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n

The batman-adv configuration interface was implemented solely using sysfs.
This approach was condemned by non-batadv developers as "huge mistake".
Instead a netlink/genl based implementation was suggested.

Beside the mesh/soft-interface specific configuration, the
slave/hard-interface have B.A.T.M.A.N. V specific configuration settings.
The genl interface reflects this by allowing to get/set it using the
hard-interface specific commands.

The BATADV_CMD_GET_HARDIFS (or short version BATADV_CMD_GET_HARDIF) is
reused as get command because it already allow to dump the content of other
information from the slave/hard-interface which are not yet configuration
specific.

The set command BATADV_CMD_SET_HARDIF will also notify interested userspace
listeners of the "config" mcast group using the BATADV_CMD_SET_HARDIF
command message type that settings might have been changed and what the
current values are.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 include/uapi/linux/batman_adv.h |  16 ++-
 net/batman-adv/netlink.c        | 237 +++++++++++++++++++++++++++++---
 2 files changed, 230 insertions(+), 23 deletions(-)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 2d6a175e..eb5097df 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -398,9 +398,15 @@ enum batadv_nl_commands {
 	BATADV_CMD_GET_ROUTING_ALGOS,
 
 	/**
-	 * @BATADV_CMD_GET_HARDIFS: Query list of hard interfaces
+	 * @BATADV_CMD_GET_HARDIF: Get attributes from a hardif of the
+	 *  current softif
 	 */
-	BATADV_CMD_GET_HARDIFS,
+	BATADV_CMD_GET_HARDIF,
+
+	/**
+	 * @BATADV_CMD_GET_HARDIFS: Alias for @BATADV_CMD_GET_HARDIF
+	 */
+	BATADV_CMD_GET_HARDIFS = BATADV_CMD_GET_HARDIF,
 
 	/**
 	 * @BATADV_CMD_GET_TRANSTABLE_LOCAL: Query list of local translations
@@ -453,6 +459,12 @@ enum batadv_nl_commands {
 	 */
 	BATADV_CMD_SET_MESH,
 
+	/**
+	 * @BATADV_CMD_SET_HARDIF: Set attributes for hardif of the
+	 *  current softif
+	 */
+	BATADV_CMD_SET_HARDIF,
+
 	/* add new commands above here */
 
 	/**
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index d89761f8..68116eb8 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -21,6 +21,7 @@
 
 #include <linux/atomic.h>
 #include <linux/bitops.h>
+#include <linux/bug.h>
 #include <linux/byteorder/generic.h>
 #include <linux/cache.h>
 #include <linux/err.h>
@@ -76,6 +77,13 @@ enum batadv_genl_ops_flags {
 	 *  safed in info->user_ptr[0]
 	 */
 	BATADV_FLAG_NEED_MESH = BIT(0),
+
+	/**
+	 * @BATADV_FLAG_NEED_HARDIF: request requires valid hard interface in
+	 *  attribute BATADV_ATTR_HARD_IFINDEX and expects a pointer to it to be
+	 *  safed in info->user_ptr[1]
+	 */
+	BATADV_FLAG_NEED_HARDIF = BIT(1),
 };
 
 static const struct genl_multicast_group batadv_netlink_mcgrps[] = {
@@ -445,29 +453,38 @@ batadv_netlink_tp_meter_cancel(struct sk_buff *skb, struct genl_info *info)
 }
 
 /**
- * batadv_netlink_dump_hardif_entry() - Dump one hard interface into a message
+ * batadv_netlink_hardif_put() - Fill message with hardif attributes
  * @msg: Netlink message to dump into
+ * @bat_priv: the bat priv with all the soft interface information
+ * @hard_iface: hard interface which was modified
+ * @cmd: type of message to generate
  * @portid: Port making netlink request
+ * @seq: sequence number for message
+ * @flags: Additional flags for message
  * @cb: Control block containing additional options
- * @hard_iface: Hard interface to dump
  *
- * Return: error code, or 0 on success
+ * Return: 0 on success or negative error number in case of failure
  */
-static int
-batadv_netlink_dump_hardif_entry(struct sk_buff *msg, u32 portid,
-				 struct netlink_callback *cb,
-				 struct batadv_hard_iface *hard_iface)
+static int batadv_netlink_hardif_put(struct sk_buff *msg,
+				     struct batadv_priv *bat_priv,
+				     struct batadv_hard_iface *hard_iface,
+				     enum batadv_nl_commands cmd,
+				     u32 portid, u32 seq, int flags,
+				     struct netlink_callback *cb)
 {
 	struct net_device *net_dev = hard_iface->net_dev;
 	void *hdr;
 
-	hdr = genlmsg_put(msg, portid, cb->nlh->nlmsg_seq,
-			  &batadv_netlink_family, NLM_F_MULTI,
-			  BATADV_CMD_GET_HARDIFS);
+	hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd);
 	if (!hdr)
-		return -EMSGSIZE;
+		return -ENOBUFS;
+
+	if (cb)
+		genl_dump_check_consistent(cb, hdr);
 
-	genl_dump_check_consistent(cb, hdr);
+	if (nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX,
+			bat_priv->soft_iface->ifindex))
+		goto nla_put_failure;
 
 	if (nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
 			net_dev->ifindex) ||
@@ -485,24 +502,107 @@ batadv_netlink_dump_hardif_entry(struct sk_buff *msg, u32 portid,
 	genlmsg_end(msg, hdr);
 	return 0;
 
- nla_put_failure:
+nla_put_failure:
 	genlmsg_cancel(msg, hdr);
 	return -EMSGSIZE;
 }
 
 /**
- * batadv_netlink_dump_hardifs() - Dump all hard interface into a messages
+ * batadv_netlink_notify_hardif() - send hardif attributes to listener
+ * @bat_priv: the bat priv with all the soft interface information
+ * @hard_iface: hard interface which was modified
+ *
+ * Return: 0 on success, < 0 on error
+ */
+static int batadv_netlink_notify_hardif(struct batadv_priv *bat_priv,
+					struct batadv_hard_iface *hard_iface)
+{
+	struct sk_buff *msg;
+	int ret;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	ret = batadv_netlink_hardif_put(msg, bat_priv, hard_iface,
+					BATADV_CMD_SET_HARDIF, 0, 0, 0, NULL);
+	if (ret < 0) {
+		nlmsg_free(msg);
+		return ret;
+	}
+
+	genlmsg_multicast_netns(&batadv_netlink_family,
+				dev_net(bat_priv->soft_iface), msg, 0,
+				BATADV_NL_MCGRP_CONFIG, GFP_KERNEL);
+
+	return 0;
+}
+
+/**
+ * batadv_netlink_get_hardif() - Get hardif attributes
+ * @skb: Netlink message with request data
+ * @info: receiver information
+ *
+ * Return: 0 on success or negative error number in case of failure
+ */
+static int batadv_netlink_get_hardif(struct sk_buff *skb,
+				     struct genl_info *info)
+{
+	struct batadv_hard_iface *hard_iface = info->user_ptr[1];
+	struct batadv_priv *bat_priv = info->user_ptr[0];
+	struct sk_buff *msg;
+	int ret;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	ret = batadv_netlink_hardif_put(msg, bat_priv, hard_iface,
+					BATADV_CMD_GET_HARDIF,
+					info->snd_portid, info->snd_seq, 0,
+					NULL);
+	if (ret < 0) {
+		nlmsg_free(msg);
+		return ret;
+	}
+
+	ret = genlmsg_reply(msg, info);
+
+	return ret;
+}
+
+/**
+ * batadv_netlink_set_hardif() - Set hardif attributes
+ * @skb: Netlink message with request data
+ * @info: receiver information
+ *
+ * Return: 0 on success or negative error number in case of failure
+ */
+static int batadv_netlink_set_hardif(struct sk_buff *skb,
+				     struct genl_info *info)
+{
+	struct batadv_hard_iface *hard_iface = info->user_ptr[1];
+	struct batadv_priv *bat_priv = info->user_ptr[0];
+
+	batadv_netlink_notify_hardif(bat_priv, hard_iface);
+
+	return 0;
+}
+
+/**
+ * batadv_netlink_dump_hardif() - Dump all hard interface into a messages
  * @msg: Netlink message to dump into
  * @cb: Parameters from query
  *
  * Return: error code, or length of reply message on success
  */
 static int
-batadv_netlink_dump_hardifs(struct sk_buff *msg, struct netlink_callback *cb)
+batadv_netlink_dump_hardif(struct sk_buff *msg, struct netlink_callback *cb)
 {
 	struct net *net = sock_net(cb->skb->sk);
 	struct net_device *soft_iface;
 	struct batadv_hard_iface *hard_iface;
+	struct batadv_priv *bat_priv;
 	int ifindex;
 	int portid = NETLINK_CB(cb->skb).portid;
 	int skip = cb->args[0];
@@ -522,6 +622,8 @@ batadv_netlink_dump_hardifs(struct sk_buff *msg, struct netlink_callback *cb)
 		return -ENODEV;
 	}
 
+	bat_priv = netdev_priv(soft_iface);
+
 	rtnl_lock();
 	cb->seq = batadv_hardif_generation << 1 | 1;
 
@@ -532,8 +634,10 @@ batadv_netlink_dump_hardifs(struct sk_buff *msg, struct netlink_callback *cb)
 		if (i++ < skip)
 			continue;
 
-		if (batadv_netlink_dump_hardif_entry(msg, portid, cb,
-						     hard_iface)) {
+		if (batadv_netlink_hardif_put(msg, bat_priv, hard_iface,
+					      BATADV_CMD_GET_HARDIF,
+					      portid, cb->nlh->nlmsg_seq,
+					      NLM_F_MULTI, cb)) {
 			i--;
 			break;
 		}
@@ -581,6 +685,48 @@ batadv_get_softif_from_info(struct net *net, struct genl_info *info)
 	return ERR_PTR(-EINVAL);
 }
 
+/**
+ * batadv_get_hardif_from_info() - Retrieve hardif from genl attributes
+ * @bat_priv: the bat priv with all the soft interface information
+ * @net: the applicable net namespace
+ * @info: receiver information
+ *
+ * Return: Pointer to hard interface on success, error pointer on error
+ */
+static struct batadv_hard_iface *
+batadv_get_hardif_from_info(struct batadv_priv *bat_priv, struct net *net,
+			    struct genl_info *info)
+{
+	struct batadv_hard_iface *hard_iface;
+	struct net_device *hard_dev;
+	unsigned int hardif_index;
+
+	if (!info->attrs[BATADV_ATTR_HARD_IFINDEX])
+		return ERR_PTR(-EINVAL);
+
+	hardif_index = nla_get_u32(info->attrs[BATADV_ATTR_HARD_IFINDEX]);
+
+	hard_dev = dev_get_by_index(net, hardif_index);
+	if (!hard_dev)
+		return ERR_PTR(-ENODEV);
+
+	hard_iface = batadv_hardif_get_by_netdev(hard_dev);
+	if (!hard_iface)
+		goto err_put_harddev;
+
+	if (hard_iface->soft_iface != bat_priv->soft_iface)
+		goto err_put_hardif;
+
+	return hard_iface;
+
+err_put_hardif:
+	batadv_hardif_put(hard_iface);
+err_put_harddev:
+	dev_put(hard_dev);
+
+	return ERR_PTR(-EINVAL);
+}
+
 /**
  * batadv_pre_doit() - Prepare batman-adv genl doit request
  * @ops: requested netlink operation
@@ -592,7 +738,16 @@ batadv_get_softif_from_info(struct net *net, struct genl_info *info)
 static int batadv_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
 			   struct genl_info *info)
 {
-	struct batadv_priv *bat_priv;
+	struct batadv_hard_iface *hard_iface;
+	struct batadv_priv *bat_priv = NULL;
+	int ret;
+
+	if (WARN_ON(ops->internal_flags & BATADV_FLAG_NEED_HARDIF))
+		return -EINVAL;
+
+	if (WARN_ON((ops->internal_flags & BATADV_FLAG_NEED_HARDIF) &&
+		    (~ops->internal_flags & BATADV_FLAG_NEED_MESH)))
+		return -EINVAL;
 
 	if (ops->internal_flags & BATADV_FLAG_NEED_MESH) {
 		bat_priv = batadv_get_softif_from_info(genl_info_net(info),
@@ -603,7 +758,25 @@ static int batadv_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
 		info->user_ptr[0] = bat_priv;
 	}
 
+	if (ops->internal_flags & BATADV_FLAG_NEED_HARDIF) {
+		hard_iface = batadv_get_hardif_from_info(bat_priv,
+							 genl_info_net(info),
+							 info);
+		if (IS_ERR(hard_iface)) {
+			ret = PTR_ERR(hard_iface);
+			goto err_put_softif;
+		}
+
+		info->user_ptr[1] = hard_iface;
+	}
+
 	return 0;
+
+err_put_softif:
+	if (bat_priv)
+		dev_put(bat_priv->soft_iface);
+
+	return ret;
 }
 
 /**
@@ -615,7 +788,18 @@ static int batadv_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
 static void batadv_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
 			     struct genl_info *info)
 {
+	struct batadv_hard_iface *hard_iface;
 	struct batadv_priv *bat_priv;
+	struct net_device *hard_dev;
+
+	if (ops->internal_flags & BATADV_FLAG_NEED_HARDIF &&
+	    info->user_ptr[1]) {
+		hard_iface = info->user_ptr[1];
+		hard_dev = hard_iface->net_dev;
+
+		batadv_hardif_put(hard_iface);
+		dev_put(hard_dev);
+	}
 
 	if (ops->internal_flags & BATADV_FLAG_NEED_MESH && info->user_ptr[0]) {
 		bat_priv = info->user_ptr[0];
@@ -652,10 +836,13 @@ static const struct genl_ops batadv_netlink_ops[] = {
 		.dumpit = batadv_algo_dump,
 	},
 	{
-		.cmd = BATADV_CMD_GET_HARDIFS,
-		.flags = GENL_ADMIN_PERM,
+		.cmd = BATADV_CMD_GET_HARDIF,
+		/* can be retrieved by unprivileged users */
 		.policy = batadv_netlink_policy,
-		.dumpit = batadv_netlink_dump_hardifs,
+		.dumpit = batadv_netlink_dump_hardif,
+		.doit = batadv_netlink_get_hardif,
+		.internal_flags = BATADV_FLAG_NEED_MESH |
+				  BATADV_FLAG_NEED_HARDIF,
 	},
 	{
 		.cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL,
@@ -718,6 +905,14 @@ static const struct genl_ops batadv_netlink_ops[] = {
 		.doit = batadv_netlink_set_mesh,
 		.internal_flags = BATADV_FLAG_NEED_MESH,
 	},
+	{
+		.cmd = BATADV_CMD_SET_HARDIF,
+		.flags = GENL_ADMIN_PERM,
+		.policy = batadv_netlink_policy,
+		.doit = batadv_netlink_set_hardif,
+		.internal_flags = BATADV_FLAG_NEED_MESH |
+				  BATADV_FLAG_NEED_HARDIF,
+	},
 };
 
 struct genl_family batadv_netlink_family __ro_after_init = {
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 04/19] batman-adv: Prepare framework for vlan genl config
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (2 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 03/19] batman-adv: Prepare framework for hardif " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2019-01-04  1:53   ` Linus Lüssing
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 05/19] batman-adv: Add aggregated_ogms mesh genl configuration Sven Eckelmann
                   ` (14 subsequent siblings)
  18 siblings, 1 reply; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n

The batman-adv configuration interface was implemented solely using sysfs.
This approach was condemned by non-batadv developers as "huge mistake".
Instead a netlink/genl based implementation was suggested.

Beside the mesh/soft-interface specific configuration, the VLANs on top of
the mesh/soft-interface have configuration settings. The genl interface
reflects this by allowing to get/set it using the vlan specific commands
BATADV_CMD_GET_VLAN/BATADV_CMD_SET_VLAN.

The set command BATADV_CMD_SET_MESH will also notify interested userspace
listeners of the "config" mcast group using the BATADV_CMD_SET_VLAN command
message type that settings might have been changed and what the current
values are.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 include/uapi/linux/batman_adv.h |  17 +++
 net/batman-adv/netlink.c        | 193 +++++++++++++++++++++++++++++++-
 2 files changed, 208 insertions(+), 2 deletions(-)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index eb5097df..865cdf90 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -345,6 +345,11 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_MCAST_FLAGS_PRIV,
 
+	/**
+	 * @BATADV_ATTR_VLANID: VLAN id on top of soft interface
+	 */
+	BATADV_ATTR_VLANID,
+
 	/* add attributes above here, update the policy in netlink.c */
 
 	/**
@@ -465,6 +470,18 @@ enum batadv_nl_commands {
 	 */
 	BATADV_CMD_SET_HARDIF,
 
+	/**
+	 * @BATADV_CMD_GET_VLAN: Get attributes from a VLAN of the
+	 *  current softif
+	 */
+	BATADV_CMD_GET_VLAN,
+
+	/**
+	 * @BATADV_CMD_SET_VLAN: Set attributes for VLAN of the
+	 *  current softif
+	 */
+	BATADV_CMD_SET_VLAN,
+
 	/* add new commands above here */
 
 	/**
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 68116eb8..30ed0672 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -30,6 +30,7 @@
 #include <linux/genetlink.h>
 #include <linux/gfp.h>
 #include <linux/if_ether.h>
+#include <linux/if_vlan.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
@@ -84,6 +85,13 @@ enum batadv_genl_ops_flags {
 	 *  safed in info->user_ptr[1]
 	 */
 	BATADV_FLAG_NEED_HARDIF = BIT(1),
+
+	/**
+	 * @BATADV_FLAG_NEED_VLAN: request requires valid vlan in
+	 *  attribute BATADV_ATTR_VLANID and expects a pointer to it to be
+	 *  safed in info->user_ptr[1]
+	 */
+	BATADV_FLAG_NEED_VLAN = BIT(2),
 };
 
 static const struct genl_multicast_group batadv_netlink_mcgrps[] = {
@@ -130,6 +138,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_DAT_CACHE_VID]		= { .type = NLA_U16 },
 	[BATADV_ATTR_MCAST_FLAGS]		= { .type = NLA_U32 },
 	[BATADV_ATTR_MCAST_FLAGS_PRIV]		= { .type = NLA_U32 },
+	[BATADV_ATTR_VLANID]			= { .type = NLA_U16 },
 };
 
 /**
@@ -652,6 +661,123 @@ batadv_netlink_dump_hardif(struct sk_buff *msg, struct netlink_callback *cb)
 	return msg->len;
 }
 
+/**
+ * batadv_netlink_vlan_put() - Fill message with vlan attributes
+ * @msg: Netlink message to dump into
+ * @bat_priv: the bat priv with all the soft interface information
+ * @vlan: vlan which was modified
+ * @cmd: type of message to generate
+ * @portid: Port making netlink request
+ * @seq: sequence number for message
+ * @flags: Additional flags for message
+ *
+ * Return: 0 on success or negative error number in case of failure
+ */
+static int batadv_netlink_vlan_put(struct sk_buff *msg,
+				   struct batadv_priv *bat_priv,
+				   struct batadv_softif_vlan *vlan,
+				   enum batadv_nl_commands cmd,
+				   u32 portid, u32 seq, int flags)
+{
+	void *hdr;
+
+	hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd);
+	if (!hdr)
+		return -ENOBUFS;
+
+	if (nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX,
+			bat_priv->soft_iface->ifindex))
+		goto nla_put_failure;
+
+	if (nla_put_u32(msg, BATADV_ATTR_VLANID, vlan->vid & VLAN_VID_MASK))
+		goto nla_put_failure;
+
+	genlmsg_end(msg, hdr);
+	return 0;
+
+nla_put_failure:
+	genlmsg_cancel(msg, hdr);
+	return -EMSGSIZE;
+}
+
+/**
+ * batadv_netlink_notify_vlan() - send vlan attributes to listener
+ * @bat_priv: the bat priv with all the soft interface information
+ * @vlan: vlan which was modified
+ *
+ * Return: 0 on success, < 0 on error
+ */
+static int batadv_netlink_notify_vlan(struct batadv_priv *bat_priv,
+				      struct batadv_softif_vlan *vlan)
+{
+	struct sk_buff *msg;
+	int ret;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	ret = batadv_netlink_vlan_put(msg, bat_priv, vlan,
+				      BATADV_CMD_SET_VLAN, 0, 0, 0);
+	if (ret < 0) {
+		nlmsg_free(msg);
+		return ret;
+	}
+
+	genlmsg_multicast_netns(&batadv_netlink_family,
+				dev_net(bat_priv->soft_iface), msg, 0,
+				BATADV_NL_MCGRP_CONFIG, GFP_KERNEL);
+
+	return 0;
+}
+
+/**
+ * batadv_netlink_get_vlan() - Get vlan attributes
+ * @skb: Netlink message with request data
+ * @info: receiver information
+ *
+ * Return: 0 on success or negative error number in case of failure
+ */
+static int batadv_netlink_get_vlan(struct sk_buff *skb, struct genl_info *info)
+{
+	struct batadv_softif_vlan *vlan = info->user_ptr[1];
+	struct batadv_priv *bat_priv = info->user_ptr[0];
+	struct sk_buff *msg;
+	int ret;
+
+	msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+
+	ret = batadv_netlink_vlan_put(msg, bat_priv, vlan, BATADV_CMD_GET_VLAN,
+				      info->snd_portid, info->snd_seq, 0);
+	if (ret < 0) {
+		nlmsg_free(msg);
+		return ret;
+	}
+
+	ret = genlmsg_reply(msg, info);
+
+	return ret;
+}
+
+/**
+ * batadv_netlink_set_vlan() - Get vlan attributes
+ * @skb: Netlink message with request data
+ * @info: receiver information
+ *
+ * Return: 0 on success or negative error number in case of failure
+ */
+static int batadv_netlink_set_vlan(struct sk_buff *skb, struct genl_info *info)
+{
+	struct batadv_softif_vlan *vlan = info->user_ptr[1];
+	struct batadv_priv *bat_priv = info->user_ptr[0];
+
+	batadv_netlink_notify_vlan(bat_priv, vlan);
+
+	return 0;
+}
+
 /**
  * batadv_get_softif_from_info() - Retrieve soft interface from genl attributes
  * @net: the applicable net namespace
@@ -727,6 +853,33 @@ batadv_get_hardif_from_info(struct batadv_priv *bat_priv, struct net *net,
 	return ERR_PTR(-EINVAL);
 }
 
+/**
+ * batadv_get_vlan_from_info() - Retrieve vlan from genl attributes
+ * @bat_priv: the bat priv with all the soft interface information
+ * @net: the applicable net namespace
+ * @info: receiver information
+ *
+ * Return: Pointer to vlan on success, error pointer on error
+ */
+static struct batadv_softif_vlan *
+batadv_get_vlan_from_info(struct batadv_priv *bat_priv, struct net *net,
+			  struct genl_info *info)
+{
+	struct batadv_softif_vlan *vlan;
+	u16 vid;
+
+	if (!info->attrs[BATADV_ATTR_VLANID])
+		return ERR_PTR(-EINVAL);
+
+	vid = nla_get_u16(info->attrs[BATADV_ATTR_VLANID]);
+
+	vlan = batadv_softif_vlan_get(bat_priv, vid | BATADV_VLAN_HAS_TAG);
+	if (!vlan)
+		return ERR_PTR(-ENOENT);
+
+	return vlan;
+}
+
 /**
  * batadv_pre_doit() - Prepare batman-adv genl doit request
  * @ops: requested netlink operation
@@ -740,12 +893,15 @@ static int batadv_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
 {
 	struct batadv_hard_iface *hard_iface;
 	struct batadv_priv *bat_priv = NULL;
+	struct batadv_softif_vlan *vlan;
 	int ret;
 
-	if (WARN_ON(ops->internal_flags & BATADV_FLAG_NEED_HARDIF))
+	if (WARN_ON((ops->internal_flags & BATADV_FLAG_NEED_HARDIF) &&
+		    (ops->internal_flags & BATADV_FLAG_NEED_VLAN)))
 		return -EINVAL;
 
-	if (WARN_ON((ops->internal_flags & BATADV_FLAG_NEED_HARDIF) &&
+	if (WARN_ON(((ops->internal_flags & BATADV_FLAG_NEED_HARDIF) ||
+		     (ops->internal_flags & BATADV_FLAG_NEED_VLAN)) &&
 		    (~ops->internal_flags & BATADV_FLAG_NEED_MESH)))
 		return -EINVAL;
 
@@ -770,6 +926,17 @@ static int batadv_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
 		info->user_ptr[1] = hard_iface;
 	}
 
+	if (ops->internal_flags & BATADV_FLAG_NEED_VLAN) {
+		vlan = batadv_get_vlan_from_info(bat_priv, genl_info_net(info),
+						 info);
+		if (IS_ERR(vlan)) {
+			ret = PTR_ERR(vlan);
+			goto err_put_softif;
+		}
+
+		info->user_ptr[1] = vlan;
+	}
+
 	return 0;
 
 err_put_softif:
@@ -789,6 +956,7 @@ static void batadv_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
 			     struct genl_info *info)
 {
 	struct batadv_hard_iface *hard_iface;
+	struct batadv_softif_vlan *vlan;
 	struct batadv_priv *bat_priv;
 	struct net_device *hard_dev;
 
@@ -801,6 +969,11 @@ static void batadv_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
 		dev_put(hard_dev);
 	}
 
+	if (ops->internal_flags & BATADV_FLAG_NEED_VLAN && info->user_ptr[1]) {
+		vlan = info->user_ptr[1];
+		batadv_softif_vlan_put(vlan);
+	}
+
 	if (ops->internal_flags & BATADV_FLAG_NEED_MESH && info->user_ptr[0]) {
 		bat_priv = info->user_ptr[0];
 		dev_put(bat_priv->soft_iface);
@@ -913,6 +1086,22 @@ static const struct genl_ops batadv_netlink_ops[] = {
 		.internal_flags = BATADV_FLAG_NEED_MESH |
 				  BATADV_FLAG_NEED_HARDIF,
 	},
+	{
+		.cmd = BATADV_CMD_GET_VLAN,
+		/* can be retrieved by unprivileged users */
+		.policy = batadv_netlink_policy,
+		.doit = batadv_netlink_get_vlan,
+		.internal_flags = BATADV_FLAG_NEED_MESH |
+				  BATADV_FLAG_NEED_VLAN,
+	},
+	{
+		.cmd = BATADV_CMD_SET_VLAN,
+		.flags = GENL_ADMIN_PERM,
+		.policy = batadv_netlink_policy,
+		.doit = batadv_netlink_set_vlan,
+		.internal_flags = BATADV_FLAG_NEED_MESH |
+				  BATADV_FLAG_NEED_VLAN,
+	},
 };
 
 struct genl_family batadv_netlink_family __ro_after_init = {
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 05/19] batman-adv: Add aggregated_ogms mesh genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (3 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 04/19] batman-adv: Prepare framework for vlan " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2019-01-04  1:40   ` Linus Lüssing
  2019-01-04  2:06   ` Linus Lüssing
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 06/19] batman-adv: Add ap_isolation mesh/vlan " Sven Eckelmann
                   ` (13 subsequent siblings)
  18 siblings, 2 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann, Marek Lindner

The mesh interface can delay OGM messages to aggregate different ogms
together in a single OGM packet.

The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH commands allow to set/get the
configuration of this feature using the BATADV_ATTR_AGGREGATED_OGMS
attribute. Setting the u8 to zero will disable this feature and setting it
to something else is enabling this feature.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Marek Lindner <mareklindner@neomailbox.ch>
---
 include/uapi/linux/batman_adv.h |  6 ++++++
 net/batman-adv/netlink.c        | 12 ++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 865cdf90..a01d90ed 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -350,6 +350,12 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_VLANID,
 
+	/**
+	 * @BATADV_ATTR_AGGREGATED_OGMS: whether the batman protocol messages
+	 *  of the mesh mesh interface shall be aggregated or not.
+	 */
+	BATADV_ATTR_AGGREGATED_OGMS,
+
 	/* 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 30ed0672..862d47c4 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -139,6 +139,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_MCAST_FLAGS]		= { .type = NLA_U32 },
 	[BATADV_ATTR_MCAST_FLAGS_PRIV]		= { .type = NLA_U32 },
 	[BATADV_ATTR_VLANID]			= { .type = NLA_U16 },
+	[BATADV_ATTR_AGGREGATED_OGMS]		= { .type = NLA_U8 },
 };
 
 /**
@@ -214,6 +215,10 @@ static int batadv_netlink_mesh_put(struct sk_buff *msg,
 			goto nla_put_failure;
 	}
 
+	if (nla_put_u8(msg, BATADV_ATTR_AGGREGATED_OGMS,
+		       !!atomic_read(&bat_priv->aggregated_ogms)))
+		goto nla_put_failure;
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -295,6 +300,13 @@ static int batadv_netlink_get_mesh(struct sk_buff *skb, struct genl_info *info)
 static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 {
 	struct batadv_priv *bat_priv = info->user_ptr[0];
+	struct nlattr *attr;
+
+	if (info->attrs[BATADV_ATTR_AGGREGATED_OGMS]) {
+		attr = info->attrs[BATADV_ATTR_AGGREGATED_OGMS];
+
+		atomic_set(&bat_priv->aggregated_ogms, !!nla_get_u8(attr));
+	}
 
 	batadv_netlink_notify_mesh(bat_priv);
 
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 06/19] batman-adv: Add ap_isolation mesh/vlan genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (4 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 05/19] batman-adv: Add aggregated_ogms mesh genl configuration Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 07/19] batman-adv: Add bonding mesh " Sven Eckelmann
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann, Antonio Quartulli

The mesh interface can drop messages between clients to implement a
mesh-wide AP isolation.

The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH and
BATADV_CMD_SET_VLAN/BATADV_CMD_GET_VLAN commands allow to set/get the
configuration of this feature using the BATADV_ATTR_AP_ISOLATION attribute.
Setting the u8 to zero will disable this feature and setting it to
something else is enabling this feature.

This feature also requires that skbuff which should be handled as isolated
are marked. The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH commands allow to
set/get the mark/mask using the u32 attributes BATADV_ATTR_ISOLATION_MARK
and BATADV_ATTR_ISOLATION_MASK.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Antonio Quartulli <a@unstable.cc>
---
 include/uapi/linux/batman_adv.h | 18 +++++++
 net/batman-adv/netlink.c        | 88 +++++++++++++++++++++++++++++++++
 2 files changed, 106 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index a01d90ed..75738032 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -356,6 +356,24 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_AGGREGATED_OGMS,
 
+	/**
+	 * @BATADV_ATTR_AP_ISOLATION: whether the data traffic going from a
+	 *  wireless client to another wireless client will be silently dropped.
+	 */
+	BATADV_ATTR_AP_ISOLATION,
+
+	/**
+	 * @BATADV_ATTR_ISOLATION_MARK: the isolation mark which is used to
+	 *  classify clients as "isolated" by the Extended Isolation feature.
+	 */
+	BATADV_ATTR_ISOLATION_MARK,
+
+	/**
+	 * @BATADV_ATTR_ISOLATION_MASK: the isolation (bit)mask which is used to
+	 *  classify clients as "isolated" by the Extended Isolation feature.
+	 */
+	BATADV_ATTR_ISOLATION_MASK,
+
 	/* 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 862d47c4..217c4b30 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -140,6 +140,9 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_MCAST_FLAGS_PRIV]		= { .type = NLA_U32 },
 	[BATADV_ATTR_VLANID]			= { .type = NLA_U16 },
 	[BATADV_ATTR_AGGREGATED_OGMS]		= { .type = NLA_U8 },
+	[BATADV_ATTR_AP_ISOLATION]		= { .type = NLA_U8 },
+	[BATADV_ATTR_ISOLATION_MARK]		= { .type = NLA_U32 },
+	[BATADV_ATTR_ISOLATION_MASK]		= { .type = NLA_U32 },
 };
 
 /**
@@ -157,6 +160,51 @@ batadv_netlink_get_ifindex(const struct nlmsghdr *nlh, int attrtype)
 	return attr ? nla_get_u32(attr) : 0;
 }
 
+/**
+ * batadv_netlink_mesh_put_ap_isolation() - Add ap_isolation softif attribute
+ * @msg: Netlink message to dump into
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Return: 0 on success or negative error number in case of failure
+ */
+static int batadv_netlink_mesh_put_ap_isolation(struct sk_buff *msg,
+						struct batadv_priv *bat_priv)
+{
+	struct batadv_softif_vlan *vlan;
+	u8 ap_isolation;
+
+	vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS);
+	if (!vlan)
+		return 0;
+
+	ap_isolation = atomic_read(&vlan->ap_isolation);
+	batadv_softif_vlan_put(vlan);
+
+	return nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION, !!ap_isolation);
+}
+
+/**
+ * batadv_option_set_ap_isolation() - Set ap_isolation from genl msg
+ * @attr: parsed BATADV_ATTR_AP_ISOLATION attribute
+ * @bat_priv: the bat priv with all the soft interface information
+ *
+ * Return: 0 on success or negative error number in case of failure
+ */
+static int batadv_netlink_set_mesh_ap_isolation(struct nlattr *attr,
+						struct batadv_priv *bat_priv)
+{
+	struct batadv_softif_vlan *vlan;
+
+	vlan = batadv_softif_vlan_get(bat_priv, BATADV_NO_FLAGS);
+	if (!vlan)
+		return -ENOENT;
+
+	atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr));
+	batadv_softif_vlan_put(vlan);
+
+	return 0;
+}
+
 /**
  * batadv_netlink_mesh_put() - Fill message with mesh attributes
  * @msg: Netlink message to dump into
@@ -219,6 +267,17 @@ static int batadv_netlink_mesh_put(struct sk_buff *msg,
 		       !!atomic_read(&bat_priv->aggregated_ogms)))
 		goto nla_put_failure;
 
+	if (batadv_netlink_mesh_put_ap_isolation(msg, bat_priv))
+		goto nla_put_failure;
+
+	if (nla_put_u32(msg, BATADV_ATTR_ISOLATION_MARK,
+			bat_priv->isolation_mark))
+		goto nla_put_failure;
+
+	if (nla_put_u32(msg, BATADV_ATTR_ISOLATION_MASK,
+			bat_priv->isolation_mark_mask))
+		goto nla_put_failure;
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -308,6 +367,24 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 		atomic_set(&bat_priv->aggregated_ogms, !!nla_get_u8(attr));
 	}
 
+	if (info->attrs[BATADV_ATTR_AP_ISOLATION]) {
+		attr = info->attrs[BATADV_ATTR_AP_ISOLATION];
+
+		batadv_netlink_set_mesh_ap_isolation(attr, bat_priv);
+	}
+
+	if (info->attrs[BATADV_ATTR_ISOLATION_MARK]) {
+		attr = info->attrs[BATADV_ATTR_ISOLATION_MARK];
+
+		bat_priv->isolation_mark = nla_get_u32(attr);
+	}
+
+	if (info->attrs[BATADV_ATTR_ISOLATION_MASK]) {
+		attr = info->attrs[BATADV_ATTR_ISOLATION_MASK];
+
+		bat_priv->isolation_mark_mask = nla_get_u32(attr);
+	}
+
 	batadv_netlink_notify_mesh(bat_priv);
 
 	return 0;
@@ -704,6 +781,10 @@ static int batadv_netlink_vlan_put(struct sk_buff *msg,
 	if (nla_put_u32(msg, BATADV_ATTR_VLANID, vlan->vid & VLAN_VID_MASK))
 		goto nla_put_failure;
 
+	if (nla_put_u8(msg, BATADV_ATTR_AP_ISOLATION,
+		       !!atomic_read(&vlan->ap_isolation)))
+		goto nla_put_failure;
+
 	genlmsg_end(msg, hdr);
 	return 0;
 
@@ -784,6 +865,13 @@ static int batadv_netlink_set_vlan(struct sk_buff *skb, struct genl_info *info)
 {
 	struct batadv_softif_vlan *vlan = info->user_ptr[1];
 	struct batadv_priv *bat_priv = info->user_ptr[0];
+	struct nlattr *attr;
+
+	if (info->attrs[BATADV_ATTR_AP_ISOLATION]) {
+		attr = info->attrs[BATADV_ATTR_AP_ISOLATION];
+
+		atomic_set(&vlan->ap_isolation, !!nla_get_u8(attr));
+	}
 
 	batadv_netlink_notify_vlan(bat_priv, vlan);
 
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 07/19] batman-adv: Add bonding mesh genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (5 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 06/19] batman-adv: Add ap_isolation mesh/vlan " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 08/19] batman-adv: Add bridge_loop_avoidance " Sven Eckelmann
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n

The mesh interface can use multiple slave/hard-interface ports at the same
time to transport the traffic to other nodes.

The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH commands allow to set/get the
configuration of this feature using the BATADV_ATTR_BONDING attribute.
Setting the u8 to zero will disable this feature and setting it to
something else is enabling this feature.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Simon Wunderlich <sw@simonwunderlich.de>
---
 include/uapi/linux/batman_adv.h |  6 ++++++
 net/batman-adv/netlink.c        | 11 +++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 75738032..d209c468 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -374,6 +374,12 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_ISOLATION_MASK,
 
+	/**
+	 * @BATADV_ATTR_BONDING: whether the data traffic going through the
+	 *  mesh will be sent using multiple interfaces at the same time.
+	 */
+	BATADV_ATTR_BONDING,
+
 	/* 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 217c4b30..a836a8f1 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -143,6 +143,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_AP_ISOLATION]		= { .type = NLA_U8 },
 	[BATADV_ATTR_ISOLATION_MARK]		= { .type = NLA_U32 },
 	[BATADV_ATTR_ISOLATION_MASK]		= { .type = NLA_U32 },
+	[BATADV_ATTR_BONDING]			= { .type = NLA_U8 },
 };
 
 /**
@@ -278,6 +279,10 @@ static int batadv_netlink_mesh_put(struct sk_buff *msg,
 			bat_priv->isolation_mark_mask))
 		goto nla_put_failure;
 
+	if (nla_put_u8(msg, BATADV_ATTR_BONDING,
+		       !!atomic_read(&bat_priv->bonding)))
+		goto nla_put_failure;
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -385,6 +390,12 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 		bat_priv->isolation_mark_mask = nla_get_u32(attr);
 	}
 
+	if (info->attrs[BATADV_ATTR_BONDING]) {
+		attr = info->attrs[BATADV_ATTR_BONDING];
+
+		atomic_set(&bat_priv->bonding, !!nla_get_u8(attr));
+	}
+
 	batadv_netlink_notify_mesh(bat_priv);
 
 	return 0;
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 08/19] batman-adv: Add bridge_loop_avoidance mesh genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (6 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 07/19] batman-adv: Add bonding mesh " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 09/19] batman-adv: Add distributed_arp_table " Sven Eckelmann
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n

The mesh interface can try to detect loops in the same mesh caused by
(indirectly) bridged mesh/soft-interfaces of different nodes. Some of the
loops can also be resolved without breaking the mesh.

The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH commands allow to set/get the
configuration of this feature using the BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE
attribute. Setting the u8 to zero will disable this feature and setting it
to something else is enabling this feature.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Simon Wunderlich <sw@simonwunderlich.de>
---
 include/uapi/linux/batman_adv.h |  7 +++++++
 net/batman-adv/netlink.c        | 17 +++++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index d209c468..711379ef 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -380,6 +380,13 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_BONDING,
 
+	/**
+	 * @BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE: whether the bridge loop avoidance
+	 *  feature is enabled. This feature detects and avoids loops between
+	 *  the mesh and devices bridged with the soft interface
+	 */
+	BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE,
+
 	/* 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 a836a8f1..95181808 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -144,6 +144,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_ISOLATION_MARK]		= { .type = NLA_U32 },
 	[BATADV_ATTR_ISOLATION_MASK]		= { .type = NLA_U32 },
 	[BATADV_ATTR_BONDING]			= { .type = NLA_U8 },
+	[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE]	= { .type = NLA_U8 },
 };
 
 /**
@@ -283,6 +284,12 @@ static int batadv_netlink_mesh_put(struct sk_buff *msg,
 		       !!atomic_read(&bat_priv->bonding)))
 		goto nla_put_failure;
 
+#ifdef CONFIG_BATMAN_ADV_BLA
+	if (nla_put_u8(msg, BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE,
+		       !!atomic_read(&bat_priv->bridge_loop_avoidance)))
+		goto nla_put_failure;
+#endif /* CONFIG_BATMAN_ADV_BLA */
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -396,6 +403,16 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 		atomic_set(&bat_priv->bonding, !!nla_get_u8(attr));
 	}
 
+#ifdef CONFIG_BATMAN_ADV_BLA
+	if (info->attrs[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE]) {
+		attr = info->attrs[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE];
+
+		atomic_set(&bat_priv->bridge_loop_avoidance,
+			   !!nla_get_u8(attr));
+		batadv_bla_status_update(bat_priv->soft_iface);
+	}
+#endif /* CONFIG_BATMAN_ADV_BLA */
+
 	batadv_netlink_notify_mesh(bat_priv);
 
 	return 0;
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 09/19] batman-adv: Add distributed_arp_table mesh genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (7 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 08/19] batman-adv: Add bridge_loop_avoidance " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 10/19] batman-adv: Add fragmentation " Sven Eckelmann
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann, Antonio Quartulli

The mesh interface can use a distributed hash table to answer ARP requests
without flooding the request through the whole mesh.

The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH commands allow to set/get the
configuration of this feature using the BATADV_ATTR_DISTRIBUTED_ARP_TABLE
attribute. Setting the u8 to zero will disable this feature and setting it
to something else is enabling this feature.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Antonio Quartulli <a@unstable.cc>
---
 include/uapi/linux/batman_adv.h |  8 ++++++++
 net/batman-adv/netlink.c        | 17 +++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 711379ef..618c727c 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -387,6 +387,14 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE,
 
+	/**
+	 * @BATADV_ATTR_DISTRIBUTED_ARP_TABLE: whether the distributed arp table
+	 *  feature is enabled. This feature uses a distributed hash table to
+	 *  answer ARP requests without flooding the request through the whole
+	 *  mesh.
+	 */
+	BATADV_ATTR_DISTRIBUTED_ARP_TABLE,
+
 	/* 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 95181808..d93039b2 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -145,6 +145,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_ISOLATION_MASK]		= { .type = NLA_U32 },
 	[BATADV_ATTR_BONDING]			= { .type = NLA_U8 },
 	[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE]	= { .type = NLA_U8 },
+	[BATADV_ATTR_DISTRIBUTED_ARP_TABLE]	= { .type = NLA_U8 },
 };
 
 /**
@@ -290,6 +291,12 @@ static int batadv_netlink_mesh_put(struct sk_buff *msg,
 		goto nla_put_failure;
 #endif /* CONFIG_BATMAN_ADV_BLA */
 
+#ifdef CONFIG_BATMAN_ADV_DAT
+	if (nla_put_u8(msg, BATADV_ATTR_DISTRIBUTED_ARP_TABLE,
+		       !!atomic_read(&bat_priv->distributed_arp_table)))
+		goto nla_put_failure;
+#endif /* CONFIG_BATMAN_ADV_DAT */
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -413,6 +420,16 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 	}
 #endif /* CONFIG_BATMAN_ADV_BLA */
 
+#ifdef CONFIG_BATMAN_ADV_DAT
+	if (info->attrs[BATADV_ATTR_DISTRIBUTED_ARP_TABLE]) {
+		attr = info->attrs[BATADV_ATTR_DISTRIBUTED_ARP_TABLE];
+
+		atomic_set(&bat_priv->distributed_arp_table,
+			   !!nla_get_u8(attr));
+		batadv_dat_status_update(bat_priv->soft_iface);
+	}
+#endif /* CONFIG_BATMAN_ADV_DAT */
+
 	batadv_netlink_notify_mesh(bat_priv);
 
 	return 0;
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 10/19] batman-adv: Add fragmentation mesh genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (8 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 09/19] batman-adv: Add distributed_arp_table " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 11/19] batman-adv: Add gateway " Sven Eckelmann
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n
  Cc: Sven Eckelmann, Andreas Langer, Martin Hundeboll, Marek Lindner

The mesh interface can fragment unicast packets when the packet size
exceeds the outgoing slave/hard-interface MTU.

The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH commands allow to set/get the
configuration of this feature using the BATADV_ATTR_FRAGMENTATION
attribute. Setting the u8 to zero will disable this feature and setting it
to something else is enabling this feature.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Andreas Langer <an.langer@gmx.de>
Cc: Martin Hundeboll <martin@hundeboll.net>
Cc: Marek Lindner <mareklindner@neomailbox.ch>
---
 include/uapi/linux/batman_adv.h |  7 +++++++
 net/batman-adv/netlink.c        | 12 ++++++++++++
 2 files changed, 19 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 618c727c..5c58d3b6 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -395,6 +395,13 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_DISTRIBUTED_ARP_TABLE,
 
+	/**
+	 * @BATADV_ATTR_FRAGMENTATION: whether the data traffic going through
+	 *  the mesh will be fragmented or silently discarded if the packet size
+	 *  exceeds the outgoing interface MTU.
+	 */
+	BATADV_ATTR_FRAGMENTATION,
+
 	/* 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 d93039b2..d7d5f196 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -146,6 +146,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_BONDING]			= { .type = NLA_U8 },
 	[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE]	= { .type = NLA_U8 },
 	[BATADV_ATTR_DISTRIBUTED_ARP_TABLE]	= { .type = NLA_U8 },
+	[BATADV_ATTR_FRAGMENTATION]		= { .type = NLA_U8 },
 };
 
 /**
@@ -297,6 +298,10 @@ static int batadv_netlink_mesh_put(struct sk_buff *msg,
 		goto nla_put_failure;
 #endif /* CONFIG_BATMAN_ADV_DAT */
 
+	if (nla_put_u8(msg, BATADV_ATTR_FRAGMENTATION,
+		       !!atomic_read(&bat_priv->fragmentation)))
+		goto nla_put_failure;
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -430,6 +435,13 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 	}
 #endif /* CONFIG_BATMAN_ADV_DAT */
 
+	if (info->attrs[BATADV_ATTR_FRAGMENTATION]) {
+		attr = info->attrs[BATADV_ATTR_FRAGMENTATION];
+
+		atomic_set(&bat_priv->fragmentation, !!nla_get_u8(attr));
+		batadv_update_min_mtu(bat_priv->soft_iface);
+	}
+
 	batadv_netlink_notify_mesh(bat_priv);
 
 	return 0;
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 11/19] batman-adv: Add gateway mesh genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (9 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 10/19] batman-adv: Add fragmentation " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 12/19] batman-adv: Add hop_penalty " Sven Eckelmann
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann, Marek Lindner, Antonio Quartulli

The mesh/soft-interface can optimize the handling of DHCP packets. Instead
of flooding them through the whole mesh, it can be forwarded as unicast to
a specific gateway server. The originator which injects the packets in the
mesh has to select (based on sel_class thresholds) a responsible gateway
server. This is done by switching this originator to the gw_mode client.
The servers announce their forwarding bandwidth (download/upload) when the
gw_mode server was selected.

The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH commands allow to set/get the
configuration of this feature using the attributes:

* u8 BATADV_ATTR_GW_MODE (0 == off, 1 == client, 2 == server)
* u32 BATADV_ATTR_GW_BANDWIDTH_DOWN (in 100 kbit/s steps)
* u32 BATADV_ATTR_GW_BANDWIDTH_UP (in 100 kbit/s steps)
* u32 BATADV_ATTR_GW_SEL_CLASS

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Marek Lindner <mareklindner@neomailbox.ch>
Cc: Antonio Quartulli <a@unstable.cc>
---
 include/uapi/linux/batman_adv.h | 40 ++++++++++++++
 net/batman-adv/gateway_client.c |  1 -
 net/batman-adv/gateway_common.c |  1 +
 net/batman-adv/gateway_common.h |  6 ---
 net/batman-adv/netlink.c        | 92 +++++++++++++++++++++++++++++++++
 net/batman-adv/soft-interface.c |  2 +-
 net/batman-adv/sysfs.c          |  1 +
 7 files changed, 135 insertions(+), 8 deletions(-)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 5c58d3b6..0d45e807 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -139,6 +139,20 @@ enum batadv_mcast_flags_priv {
 	BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING	= (1 << 4),
 };
 
+/**
+ * enum batadv_gw_modes - gateway mode of node
+ */
+enum batadv_gw_modes {
+	/** @BATADV_GW_MODE_OFF: gw mode disabled */
+	BATADV_GW_MODE_OFF,
+
+	/** @BATADV_GW_MODE_CLIENT: send DHCP requests to gw servers */
+	BATADV_GW_MODE_CLIENT,
+
+	/** @BATADV_GW_MODE_SERVER: announce itself as gatway server */
+	BATADV_GW_MODE_SERVER,
+};
+
 /**
  * enum batadv_nl_attrs - batman-adv netlink attributes
  */
@@ -402,6 +416,32 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_FRAGMENTATION,
 
+	/**
+	 * @BATADV_ATTR_GW_BANDWIDTH_DOWN: defines the download bandwidth which
+	 *  is propagated by this node if %BATADV_ATTR_GW_BANDWIDTH_MODE was set
+	 *  to 'server'.
+	 */
+	BATADV_ATTR_GW_BANDWIDTH_DOWN,
+
+	/**
+	 * @BATADV_ATTR_GW_BANDWIDTH_UP: defines the upload bandwidth which
+	 *  is propagated by this node if %BATADV_ATTR_GW_BANDWIDTH_MODE was set
+	 *  to 'server'.
+	 */
+	BATADV_ATTR_GW_BANDWIDTH_UP,
+
+	/**
+	 * @BATADV_ATTR_GW_MODE: defines the state of the gateway features.
+	 * Possible values are specified in enum batadv_gw_modes
+	 */
+	BATADV_ATTR_GW_MODE,
+
+	/**
+	 * @BATADV_ATTR_GW_SEL_CLASS: defines the selection criteria this node
+	 *  will use to choose a gateway if gw_mode was set to 'client'.
+	 */
+	BATADV_ATTR_GW_SEL_CLASS,
+
 	/* add attributes above here, update the policy in netlink.c */
 
 	/**
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c
index 9d8e5eda..2373903c 100644
--- a/net/batman-adv/gateway_client.c
+++ b/net/batman-adv/gateway_client.c
@@ -47,7 +47,6 @@
 #include <uapi/linux/batadv_packet.h>
 #include <uapi/linux/batman_adv.h>
 
-#include "gateway_common.h"
 #include "hard-interface.h"
 #include "log.h"
 #include "netlink.h"
diff --git a/net/batman-adv/gateway_common.c b/net/batman-adv/gateway_common.c
index 936c107f..08b62271 100644
--- a/net/batman-adv/gateway_common.c
+++ b/net/batman-adv/gateway_common.c
@@ -28,6 +28,7 @@
 #include <linux/stddef.h>
 #include <linux/string.h>
 #include <uapi/linux/batadv_packet.h>
+#include <uapi/linux/batman_adv.h>
 
 #include "gateway_client.h"
 #include "log.h"
diff --git a/net/batman-adv/gateway_common.h b/net/batman-adv/gateway_common.h
index 80afb279..cd1c5f54 100644
--- a/net/batman-adv/gateway_common.h
+++ b/net/batman-adv/gateway_common.h
@@ -25,12 +25,6 @@
 
 struct net_device;
 
-enum batadv_gw_modes {
-	BATADV_GW_MODE_OFF,
-	BATADV_GW_MODE_CLIENT,
-	BATADV_GW_MODE_SERVER,
-};
-
 /**
  * enum batadv_bandwidth_units - bandwidth unit types
  */
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index d7d5f196..e79a61a6 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -51,6 +51,7 @@
 #include "bridge_loop_avoidance.h"
 #include "distributed-arp-table.h"
 #include "gateway_client.h"
+#include "gateway_common.h"
 #include "hard-interface.h"
 #include "multicast.h"
 #include "originator.h"
@@ -147,6 +148,10 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_BRIDGE_LOOP_AVOIDANCE]	= { .type = NLA_U8 },
 	[BATADV_ATTR_DISTRIBUTED_ARP_TABLE]	= { .type = NLA_U8 },
 	[BATADV_ATTR_FRAGMENTATION]		= { .type = NLA_U8 },
+	[BATADV_ATTR_GW_BANDWIDTH_DOWN]		= { .type = NLA_U32 },
+	[BATADV_ATTR_GW_BANDWIDTH_UP]		= { .type = NLA_U32 },
+	[BATADV_ATTR_GW_MODE]			= { .type = NLA_U8 },
+	[BATADV_ATTR_GW_SEL_CLASS]		= { .type = NLA_U32 },
 };
 
 /**
@@ -302,6 +307,28 @@ static int batadv_netlink_mesh_put(struct sk_buff *msg,
 		       !!atomic_read(&bat_priv->fragmentation)))
 		goto nla_put_failure;
 
+	if (nla_put_u32(msg, BATADV_ATTR_GW_BANDWIDTH_DOWN,
+			atomic_read(&bat_priv->gw.bandwidth_down)))
+		goto nla_put_failure;
+
+	if (nla_put_u32(msg, BATADV_ATTR_GW_BANDWIDTH_UP,
+			atomic_read(&bat_priv->gw.bandwidth_up)))
+		goto nla_put_failure;
+
+	if (nla_put_u8(msg, BATADV_ATTR_GW_MODE,
+		       atomic_read(&bat_priv->gw.mode)))
+		goto nla_put_failure;
+
+	if (bat_priv->algo_ops->gw.get_best_gw_node &&
+	    bat_priv->algo_ops->gw.is_eligible) {
+		/* GW selection class is not available if the routing algorithm
+		 * in use does not implement the GW API
+		 */
+		if (nla_put_u32(msg, BATADV_ATTR_GW_SEL_CLASS,
+				atomic_read(&bat_priv->gw.sel_class)))
+			goto nla_put_failure;
+	}
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -442,6 +469,71 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 		batadv_update_min_mtu(bat_priv->soft_iface);
 	}
 
+	if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN]) {
+		attr = info->attrs[BATADV_ATTR_GW_BANDWIDTH_DOWN];
+
+		atomic_set(&bat_priv->gw.bandwidth_down, nla_get_u32(attr));
+		batadv_gw_tvlv_container_update(bat_priv);
+	}
+
+	if (info->attrs[BATADV_ATTR_GW_BANDWIDTH_UP]) {
+		attr = info->attrs[BATADV_ATTR_GW_BANDWIDTH_UP];
+
+		atomic_set(&bat_priv->gw.bandwidth_up, nla_get_u32(attr));
+		batadv_gw_tvlv_container_update(bat_priv);
+	}
+
+	if (info->attrs[BATADV_ATTR_GW_MODE]) {
+		u8 gw_mode;
+
+		attr = info->attrs[BATADV_ATTR_GW_MODE];
+		gw_mode = nla_get_u8(attr);
+
+		if (gw_mode <= BATADV_GW_MODE_SERVER) {
+			/* Invoking batadv_gw_reselect() is not enough to really
+			 * de-select the current GW. It will only instruct the
+			 * gateway client code to perform a re-election the next
+			 * time that this is needed.
+			 *
+			 * When gw client mode is being switched off the current
+			 * GW must be de-selected explicitly otherwise no GW_ADD
+			 * uevent is thrown on client mode re-activation. This
+			 * is operation is performed in
+			 * batadv_gw_check_client_stop().
+			 */
+			batadv_gw_reselect(bat_priv);
+
+			/* always call batadv_gw_check_client_stop() before
+			 * changing the gateway state
+			 */
+			batadv_gw_check_client_stop(bat_priv);
+			atomic_set(&bat_priv->gw.mode, gw_mode);
+			batadv_gw_tvlv_container_update(bat_priv);
+		}
+	}
+
+	if (info->attrs[BATADV_ATTR_GW_SEL_CLASS] &&
+	    bat_priv->algo_ops->gw.get_best_gw_node &&
+	    bat_priv->algo_ops->gw.is_eligible) {
+		/* setting the GW selection class is allowed only if the routing
+		 * algorithm in use implements the GW API
+		 */
+
+		u32 sel_class_max = 0xffffffffu;
+		u32 sel_class;
+
+		attr = info->attrs[BATADV_ATTR_GW_SEL_CLASS];
+		sel_class = nla_get_u32(attr);
+
+		if (!bat_priv->algo_ops->gw.store_sel_class)
+			sel_class_max = BATADV_TQ_MAX_VALUE;
+
+		if (sel_class >= 1 && sel_class <= sel_class_max) {
+			atomic_set(&bat_priv->gw.sel_class, sel_class);
+			batadv_gw_reselect(bat_priv);
+		}
+	}
+
 	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 5db5a0a4..d158ac70 100644
--- a/net/batman-adv/soft-interface.c
+++ b/net/batman-adv/soft-interface.c
@@ -50,13 +50,13 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <uapi/linux/batadv_packet.h>
+#include <uapi/linux/batman_adv.h>
 
 #include "bat_algo.h"
 #include "bridge_loop_avoidance.h"
 #include "debugfs.h"
 #include "distributed-arp-table.h"
 #include "gateway_client.h"
-#include "gateway_common.h"
 #include "hard-interface.h"
 #include "multicast.h"
 #include "network-coding.h"
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index 09427fc6..344e5787 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -40,6 +40,7 @@
 #include <linux/stringify.h>
 #include <linux/workqueue.h>
 #include <uapi/linux/batadv_packet.h>
+#include <uapi/linux/batman_adv.h>
 
 #include "bridge_loop_avoidance.h"
 #include "distributed-arp-table.h"
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 12/19] batman-adv: Add hop_penalty mesh genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (10 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 11/19] batman-adv: Add gateway " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 13/19] batman-adv: Add log_level " Sven Eckelmann
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n
  Cc: Sven Eckelmann, Linus Lüssing, Marek Lindner,
	Antonio Quartulli, Simon Wunderlich

The TQ (B.A.T.M.A.N. IV) and throughput values (B.A.T.M.A.N. V) are reduced
when they are forwarded. One of the reductions is the penalty for
traversing an additional hop. This hop_penalty (0-255) defines the
percentage of reduction (0-100%).

The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH commands allow to set/get the
configuration of this feature using the u8 BATADV_ATTR_HOP_PENALTY
attribute.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Linus Lüssing <linus.luessing@c0d3.blue>
Cc: Marek Lindner <mareklindner@neomailbox.ch>
Cc: Antonio Quartulli <a@unstable.cc>
Cc: Simon Wunderlich <sw@simonwunderlich.de>
---
 include/uapi/linux/batman_adv.h |  6 ++++++
 net/batman-adv/netlink.c        | 11 +++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 0d45e807..7cc69802 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -442,6 +442,12 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_GW_SEL_CLASS,
 
+	/**
+	 * @BATADV_ATTR_HOP_PENALTY: defines the penalty which will be applied
+	 *  to an originator message's tq-field on every hop.
+	 */
+	BATADV_ATTR_HOP_PENALTY,
+
 	/* 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 e79a61a6..bbea6ac0 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -152,6 +152,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_GW_BANDWIDTH_UP]		= { .type = NLA_U32 },
 	[BATADV_ATTR_GW_MODE]			= { .type = NLA_U8 },
 	[BATADV_ATTR_GW_SEL_CLASS]		= { .type = NLA_U32 },
+	[BATADV_ATTR_HOP_PENALTY]		= { .type = NLA_U8 },
 };
 
 /**
@@ -329,6 +330,10 @@ static int batadv_netlink_mesh_put(struct sk_buff *msg,
 			goto nla_put_failure;
 	}
 
+	if (nla_put_u8(msg, BATADV_ATTR_HOP_PENALTY,
+		       atomic_read(&bat_priv->hop_penalty)))
+		goto nla_put_failure;
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -534,6 +539,12 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 		}
 	}
 
+	if (info->attrs[BATADV_ATTR_HOP_PENALTY]) {
+		attr = info->attrs[BATADV_ATTR_HOP_PENALTY];
+
+		atomic_set(&bat_priv->hop_penalty, nla_get_u8(attr));
+	}
+
 	batadv_netlink_notify_mesh(bat_priv);
 
 	return 0;
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 13/19] batman-adv: Add log_level mesh genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (11 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 12/19] batman-adv: Add hop_penalty " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 14/19] batman-adv: Add multicast_mode " Sven Eckelmann
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann, Marek Lindner

In contrast to other modules, batman-adv allows to set the debug message
verbosity per mesh/soft-interface and not per module (via modparam).

The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH commands allow to set/get the
configuration of this feature using the u32 (bitmask) BATADV_ATTR_LOG_LEVEL
attribute.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Marek Lindner <mareklindner@neomailbox.ch>
---
 include/uapi/linux/batman_adv.h |  6 ++++++
 net/batman-adv/netlink.c        | 17 +++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 7cc69802..efc06449 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -448,6 +448,12 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_HOP_PENALTY,
 
+	/**
+	 * @BATADV_ATTR_LOG_LEVEL: bitmask with to define which debug messages
+	 *  should be send to the debug log/trace ring buffer
+	 */
+	BATADV_ATTR_LOG_LEVEL,
+
 	/* 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 bbea6ac0..8e3a1b6e 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -53,6 +53,7 @@
 #include "gateway_client.h"
 #include "gateway_common.h"
 #include "hard-interface.h"
+#include "log.h"
 #include "multicast.h"
 #include "originator.h"
 #include "soft-interface.h"
@@ -153,6 +154,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_GW_MODE]			= { .type = NLA_U8 },
 	[BATADV_ATTR_GW_SEL_CLASS]		= { .type = NLA_U32 },
 	[BATADV_ATTR_HOP_PENALTY]		= { .type = NLA_U8 },
+	[BATADV_ATTR_LOG_LEVEL]			= { .type = NLA_U32 },
 };
 
 /**
@@ -334,6 +336,12 @@ static int batadv_netlink_mesh_put(struct sk_buff *msg,
 		       atomic_read(&bat_priv->hop_penalty)))
 		goto nla_put_failure;
 
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+	if (nla_put_u32(msg, BATADV_ATTR_LOG_LEVEL,
+			atomic_read(&bat_priv->log_level)))
+		goto nla_put_failure;
+#endif /* CONFIG_BATMAN_ADV_DEBUG */
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -545,6 +553,15 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 		atomic_set(&bat_priv->hop_penalty, nla_get_u8(attr));
 	}
 
+#ifdef CONFIG_BATMAN_ADV_DEBUG
+	if (info->attrs[BATADV_ATTR_LOG_LEVEL]) {
+		attr = info->attrs[BATADV_ATTR_LOG_LEVEL];
+
+		atomic_set(&bat_priv->log_level,
+			   nla_get_u32(attr) & BATADV_DBG_ALL);
+	}
+#endif /* CONFIG_BATMAN_ADV_DEBUG */
+
 	batadv_netlink_notify_mesh(bat_priv);
 
 	return 0;
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 14/19] batman-adv: Add multicast_mode mesh genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (12 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 13/19] batman-adv: Add log_level " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2019-01-04  1:57   ` Linus Lüssing
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 15/19] batman-adv: Add network_coding " Sven Eckelmann
                   ` (4 subsequent siblings)
  18 siblings, 1 reply; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n

The mesh interface can optimize the flooding of multicast packets based on
the content of the global translation tables.

The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH commands allow to set/get the
configuration of this feature using the BATADV_ATTR_MULTICAST_MODE
attribute. Setting the u8 to zero will disable this feature and setting it
to something else is enabling this feature.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Linus Lüssing <linus.luessing@c0d3.blue>
---
 include/uapi/linux/batman_adv.h |  8 ++++++++
 net/batman-adv/netlink.c        | 15 +++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index efc06449..514acc06 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -454,6 +454,14 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_LOG_LEVEL,
 
+	/**
+	 * @BATADV_ATTR_MULTICAST_MODE: whether multicast optimizations are
+	 *  enabled or disabled. If set to zero then all nodes in the mesh are
+	 *  going to use classic flooding for any multicast packet with no
+	 *  optimizations.
+	 */
+	BATADV_ATTR_MULTICAST_MODE,
+
 	/* 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 8e3a1b6e..32762003 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -155,6 +155,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_GW_SEL_CLASS]		= { .type = NLA_U32 },
 	[BATADV_ATTR_HOP_PENALTY]		= { .type = NLA_U8 },
 	[BATADV_ATTR_LOG_LEVEL]			= { .type = NLA_U32 },
+	[BATADV_ATTR_MULTICAST_MODE]		= { .type = NLA_U8 },
 };
 
 /**
@@ -342,6 +343,12 @@ static int batadv_netlink_mesh_put(struct sk_buff *msg,
 		goto nla_put_failure;
 #endif /* CONFIG_BATMAN_ADV_DEBUG */
 
+#ifdef CONFIG_BATMAN_ADV_MCAST
+	if (nla_put_u8(msg, BATADV_ATTR_MULTICAST_MODE,
+		       !!atomic_read(&bat_priv->multicast_mode)))
+		goto nla_put_failure;
+#endif /* CONFIG_BATMAN_ADV_MCAST */
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -562,6 +569,14 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 	}
 #endif /* CONFIG_BATMAN_ADV_DEBUG */
 
+#ifdef CONFIG_BATMAN_ADV_MCAST
+	if (info->attrs[BATADV_ATTR_MULTICAST_MODE]) {
+		attr = info->attrs[BATADV_ATTR_MULTICAST_MODE];
+
+		atomic_set(&bat_priv->multicast_mode, !!nla_get_u8(attr));
+	}
+#endif /* CONFIG_BATMAN_ADV_MCAST */
+
 	batadv_netlink_notify_mesh(bat_priv);
 
 	return 0;
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 15/19] batman-adv: Add network_coding mesh genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (13 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 14/19] batman-adv: Add multicast_mode " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 16/19] batman-adv: Add orig_interval " Sven Eckelmann
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann, Martin Hundeboll, Marek Lindner

The mesh interface can use (in an homogeneous mesh) network coding, a
mechanism that aims to increase the overall network throughput by fusing
multiple packets in one transmission.

The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH commands allow to set/get the
configuration of this feature using the BATADV_ATTR_NETWORK_CODING
attribute. Setting the u8 to zero will disable this feature and setting it
to something else is enabling this feature.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Martin Hundeboll <martin@hundeboll.net>
Cc: Marek Lindner <mareklindner@neomailbox.ch>
---
 include/uapi/linux/batman_adv.h |  7 +++++++
 net/batman-adv/netlink.c        | 17 +++++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 514acc06..7e8a086f 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -462,6 +462,13 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_MULTICAST_MODE,
 
+	/**
+	 * @BATADV_ATTR_NETWORK_CODING: whether Network Coding (using some magic
+	 *  to send fewer wifi packets but still the same content) is enabled or
+	 *  not.
+	 */
+	BATADV_ATTR_NETWORK_CODING,
+
 	/* 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 32762003..bdfea982 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -55,6 +55,7 @@
 #include "hard-interface.h"
 #include "log.h"
 #include "multicast.h"
+#include "network-coding.h"
 #include "originator.h"
 #include "soft-interface.h"
 #include "tp_meter.h"
@@ -156,6 +157,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_HOP_PENALTY]		= { .type = NLA_U8 },
 	[BATADV_ATTR_LOG_LEVEL]			= { .type = NLA_U32 },
 	[BATADV_ATTR_MULTICAST_MODE]		= { .type = NLA_U8 },
+	[BATADV_ATTR_NETWORK_CODING]		= { .type = NLA_U8 },
 };
 
 /**
@@ -349,6 +351,12 @@ static int batadv_netlink_mesh_put(struct sk_buff *msg,
 		goto nla_put_failure;
 #endif /* CONFIG_BATMAN_ADV_MCAST */
 
+#ifdef CONFIG_BATMAN_ADV_NC
+	if (nla_put_u8(msg, BATADV_ATTR_NETWORK_CODING,
+		       !!atomic_read(&bat_priv->network_coding)))
+		goto nla_put_failure;
+#endif /* CONFIG_BATMAN_ADV_NC */
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -577,6 +585,15 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 	}
 #endif /* CONFIG_BATMAN_ADV_MCAST */
 
+#ifdef CONFIG_BATMAN_ADV_NC
+	if (info->attrs[BATADV_ATTR_NETWORK_CODING]) {
+		attr = info->attrs[BATADV_ATTR_NETWORK_CODING];
+
+		atomic_set(&bat_priv->network_coding, !!nla_get_u8(attr));
+		batadv_nc_status_update(bat_priv->soft_iface);
+	}
+#endif /* CONFIG_BATMAN_ADV_NC */
+
 	batadv_netlink_notify_mesh(bat_priv);
 
 	return 0;
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 16/19] batman-adv: Add orig_interval mesh genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (14 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 15/19] batman-adv: Add network_coding " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 17/19] batman-adv: Add elp_interval hardif " Sven Eckelmann
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann, Marek Lindner

The OGM packets are transmitted every orig_interval milliseconds. This
value can be changed using the configuration interface.

The BATADV_CMD_SET_MESH/BATADV_CMD_GET_MESH commands allow to set/get the
configuration of this feature using the u32 BATADV_ATTR_ORIG_INTERVAL
attribute.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Marek Lindner <mareklindner@neomailbox.ch>
---
 include/uapi/linux/batman_adv.h |  6 ++++++
 net/batman-adv/netlink.c        | 17 +++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 7e8a086f..b8cb26d2 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -469,6 +469,12 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_NETWORK_CODING,
 
+	/**
+	 * @BATADV_ATTR_ORIG_INTERVAL: defines the interval in milliseconds in
+	 *  which batman sends its protocol messages.
+	 */
+	BATADV_ATTR_ORIG_INTERVAL,
+
 	/* 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 bdfea982..831678fd 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -158,6 +158,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_LOG_LEVEL]			= { .type = NLA_U32 },
 	[BATADV_ATTR_MULTICAST_MODE]		= { .type = NLA_U8 },
 	[BATADV_ATTR_NETWORK_CODING]		= { .type = NLA_U8 },
+	[BATADV_ATTR_ORIG_INTERVAL]		= { .type = NLA_U32 },
 };
 
 /**
@@ -357,6 +358,10 @@ static int batadv_netlink_mesh_put(struct sk_buff *msg,
 		goto nla_put_failure;
 #endif /* CONFIG_BATMAN_ADV_NC */
 
+	if (nla_put_u32(msg, BATADV_ATTR_ORIG_INTERVAL,
+			atomic_read(&bat_priv->orig_interval)))
+		goto nla_put_failure;
+
 	batadv_hardif_put(primary_if);
 
 	genlmsg_end(msg, hdr);
@@ -594,6 +599,18 @@ static int batadv_netlink_set_mesh(struct sk_buff *skb, struct genl_info *info)
 	}
 #endif /* CONFIG_BATMAN_ADV_NC */
 
+	if (info->attrs[BATADV_ATTR_ORIG_INTERVAL]) {
+		u32 orig_interval;
+
+		attr = info->attrs[BATADV_ATTR_ORIG_INTERVAL];
+		orig_interval = nla_get_u32(attr);
+
+		orig_interval = min_t(u32, orig_interval, INT_MAX);
+		orig_interval = max_t(u32, orig_interval, 2 * BATADV_JITTER);
+
+		atomic_set(&bat_priv->orig_interval, orig_interval);
+	}
+
 	batadv_netlink_notify_mesh(bat_priv);
 
 	return 0;
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 17/19] batman-adv: Add elp_interval hardif genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (15 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 16/19] batman-adv: Add orig_interval " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 18/19] batman-adv: Add throughput_override " Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 19/19] batman-adv: Trigger genl notification on sysfs config change Sven Eckelmann
  18 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n

The ELP packets are transmitted every elp_interval milliseconds on an
slave/hard-interface. This value can be changed using the configuration
interface.

The BATADV_CMD_SET_HARDIF/BATADV_CMD_GET_HARDIF commands allow to set/get
the configuration of this feature using the u32 BATADV_ATTR_ELP_INTERVAL
attribute.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Linus Lüssing <linus.luessing@c0d3.blue>
---
 include/uapi/linux/batman_adv.h |  6 ++++++
 net/batman-adv/netlink.c        | 17 +++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index b8cb26d2..716471df 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -475,6 +475,12 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_ORIG_INTERVAL,
 
+	/**
+	 * @BATADV_ATTR_ELP_INTERVAL: defines the interval in milliseconds in
+	 *  which batman emits probing packets for neighbor sensing (ELP).
+	 */
+	BATADV_ATTR_ELP_INTERVAL,
+
 	/* 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 831678fd..5144c350 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -159,6 +159,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_MULTICAST_MODE]		= { .type = NLA_U8 },
 	[BATADV_ATTR_NETWORK_CODING]		= { .type = NLA_U8 },
 	[BATADV_ATTR_ORIG_INTERVAL]		= { .type = NLA_U32 },
+	[BATADV_ATTR_ELP_INTERVAL]		= { .type = NLA_U32 },
 };
 
 /**
@@ -823,6 +824,12 @@ static int batadv_netlink_hardif_put(struct sk_buff *msg,
 			goto nla_put_failure;
 	}
 
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+	if (nla_put_u32(msg, BATADV_ATTR_ELP_INTERVAL,
+			atomic_read(&hard_iface->bat_v.elp_interval)))
+		goto nla_put_failure;
+#endif /* CONFIG_BATMAN_ADV_BATMAN_V */
+
 	genlmsg_end(msg, hdr);
 	return 0;
 
@@ -908,6 +915,16 @@ static int batadv_netlink_set_hardif(struct sk_buff *skb,
 	struct batadv_hard_iface *hard_iface = info->user_ptr[1];
 	struct batadv_priv *bat_priv = info->user_ptr[0];
 
+#ifdef CONFIG_BATMAN_ADV_BATMAN_V
+	struct nlattr *attr;
+
+	if (info->attrs[BATADV_ATTR_ELP_INTERVAL]) {
+		attr = info->attrs[BATADV_ATTR_ELP_INTERVAL];
+
+		atomic_set(&hard_iface->bat_v.elp_interval, nla_get_u32(attr));
+	}
+#endif /* CONFIG_BATMAN_ADV_BATMAN_V */
+
 	batadv_netlink_notify_hardif(bat_priv, hard_iface);
 
 	return 0;
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 18/19] batman-adv: Add throughput_override hardif genl configuration
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (16 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 17/19] batman-adv: Add elp_interval hardif " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 19/19] batman-adv: Trigger genl notification on sysfs config change Sven Eckelmann
  18 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Sven Eckelmann, Antonio Quartulli

The B.A.T.M.A.N. V implementation tries to estimate the link throughput of
an interface to an originator using different automatic methods. It is
still possible to overwrite it the link throughput for all reachable
originators via this interface.

The BATADV_CMD_SET_HARDIF/BATADV_CMD_GET_HARDIF commands allow to set/get
the configuration of this feature using the u32
BATADV_ATTR_THROUGHPUT_OVERRIDE attribute. The used unit is in 100 Kbit/s.
If the value is set to 0 then batman-adv will try to estimate the
throughput by itself.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
Cc: Antonio Quartulli <a@unstable.cc>
---
 include/uapi/linux/batman_adv.h |  8 ++++++++
 net/batman-adv/netlink.c        | 12 ++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
index 716471df..b5a245ef 100644
--- a/include/uapi/linux/batman_adv.h
+++ b/include/uapi/linux/batman_adv.h
@@ -481,6 +481,14 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_ELP_INTERVAL,
 
+	/**
+	 * @BATADV_ATTR_THROUGHPUT_OVERRIDE: defines the throughput value to be
+	 *  used by B.A.T.M.A.N. V when estimating the link throughput using
+	 *  this interface. If the value is set to 0 then batman-adv will try to
+	 *  estimate the throughput by itself.
+	 */
+	BATADV_ATTR_THROUGHPUT_OVERRIDE,
+
 	/* 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 5144c350..4065d871 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -160,6 +160,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
 	[BATADV_ATTR_NETWORK_CODING]		= { .type = NLA_U8 },
 	[BATADV_ATTR_ORIG_INTERVAL]		= { .type = NLA_U32 },
 	[BATADV_ATTR_ELP_INTERVAL]		= { .type = NLA_U32 },
+	[BATADV_ATTR_THROUGHPUT_OVERRIDE]	= { .type = NLA_U32 },
 };
 
 /**
@@ -828,6 +829,10 @@ static int batadv_netlink_hardif_put(struct sk_buff *msg,
 	if (nla_put_u32(msg, BATADV_ATTR_ELP_INTERVAL,
 			atomic_read(&hard_iface->bat_v.elp_interval)))
 		goto nla_put_failure;
+
+	if (nla_put_u32(msg, BATADV_ATTR_THROUGHPUT_OVERRIDE,
+			atomic_read(&hard_iface->bat_v.throughput_override)))
+		goto nla_put_failure;
 #endif /* CONFIG_BATMAN_ADV_BATMAN_V */
 
 	genlmsg_end(msg, hdr);
@@ -923,6 +928,13 @@ static int batadv_netlink_set_hardif(struct sk_buff *skb,
 
 		atomic_set(&hard_iface->bat_v.elp_interval, nla_get_u32(attr));
 	}
+
+	if (info->attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE]) {
+		attr = info->attrs[BATADV_ATTR_THROUGHPUT_OVERRIDE];
+
+		atomic_set(&hard_iface->bat_v.throughput_override,
+			   nla_get_u32(attr));
+	}
 #endif /* CONFIG_BATMAN_ADV_BATMAN_V */
 
 	batadv_netlink_notify_hardif(bat_priv, hard_iface);
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* [B.A.T.M.A.N.] [RFC v3 19/19] batman-adv: Trigger genl notification on sysfs config change
  2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
                   ` (17 preceding siblings ...)
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 18/19] batman-adv: Add throughput_override " Sven Eckelmann
@ 2018-12-07 13:58 ` Sven Eckelmann
  2019-01-04  2:29   ` Linus Lüssing
  18 siblings, 1 reply; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-07 13:58 UTC (permalink / raw)
  To: b.a.t.m.a.n

The generic netlink code is expected to trigger notification messages when
configuration might have been changed. But the configuration of batman-adv
is most of the time still done using sysfs. So the sysfs interface should
also trigger the corresponding netlink messages via the "config" multicast
group.

Signed-off-by: Sven Eckelmann <sven@narfation.org>
---
 net/batman-adv/netlink.c | 10 +++----
 net/batman-adv/netlink.h |  6 ++++
 net/batman-adv/sysfs.c   | 63 +++++++++++++++++++++++++++++++++-------
 3 files changed, 63 insertions(+), 16 deletions(-)

diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 4065d871..37552736 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -383,7 +383,7 @@ static int batadv_netlink_mesh_put(struct sk_buff *msg,
  *
  * Return: 0 on success, < 0 on error
  */
-static int batadv_netlink_notify_mesh(struct batadv_priv *bat_priv)
+int batadv_netlink_notify_mesh(struct batadv_priv *bat_priv)
 {
 	struct sk_buff *msg;
 	int ret;
@@ -850,8 +850,8 @@ static int batadv_netlink_hardif_put(struct sk_buff *msg,
  *
  * Return: 0 on success, < 0 on error
  */
-static int batadv_netlink_notify_hardif(struct batadv_priv *bat_priv,
-					struct batadv_hard_iface *hard_iface)
+int batadv_netlink_notify_hardif(struct batadv_priv *bat_priv,
+				 struct batadv_hard_iface *hard_iface)
 {
 	struct sk_buff *msg;
 	int ret;
@@ -1055,8 +1055,8 @@ static int batadv_netlink_vlan_put(struct sk_buff *msg,
  *
  * Return: 0 on success, < 0 on error
  */
-static int batadv_netlink_notify_vlan(struct batadv_priv *bat_priv,
-				      struct batadv_softif_vlan *vlan)
+int batadv_netlink_notify_vlan(struct batadv_priv *bat_priv,
+			       struct batadv_softif_vlan *vlan)
 {
 	struct sk_buff *msg;
 	int ret;
diff --git a/net/batman-adv/netlink.h b/net/batman-adv/netlink.h
index 571d9a5a..8d17ce0e 100644
--- a/net/batman-adv/netlink.h
+++ b/net/batman-adv/netlink.h
@@ -34,6 +34,12 @@ int batadv_netlink_tpmeter_notify(struct batadv_priv *bat_priv, const u8 *dst,
 				  u8 result, u32 test_time, u64 total_bytes,
 				  u32 cookie);
 
+int batadv_netlink_notify_mesh(struct batadv_priv *bat_priv);
+int batadv_netlink_notify_hardif(struct batadv_priv *bat_priv,
+				 struct batadv_hard_iface *hard_iface);
+int batadv_netlink_notify_vlan(struct batadv_priv *bat_priv,
+			       struct batadv_softif_vlan *vlan);
+
 extern struct genl_family batadv_netlink_family;
 
 #endif /* _NET_BATMAN_ADV_NETLINK_H_ */
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c
index 344e5787..7c67fe29 100644
--- a/net/batman-adv/sysfs.c
+++ b/net/batman-adv/sysfs.c
@@ -48,6 +48,7 @@
 #include "gateway_common.h"
 #include "hard-interface.h"
 #include "log.h"
+#include "netlink.h"
 #include "network-coding.h"
 #include "soft-interface.h"
 
@@ -154,9 +155,14 @@ ssize_t batadv_store_##_name(struct kobject *kobj,			\
 {									\
 	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);	\
 	struct batadv_priv *bat_priv = netdev_priv(net_dev);		\
+	ssize_t length;							\
+									\
+	length = __batadv_store_bool_attr(buff, count, _post_func, attr,\
+					  &bat_priv->_name, net_dev);	\
 									\
-	return __batadv_store_bool_attr(buff, count, _post_func, attr,	\
-					&bat_priv->_name, net_dev);	\
+	batadv_netlink_notify_mesh(bat_priv);				\
+									\
+	return length;							\
 }
 
 #define BATADV_ATTR_SIF_SHOW_BOOL(_name)				\
@@ -186,11 +192,16 @@ ssize_t batadv_store_##_name(struct kobject *kobj,			\
 {									\
 	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);	\
 	struct batadv_priv *bat_priv = netdev_priv(net_dev);		\
+	ssize_t length;							\
 									\
-	return __batadv_store_uint_attr(buff, count, _min, _max,	\
-					_post_func, attr,		\
-					&bat_priv->_var, net_dev,	\
-					NULL);	\
+	length = __batadv_store_uint_attr(buff, count, _min, _max,	\
+					  _post_func, attr,		\
+					  &bat_priv->_var, net_dev,	\
+					  NULL);			\
+									\
+	batadv_netlink_notify_mesh(bat_priv);				\
+									\
+	return length;							\
 }
 
 #define BATADV_ATTR_SIF_SHOW_UINT(_name, _var)				\
@@ -223,6 +234,11 @@ ssize_t batadv_store_vlan_##_name(struct kobject *kobj,			\
 					      attr, &vlan->_name,	\
 					      bat_priv->soft_iface);	\
 									\
+	if (vlan->vid)							\
+		batadv_netlink_notify_vlan(bat_priv, vlan);		\
+	else								\
+		batadv_netlink_notify_mesh(bat_priv);			\
+									\
 	batadv_softif_vlan_put(vlan);					\
 	return res;							\
 }
@@ -256,6 +272,7 @@ ssize_t batadv_store_##_name(struct kobject *kobj,			\
 {									\
 	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);	\
 	struct batadv_hard_iface *hard_iface;				\
+	struct batadv_priv *bat_priv;					\
 	ssize_t length;							\
 									\
 	hard_iface = batadv_hardif_get_by_netdev(net_dev);		\
@@ -268,6 +285,11 @@ ssize_t batadv_store_##_name(struct kobject *kobj,			\
 					  hard_iface->soft_iface,	\
 					  net_dev);			\
 									\
+	if (hard_iface->soft_iface) {					\
+		bat_priv = netdev_priv(hard_iface->soft_iface);		\
+		batadv_netlink_notify_hardif(bat_priv, hard_iface);	\
+	}								\
+									\
 	batadv_hardif_put(hard_iface);				\
 	return length;							\
 }
@@ -537,6 +559,9 @@ static ssize_t batadv_store_gw_mode(struct kobject *kobj,
 	batadv_gw_check_client_stop(bat_priv);
 	atomic_set(&bat_priv->gw.mode, (unsigned int)gw_mode_tmp);
 	batadv_gw_tvlv_container_update(bat_priv);
+
+	batadv_netlink_notify_mesh(bat_priv);
+
 	return count;
 }
 
@@ -563,6 +588,7 @@ static ssize_t batadv_store_gw_sel_class(struct kobject *kobj,
 					 size_t count)
 {
 	struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
+	ssize_t length;
 
 	/* setting the GW selection class is allowed only if the routing
 	 * algorithm in use implements the GW API
@@ -578,10 +604,14 @@ static ssize_t batadv_store_gw_sel_class(struct kobject *kobj,
 		return bat_priv->algo_ops->gw.store_sel_class(bat_priv, buff,
 							      count);
 
-	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, NULL);
+	length = __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, NULL);
+
+	batadv_netlink_notify_mesh(bat_priv);
+
+	return length;
 }
 
 static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,
@@ -601,12 +631,18 @@ static ssize_t batadv_store_gw_bwidth(struct kobject *kobj,
 				      struct attribute *attr, char *buff,
 				      size_t count)
 {
+	struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
 	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
+	ssize_t length;
 
 	if (buff[count - 1] == '\n')
 		buff[count - 1] = '\0';
 
-	return batadv_gw_bandwidth_set(net_dev, buff, count);
+	length = batadv_gw_bandwidth_set(net_dev, buff, count);
+
+	batadv_netlink_notify_mesh(bat_priv);
+
+	return length;
 }
 
 /**
@@ -674,6 +710,8 @@ static ssize_t batadv_store_isolation_mark(struct kobject *kobj,
 		    "New skb mark for extended isolation: %#.8x/%#.8x\n",
 		    bat_priv->isolation_mark, bat_priv->isolation_mark_mask);
 
+	batadv_netlink_notify_mesh(bat_priv);
+
 	return count;
 }
 
@@ -1078,6 +1116,7 @@ static ssize_t batadv_store_throughput_override(struct kobject *kobj,
 						struct attribute *attr,
 						char *buff, size_t count)
 {
+	struct batadv_priv *bat_priv = batadv_kobj_to_batpriv(kobj);
 	struct net_device *net_dev = batadv_kobj_to_netdev(kobj);
 	struct batadv_hard_iface *hard_iface;
 	u32 tp_override;
@@ -1108,6 +1147,8 @@ static ssize_t batadv_store_throughput_override(struct kobject *kobj,
 
 	atomic_set(&hard_iface->bat_v.throughput_override, tp_override);
 
+	batadv_netlink_notify_hardif(bat_priv, hard_iface);
+
 out:
 	batadv_hardif_put(hard_iface);
 	return count;
-- 
2.19.2


^ permalink raw reply related	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 01/19] batman-adv: Move common genl doit code pre/post hooks
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 01/19] batman-adv: Move common genl doit code pre/post hooks Sven Eckelmann
@ 2018-12-30 16:57   ` Linus Lüssing
  2018-12-31 19:08     ` Sven Eckelmann
  0 siblings, 1 reply; 43+ messages in thread
From: Linus Lüssing @ 2018-12-30 16:57 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Fri, Dec 07, 2018 at 02:58:28PM +0100, Sven Eckelmann wrote:
> +/**
> + * batadv_get_softif_from_info() - Retrieve soft interface from genl attributes
> + * @net: the applicable net namespace
> + * @info: receiver information
> + *
> + * Return: Pointer to soft interface on success, error pointer on error
> + */
> +static struct batadv_priv *
> +batadv_get_softif_from_info(struct net *net, struct genl_info *info)

Since this returns a batadv_priv, shouldn't it better be called
batadv_get_batpriv_from_info() or batadv_get_bat_priv_from_info() maybe?

> +{
> +	struct net_device *soft_iface;
> +	int ifindex;
> +
> +	if (!info->attrs[BATADV_ATTR_MESH_IFINDEX])
> +		return ERR_PTR(-EINVAL);
> +
> +	ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]);
> +
> +	soft_iface = dev_get_by_index(net, ifindex);
> +	if (!soft_iface)
> +		return ERR_PTR(-ENODEV);
> +
> +	if (!batadv_softif_is_valid(soft_iface))
> +		goto err_put_softif;
> +
> +	return netdev_priv(soft_iface);
> +
> +err_put_softif:
> +	dev_put(soft_iface);
> +
> +	return ERR_PTR(-EINVAL);
> +}

Is holding a reference to bat_priv->soft_iface really
necessary (and releasing it in batadv_post_doit() )?
If we are able to retrieve a valid bat_priv then this bat_priv
itself should hold a reference to to soft_iface, shouldn't it?

> +
> +/**
> + * batadv_pre_doit() - Prepare batman-adv genl doit request
> + * @ops: requested netlink operation
> + * @skb: Netlink message with request data
> + * @info: receiver information
> + *
> + * Return: 0 on success or negative error number in case of failure
> + */
> +static int batadv_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
> +			   struct genl_info *info)
> +{
> +	struct batadv_priv *bat_priv;
> +
> +	if (ops->internal_flags & BATADV_FLAG_NEED_MESH) {
> +		bat_priv = batadv_get_softif_from_info(genl_info_net(info),
> +						       info);

Would it look nicer to store genl_info_net(info) in a temporary variable
so that its shorter and the newline for the second parameter could
be avoided?

> +		if (IS_ERR(bat_priv))
> +			return PTR_ERR(bat_priv);
> +
> +		info->user_ptr[0] = bat_priv;

Would it make sense to wrap this private data access into
something somehow? Conceptually similar to what we do not with skb private
data already for instance. There we use BATADV_SKB_CB() for instance.

> +	}
> +
> +	return 0;
> +}

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 02/19] batman-adv: Prepare framework for mesh genl config
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 02/19] batman-adv: Prepare framework for mesh genl config Sven Eckelmann
@ 2018-12-31 11:09   ` Linus Lüssing
  2018-12-31 19:11     ` Sven Eckelmann
  2019-01-07 18:49   ` Linus Lüssing
  1 sibling, 1 reply; 43+ messages in thread
From: Linus Lüssing @ 2018-12-31 11:09 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Fri, Dec 07, 2018 at 02:58:29PM +0100, Sven Eckelmann wrote:
> The batman-adv configuration interface was implemented solely using sysfs.
> This approach was condemned by non-batadv developers as "huge mistake".
> Instead a netlink/genl based implementation was suggested.
> 
> The main objects for this configuration is the mesh/soft-interface object.
> Its actual object in memory already contains most of the available
> configuration settings. The genl interface reflects this by allowing to
> get/set it using the mesh specific commands.
> 
> The BATADV_CMD_GET_MESH_INFO (or short version BATADV_CMD_GET_MESH) is
> reused as get command because it already provides the content of other
> information from the mesh/soft-interface which are not yet configuration
> specific.
> 
> The set command BATADV_CMD_SET_MESH will also notify interested userspace
> listeners of the "config" mcast group using the BATADV_CMD_SET_MESH command
> message type that settings might have been changed and what the current
> values are.
> 
> Signed-off-by: Sven Eckelmann <sven@narfation.org>
> ---
>  include/uapi/linux/batman_adv.h |  16 +++-
>  net/batman-adv/netlink.c        | 159 +++++++++++++++++++-------------
>  2 files changed, 110 insertions(+), 65 deletions(-)
> 
> diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
> index 324a0e11..2d6a175e 100644
> --- a/include/uapi/linux/batman_adv.h
> +++ b/include/uapi/linux/batman_adv.h
> @@ -27,6 +27,7 @@
>  
>  #define BATADV_NL_NAME "batadv"
>  
> +#define BATADV_NL_MCAST_GROUP_CONFIG	"config"
>  #define BATADV_NL_MCAST_GROUP_TPMETER	"tpmeter"
>  
>  /**
> @@ -372,10 +373,14 @@ enum batadv_nl_commands {
>  	BATADV_CMD_UNSPEC,
>  
>  	/**
> -	 * @BATADV_CMD_GET_MESH_INFO: Query basic information about batman-adv
> -	 * device
> +	 * @BATADV_CMD_GET_MESH: Get attributes from softif/mesh
>  	 */
> -	BATADV_CMD_GET_MESH_INFO,
> +	BATADV_CMD_GET_MESH,
> +
> +	/**
> +	 * @BATADV_CMD_GET_MESH_INFO: Alias for @BATADV_CMD_GET_MESH
> +	 */
> +	BATADV_CMD_GET_MESH_INFO = BATADV_CMD_GET_MESH,
>  
>  	/**
>  	 * @BATADV_CMD_TP_METER: Start a tp meter session
> @@ -443,6 +448,11 @@ enum batadv_nl_commands {
>  	 */
>  	BATADV_CMD_GET_MCAST_FLAGS,
>  
> +	/**
> +	 * @BATADV_CMD_SET_MESH: Set attributes for softif/mesh
> +	 */
> +	BATADV_CMD_SET_MESH,
> +
>  	/* add new commands above here */
>  
>  	/**
> diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
> index b20801a3..d89761f8 100644
> --- a/net/batman-adv/netlink.c
> +++ b/net/batman-adv/netlink.c
> @@ -62,6 +62,7 @@ struct genl_family batadv_netlink_family;
>  
>  /* multicast groups */
>  enum batadv_netlink_multicast_groups {
> +	BATADV_NL_MCGRP_CONFIG,
>  	BATADV_NL_MCGRP_TPMETER,
>  };
>  
> @@ -78,6 +79,7 @@ enum batadv_genl_ops_flags {
>  };
>  
>  static const struct genl_multicast_group batadv_netlink_mcgrps[] = {
> +	[BATADV_NL_MCGRP_CONFIG] = { .name = BATADV_NL_MCAST_GROUP_CONFIG },
>  	[BATADV_NL_MCGRP_TPMETER] = { .name = BATADV_NL_MCAST_GROUP_TPMETER },
>  };
>  
> @@ -138,20 +140,29 @@ batadv_netlink_get_ifindex(const struct nlmsghdr *nlh, int attrtype)
>  }
>  
>  /**
> - * batadv_netlink_mesh_info_put() - fill in generic information about mesh
> - *  interface
> - * @msg: netlink message to be sent back
> - * @soft_iface: interface for which the data should be taken
> + * batadv_netlink_mesh_put() - Fill message with mesh attributes
> + * @msg: Netlink message to dump into
> + * @bat_priv: the bat priv with all the soft interface information
> + * @cmd: type of message to generate
> + * @portid: Port making netlink request
> + * @seq: sequence number for message
> + * @flags: Additional flags for message
>   *
> - * Return: 0 on success, < 0 on error
> + * Return: 0 on success or negative error number in case of failure
>   */
> -static int
> -batadv_netlink_mesh_info_put(struct sk_buff *msg, struct net_device *soft_iface)
> +static int batadv_netlink_mesh_put(struct sk_buff *msg,
> +				   struct batadv_priv *bat_priv,
> +				   enum batadv_nl_commands cmd,
> +				   u32 portid, u32 seq, int flags)
>  {

[...]

>  #ifdef CONFIG_BATMAN_ADV_BLA
>  	if (nla_put_u16(msg, BATADV_ATTR_BLA_CRC,
>  			ntohs(bat_priv->bla.claim_dest.group)))
> -		goto out;
> +		goto nla_put_failure;
>  #endif
>  
>  	if (batadv_mcast_mesh_info_put(msg, bat_priv))
> -		goto out;
> +		goto nla_put_failure;

With the rename of "batadv_netlink_mesh_info_put" to
"batadv_netlink_mesh_put", I'm wondering whether
batadv_mcast_mesh_info_put() should be renamed, too.
batadv_mcast_mesh_put() would probably be a bit too generic.
But maybe something like batadv_mcast_nl_mesh_put()?


> +/**
> + * batadv_netlink_get_mesh() - Get softif attributes
> + * @skb: Netlink message with request data
> + * @info: receiver information
> + *
> + * Return: 0 on success or negative error number in case of failure
> + */
> +static int batadv_netlink_get_mesh(struct sk_buff *skb, struct genl_info *info)
> +{
> +	struct batadv_priv *bat_priv = info->user_ptr[0];
> +	struct sk_buff *msg;
> +	int ret;

Same question here for info->user_ptr[0], would a wrapper
make sense?

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 03/19] batman-adv: Prepare framework for hardif genl config
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 03/19] batman-adv: Prepare framework for hardif " Sven Eckelmann
@ 2018-12-31 11:59   ` Linus Lüssing
  2018-12-31 19:17     ` Sven Eckelmann
  2019-01-04  0:39   ` Linus Lüssing
  1 sibling, 1 reply; 43+ messages in thread
From: Linus Lüssing @ 2018-12-31 11:59 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Fri, Dec 07, 2018 at 02:58:30PM +0100, Sven Eckelmann wrote:
[...]
> The BATADV_CMD_GET_HARDIFS (or short version BATADV_CMD_GET_HARDIF) is
> reused as get command because it already allow to dump the content of other
> information from the slave/hard-interface which are not yet configuration
> specific.

"already allow" -> "already allows"

[...]
> @@ -76,6 +77,13 @@ enum batadv_genl_ops_flags {
>  	 *  safed in info->user_ptr[0]
>  	 */
>  	BATADV_FLAG_NEED_MESH = BIT(0),
> +
> +	/**
> +	 * @BATADV_FLAG_NEED_HARDIF: request requires valid hard interface in
> +	 *  attribute BATADV_ATTR_HARD_IFINDEX and expects a pointer to it to be
> +	 *  safed in info->user_ptr[1]
> +	 */
> +	BATADV_FLAG_NEED_HARDIF = BIT(1),

safed -> saved
(and same in the previous patch)

[...]
>  /**
>   * batadv_pre_doit() - Prepare batman-adv genl doit request
>   * @ops: requested netlink operation
> @@ -592,7 +738,16 @@ batadv_get_softif_from_info(struct net *net, struct genl_info *info)
>  static int batadv_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
>  			   struct genl_info *info)
>  {
> -	struct batadv_priv *bat_priv;
> +	struct batadv_hard_iface *hard_iface;
> +	struct batadv_priv *bat_priv = NULL;
> +	int ret;
> +
> +	if (WARN_ON(ops->internal_flags & BATADV_FLAG_NEED_HARDIF))
> +		return -EINVAL;
> +
> +	if (WARN_ON((ops->internal_flags & BATADV_FLAG_NEED_HARDIF) &&
> +		    (~ops->internal_flags & BATADV_FLAG_NEED_MESH)))
> +		return -EINVAL;

Seems like the second part is unreachable code. If
BATADV_FLAG_NEED_HARDIF is set then the function returns with the first
if-clause already.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 01/19] batman-adv: Move common genl doit code pre/post hooks
  2018-12-30 16:57   ` Linus Lüssing
@ 2018-12-31 19:08     ` Sven Eckelmann
  0 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-31 19:08 UTC (permalink / raw)
  To: b.a.t.m.a.n

[-- Attachment #1: Type: text/plain, Size: 2700 bytes --]

On Sunday, 30 December 2018 17.57.54 CET Linus Lüssing wrote:
> On Fri, Dec 07, 2018 at 02:58:28PM +0100, Sven Eckelmann wrote:
> > +/**
> > + * batadv_get_softif_from_info() - Retrieve soft interface from genl 
attributes
> > + * @net: the applicable net namespace
> > + * @info: receiver information
> > + *
> > + * Return: Pointer to soft interface on success, error pointer on error
> > + */
> > +static struct batadv_priv *
> > +batadv_get_softif_from_info(struct net *net, struct genl_info *info)
> 
> Since this returns a batadv_priv, shouldn't it better be called
> batadv_get_batpriv_from_info() or batadv_get_bat_priv_from_info() maybe?

OK

> 
> > +{
> > +	struct net_device *soft_iface;
> > +	int ifindex;
> > +
> > +	if (!info->attrs[BATADV_ATTR_MESH_IFINDEX])
> > +		return ERR_PTR(-EINVAL);
> > +
> > +	ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]);
> > +
> > +	soft_iface = dev_get_by_index(net, ifindex);
> > +	if (!soft_iface)
> > +		return ERR_PTR(-ENODEV);
> > +
> > +	if (!batadv_softif_is_valid(soft_iface))
> > +		goto err_put_softif;
> > +
> > +	return netdev_priv(soft_iface);
> > +
> > +err_put_softif:
> > +	dev_put(soft_iface);
> > +
> > +	return ERR_PTR(-EINVAL);
> > +}
> 
> Is holding a reference to bat_priv->soft_iface really
> necessary (and releasing it in batadv_post_doit() )?
> If we are able to retrieve a valid bat_priv then this bat_priv
> itself should hold a reference to to soft_iface, shouldn't it?

No, we don't hold any explicit reference to bat_priv itself. The bat_priv is a 
part of the memory of the soft_iface. So we most hold a reference for 
soft_iface because we don't prevent that it is removed in the meantime (the 
netlink interface is registered per module and not per meshif/softif).

[...]
> > +	if (ops->internal_flags & BATADV_FLAG_NEED_MESH) {
> > +		bat_priv = batadv_get_softif_from_info(genl_info_net(info),
> > +						       info);
> 
> Would it look nicer to store genl_info_net(info) in a temporary variable
> so that its shorter and the newline for the second parameter could
> be avoided?

Ok

> > +		if (IS_ERR(bat_priv))
> > +			return PTR_ERR(bat_priv);
> > +
> > +		info->user_ptr[0] = bat_priv;
> 
> Would it make sense to wrap this private data access into
> something somehow? Conceptually similar to what we do not with skb private
> data already for instance. There we use BATADV_SKB_CB() for instance.

Please not, we only have two pointers and I definitely don't want to force 
specific positions (we need three at the moment - but max two per command). 
You should compare it with the nl80211 code.

Kind regards,
	Sven


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 02/19] batman-adv: Prepare framework for mesh genl config
  2018-12-31 11:09   ` Linus Lüssing
@ 2018-12-31 19:11     ` Sven Eckelmann
  0 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-31 19:11 UTC (permalink / raw)
  To: b.a.t.m.a.n

[-- Attachment #1: Type: text/plain, Size: 846 bytes --]

On Monday, 31 December 2018 12.09.50 CET Linus Lüssing wrote:
[...]
> [...]
> 
> >  #ifdef CONFIG_BATMAN_ADV_BLA
> >  	if (nla_put_u16(msg, BATADV_ATTR_BLA_CRC,
> >  			ntohs(bat_priv->bla.claim_dest.group)))
> > -		goto out;
> > +		goto nla_put_failure;
> >  #endif
> >  
> >  	if (batadv_mcast_mesh_info_put(msg, bat_priv))
> > -		goto out;
> > +		goto nla_put_failure;
> 
> With the rename of "batadv_netlink_mesh_info_put" to
> "batadv_netlink_mesh_put", I'm wondering whether
> batadv_mcast_mesh_info_put() should be renamed, too.
> batadv_mcast_mesh_put() would probably be a bit too generic.
> But maybe something like batadv_mcast_nl_mesh_put()?

Not relevant for this patch. But feel free to check what we can do to make it 
more consistent. We can then do it after having the rest in place.

Kind regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 03/19] batman-adv: Prepare framework for hardif genl config
  2018-12-31 11:59   ` Linus Lüssing
@ 2018-12-31 19:17     ` Sven Eckelmann
  0 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2018-12-31 19:17 UTC (permalink / raw)
  To: b.a.t.m.a.n

[-- Attachment #1: Type: text/plain, Size: 1027 bytes --]

On Monday, 31 December 2018 12.59.36 CET Linus Lüssing wrote:
[...]
> >  static int batadv_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
> >  			   struct genl_info *info)
> >  {
> > -	struct batadv_priv *bat_priv;
> > +	struct batadv_hard_iface *hard_iface;
> > +	struct batadv_priv *bat_priv = NULL;
> > +	int ret;
> > +
> > +	if (WARN_ON(ops->internal_flags & BATADV_FLAG_NEED_HARDIF))
> > +		return -EINVAL;
> > +
> > +	if (WARN_ON((ops->internal_flags & BATADV_FLAG_NEED_HARDIF) &&
> > +		    (~ops->internal_flags & BATADV_FLAG_NEED_MESH)))
> > +		return -EINVAL;
> 
> Seems like the second part is unreachable code. If
> BATADV_FLAG_NEED_HARDIF is set then the function returns with the first
> if-clause already.

Looks like I've incorrectly splitted the patch at this position. Makes more 
sense when you check the next patch.

So the first check should be removed from this patch to make it less 
confusing.


Btw. thanks for the spelling/grammar fixes.

Kind regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 03/19] batman-adv: Prepare framework for hardif genl config
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 03/19] batman-adv: Prepare framework for hardif " Sven Eckelmann
  2018-12-31 11:59   ` Linus Lüssing
@ 2019-01-04  0:39   ` Linus Lüssing
  2019-01-04  7:52     ` Sven Eckelmann
  1 sibling, 1 reply; 43+ messages in thread
From: Linus Lüssing @ 2019-01-04  0:39 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Fri, Dec 07, 2018 at 02:58:30PM +0100, Sven Eckelmann wrote:
[...]
> +/**
> + * batadv_get_hardif_from_info() - Retrieve hardif from genl attributes
> + * @bat_priv: the bat priv with all the soft interface information
> + * @net: the applicable net namespace
> + * @info: receiver information
> + *
> + * Return: Pointer to hard interface on success, error pointer on error
> + */
> +static struct batadv_hard_iface *
> +batadv_get_hardif_from_info(struct batadv_priv *bat_priv, struct net *net,
> +			    struct genl_info *info)
> +{
> +	struct batadv_hard_iface *hard_iface;
> +	struct net_device *hard_dev;
> +	unsigned int hardif_index;
> +
> +	if (!info->attrs[BATADV_ATTR_HARD_IFINDEX])
> +		return ERR_PTR(-EINVAL);
> +
> +	hardif_index = nla_get_u32(info->attrs[BATADV_ATTR_HARD_IFINDEX]);
> +
> +	hard_dev = dev_get_by_index(net, hardif_index);
> +	if (!hard_dev)
> +		return ERR_PTR(-ENODEV);
> +
> +	hard_iface = batadv_hardif_get_by_netdev(hard_dev);
> +	if (!hard_iface)
> +		goto err_put_harddev;
> +
> +	if (hard_iface->soft_iface != bat_priv->soft_iface)
> +		goto err_put_hardif;

When would this case above happen?

> +
> +	return hard_iface;

It seems unnecessary to keep holding a reference to hard_dev on
successful return here (and releasing it in post_doit). We return
hard_iface and increase its reference count which in turn itself holds
a reference to the according hard_dev already.

The usual pattern for a getter like this would be to increase the
reference count for just the object returned, wouldn't it?

In any case, maybe it would make sense to mention increased
refcounts in the kerneldoc? So that in case someone were reusing
this function that s/he would not miss the decrease. (happens too
often with these net_device reference counters...) Same for
batadv_get_softif_from_info().

> +
> +err_put_hardif:
> +	batadv_hardif_put(hard_iface);
> +err_put_harddev:
> +	dev_put(hard_dev);
> +
> +	return ERR_PTR(-EINVAL);
> +}
> +

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 05/19] batman-adv: Add aggregated_ogms mesh genl configuration
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 05/19] batman-adv: Add aggregated_ogms mesh genl configuration Sven Eckelmann
@ 2019-01-04  1:40   ` Linus Lüssing
  2019-01-04  7:59     ` Sven Eckelmann
  2019-01-04  2:06   ` Linus Lüssing
  1 sibling, 1 reply; 43+ messages in thread
From: Linus Lüssing @ 2019-01-04  1:40 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking; +Cc: Marek Lindner

On Fri, Dec 07, 2018 at 02:58:32PM +0100, Sven Eckelmann wrote:
> +	/**
> +	 * @BATADV_ATTR_AGGREGATED_OGMS: whether the batman protocol messages
> +	 *  of the mesh mesh interface shall be aggregated or not.
> +	 */
> +	BATADV_ATTR_AGGREGATED_OGMS,
> +

I'm wondering, would it make sense to take this opportunity to
rename this to BATADV_ATTR_AGGREGATION? In case we were adding
aggregation support to something other than OGMs in the future.

(and maybe even make it a u32 to be able to potentially use it as
a bitfield with a useable length?)

And I know, the generic aggregation patchset was rejected. But on
the other hand I don't think that OGMs are that special that they
will always be the only packet type worth aggregating.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 04/19] batman-adv: Prepare framework for vlan genl config
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 04/19] batman-adv: Prepare framework for vlan " Sven Eckelmann
@ 2019-01-04  1:53   ` Linus Lüssing
  0 siblings, 0 replies; 43+ messages in thread
From: Linus Lüssing @ 2019-01-04  1:53 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking




On Fri, Dec 07, 2018 at 02:58:31PM +0100, Sven Eckelmann wrote:
> The batman-adv configuration interface was implemented solely using sysfs.
> This approach was condemned by non-batadv developers as "huge mistake".
> Instead a netlink/genl based implementation was suggested.
> 
> Beside the mesh/soft-interface specific configuration, the VLANs on top of
> the mesh/soft-interface have configuration settings. The genl interface
> reflects this by allowing to get/set it using the vlan specific commands
> BATADV_CMD_GET_VLAN/BATADV_CMD_SET_VLAN.
> 
> The set command BATADV_CMD_SET_MESH will also notify interested userspace
> listeners of the "config" mcast group using the BATADV_CMD_SET_VLAN command
> message type that settings might have been changed and what the current
> values are.
> 
> Signed-off-by: Sven Eckelmann <sven@narfation.org>
> ---

Looks good.

Initially I was a bit confused with batadv_pre_doit() and
thought you were missing to free the hard_iface in the
"if (IS_ERR(vlan))" case. But then I remembered your initial
WARN_ON() which ensures that hardif and vlan are exclusive.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 14/19] batman-adv: Add multicast_mode mesh genl configuration
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 14/19] batman-adv: Add multicast_mode " Sven Eckelmann
@ 2019-01-04  1:57   ` Linus Lüssing
  2019-01-04  7:44     ` Sven Eckelmann
  0 siblings, 1 reply; 43+ messages in thread
From: Linus Lüssing @ 2019-01-04  1:57 UTC (permalink / raw)
  To: Sven Eckelmann; +Cc: b.a.t.m.a.n

On Fri, Dec 07, 2018 at 02:58:41PM +0100, Sven Eckelmann wrote:
> diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
> index 8e3a1b6e..32762003 100644
> --- a/net/batman-adv/netlink.c
> +++ b/net/batman-adv/netlink.c
> @@ -155,6 +155,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
>  	[BATADV_ATTR_GW_SEL_CLASS]		= { .type = NLA_U32 },
>  	[BATADV_ATTR_HOP_PENALTY]		= { .type = NLA_U8 },
>  	[BATADV_ATTR_LOG_LEVEL]			= { .type = NLA_U32 },
> +	[BATADV_ATTR_MULTICAST_MODE]		= { .type = NLA_U8 },
>  };

Since the name is more generic than just a flag, would it make
sense to make this a U32, just to stay flexible for the future?

(I don't have any specific ideas or plans to use more
values for it right now, though)

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 05/19] batman-adv: Add aggregated_ogms mesh genl configuration
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 05/19] batman-adv: Add aggregated_ogms mesh genl configuration Sven Eckelmann
  2019-01-04  1:40   ` Linus Lüssing
@ 2019-01-04  2:06   ` Linus Lüssing
  1 sibling, 0 replies; 43+ messages in thread
From: Linus Lüssing @ 2019-01-04  2:06 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking; +Cc: Marek Lindner

On Fri, Dec 07, 2018 at 02:58:32PM +0100, Sven Eckelmann wrote:
> diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h
> index 865cdf90..a01d90ed 100644
> --- a/include/uapi/linux/batman_adv.h
> +++ b/include/uapi/linux/batman_adv.h
> @@ -350,6 +350,12 @@ enum batadv_nl_attrs {
>  	 */
>  	BATADV_ATTR_VLANID,
>  
> +	/**
> +	 * @BATADV_ATTR_AGGREGATED_OGMS: whether the batman protocol messages
> +	 *  of the mesh mesh interface shall be aggregated or not.
> +	 */
> +	BATADV_ATTR_AGGREGATED_OGMS,
> +

"mesh mesh" -> "mesh"

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 19/19] batman-adv: Trigger genl notification on sysfs config change
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 19/19] batman-adv: Trigger genl notification on sysfs config change Sven Eckelmann
@ 2019-01-04  2:29   ` Linus Lüssing
  2019-01-04  7:58     ` Sven Eckelmann
  0 siblings, 1 reply; 43+ messages in thread
From: Linus Lüssing @ 2019-01-04  2:29 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Fri, Dec 07, 2018 at 02:58:46PM +0100, Sven Eckelmann wrote:
> The generic netlink code is expected to trigger notification messages when
> configuration might have been changed. But the configuration of batman-adv
> is most of the time still done using sysfs. So the sysfs interface should
> also trigger the corresponding netlink messages via the "config" multicast
> group.
> 
> Signed-off-by: Sven Eckelmann <sven@narfation.org>
> ---

I'm wondering, before it was quite easy to add new sysfs
attributes with just a few lines thanks to macros. Now we
need to add code in four more places in netlink.c whenever we introduce a
new configuration option.

Would it be possible (and maybe even reduce code size?) if the
sysfs and netlink parts were wrapped into some (macro) functions and/or
structs, to still be able to add options from a central place and with
only a few lines?

Or would that become too ugly? Or not worth the effort for the few
options we have right now?

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 14/19] batman-adv: Add multicast_mode mesh genl configuration
  2019-01-04  1:57   ` Linus Lüssing
@ 2019-01-04  7:44     ` Sven Eckelmann
  2019-01-04  8:51       ` Jiri Pirko
  0 siblings, 1 reply; 43+ messages in thread
From: Sven Eckelmann @ 2019-01-04  7:44 UTC (permalink / raw)
  To: Linus Lüssing, Jiri Pirko; +Cc: b.a.t.m.a.n

[-- Attachment #1: Type: text/plain, Size: 967 bytes --]

On Friday, 4 January 2019 02.57.26 CET Linus Lüssing wrote:
> On Fri, Dec 07, 2018 at 02:58:41PM +0100, Sven Eckelmann wrote:
> > diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
> > index 8e3a1b6e..32762003 100644
> > --- a/net/batman-adv/netlink.c
> > +++ b/net/batman-adv/netlink.c
> > @@ -155,6 +155,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
> >  	[BATADV_ATTR_GW_SEL_CLASS]		= { .type = NLA_U32 },
> >  	[BATADV_ATTR_HOP_PENALTY]		= { .type = NLA_U8 },
> >  	[BATADV_ATTR_LOG_LEVEL]			= { .type = NLA_U32 },
> > +	[BATADV_ATTR_MULTICAST_MODE]		= { .type = NLA_U8 },
> >  };
> 
> Since the name is more generic than just a flag, would it make
> sense to make this a U32, just to stay flexible for the future?
> 
> (I don't have any specific ideas or plans to use more
> values for it right now, though)

Please discuss this with Jiro because he told us to use u8.

Kind regards,
	Sven


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 03/19] batman-adv: Prepare framework for hardif genl config
  2019-01-04  0:39   ` Linus Lüssing
@ 2019-01-04  7:52     ` Sven Eckelmann
  2019-01-05 15:12       ` Linus Lüssing
  0 siblings, 1 reply; 43+ messages in thread
From: Sven Eckelmann @ 2019-01-04  7:52 UTC (permalink / raw)
  To: b.a.t.m.a.n

[-- Attachment #1: Type: text/plain, Size: 1887 bytes --]

On Friday, 4 January 2019 01.39.54 CET Linus Lüssing wrote:
> On Fri, Dec 07, 2018 at 02:58:30PM +0100, Sven Eckelmann wrote:
> [...]
> > +/**
> > + * batadv_get_hardif_from_info() - Retrieve hardif from genl attributes
> > + * @bat_priv: the bat priv with all the soft interface information
> > + * @net: the applicable net namespace
> > + * @info: receiver information
> > + *
> > + * Return: Pointer to hard interface on success, error pointer on error
> > + */
> > +static struct batadv_hard_iface *
> > +batadv_get_hardif_from_info(struct batadv_priv *bat_priv, struct net 
*net,
> > +			    struct genl_info *info)
> > +{
> > +	struct batadv_hard_iface *hard_iface;
> > +	struct net_device *hard_dev;
> > +	unsigned int hardif_index;
> > +
> > +	if (!info->attrs[BATADV_ATTR_HARD_IFINDEX])
> > +		return ERR_PTR(-EINVAL);
> > +
> > +	hardif_index = nla_get_u32(info->attrs[BATADV_ATTR_HARD_IFINDEX]);
> > +
> > +	hard_dev = dev_get_by_index(net, hardif_index);
> > +	if (!hard_dev)
> > +		return ERR_PTR(-ENODEV);
> > +
> > +	hard_iface = batadv_hardif_get_by_netdev(hard_dev);
> > +	if (!hard_iface)
> > +		goto err_put_harddev;
> > +
> > +	if (hard_iface->soft_iface != bat_priv->soft_iface)
> > +		goto err_put_hardif;
> 
> When would this case above happen?


When you ask for a hard interface from a different mesh interface or a hard 
interface without a mesh interface.


> It seems unnecessary to keep holding a reference to hard_dev on
> successful return here (and releasing it in post_doit).
[...]

Ok.

> often with these net_device reference counters...) Same for
> batadv_get_softif_from_info().

No, no, no, no, no, no, no and again no. The net_device is the only thing with 
a refcounter here. The bat_priv doesn't have a refcounter because it is just a 
memory region in the net_device.

Kind regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 19/19] batman-adv: Trigger genl notification on sysfs config change
  2019-01-04  2:29   ` Linus Lüssing
@ 2019-01-04  7:58     ` Sven Eckelmann
  2019-01-05 15:03       ` Linus Lüssing
  0 siblings, 1 reply; 43+ messages in thread
From: Sven Eckelmann @ 2019-01-04  7:58 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Linus Lüssing, jiri

[-- Attachment #1: Type: text/plain, Size: 837 bytes --]

On Friday, 4 January 2019 03.29.16 CET Linus Lüssing wrote:
[...]
> I'm wondering, before it was quite easy to add new sysfs
> attributes with just a few lines thanks to macros. Now we
> need to add code in four more places in netlink.c whenever we introduce a
> new configuration option.
> 
> Would it be possible (and maybe even reduce code size?) if the
> sysfs and netlink parts were wrapped into some (macro) functions and/or
> structs, to still be able to add options from a central place and with
> only a few lines?
> 
> Or would that become too ugly? Or not worth the effort for the few
> options we have right now?

You only need a couple of lines to add netlink things. And we don't want sysfs 
anymore. So no need to add ugly hacks to add both netlink+sysfs with a "couple 
of lines".

Kind regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 05/19] batman-adv: Add aggregated_ogms mesh genl configuration
  2019-01-04  1:40   ` Linus Lüssing
@ 2019-01-04  7:59     ` Sven Eckelmann
  0 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2019-01-04  7:59 UTC (permalink / raw)
  To: b.a.t.m.a.n; +Cc: Linus Lüssing, Marek Lindner, jiri

[-- Attachment #1: Type: text/plain, Size: 923 bytes --]

On Friday, 4 January 2019 02.40.06 CET Linus Lüssing wrote:
> On Fri, Dec 07, 2018 at 02:58:32PM +0100, Sven Eckelmann wrote:
> > +	/**
> > +	 * @BATADV_ATTR_AGGREGATED_OGMS: whether the batman protocol messages
> > +	 *  of the mesh mesh interface shall be aggregated or not.
> > +	 */
> > +	BATADV_ATTR_AGGREGATED_OGMS,
> > +
> 
> I'm wondering, would it make sense to take this opportunity to
> rename this to BATADV_ATTR_AGGREGATION? In case we were adding
> aggregation support to something other than OGMs in the future.
> 
> (and maybe even make it a u32 to be able to potentially use it as
> a bitfield with a useable length?)
> 
> And I know, the generic aggregation patchset was rejected. But on
> the other hand I don't think that OGMs are that special that they
> will always be the only packet type worth aggregating.
> 

Any suggestions from Jiri regarding this?

Kind regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 14/19] batman-adv: Add multicast_mode mesh genl configuration
  2019-01-04  7:44     ` Sven Eckelmann
@ 2019-01-04  8:51       ` Jiri Pirko
  2019-01-05 15:02         ` Linus Lüssing
  0 siblings, 1 reply; 43+ messages in thread
From: Jiri Pirko @ 2019-01-04  8:51 UTC (permalink / raw)
  To: Sven Eckelmann; +Cc: Linus Lüssing, b.a.t.m.a.n

Fri, Jan 04, 2019 at 08:44:38AM CET, sven@narfation.org wrote:
>On Friday, 4 January 2019 02.57.26 CET Linus Lüssing wrote:
>> On Fri, Dec 07, 2018 at 02:58:41PM +0100, Sven Eckelmann wrote:
>> > diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
>> > index 8e3a1b6e..32762003 100644
>> > --- a/net/batman-adv/netlink.c
>> > +++ b/net/batman-adv/netlink.c
>> > @@ -155,6 +155,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
>> >  	[BATADV_ATTR_GW_SEL_CLASS]		= { .type = NLA_U32 },
>> >  	[BATADV_ATTR_HOP_PENALTY]		= { .type = NLA_U8 },
>> >  	[BATADV_ATTR_LOG_LEVEL]			= { .type = NLA_U32 },
>> > +	[BATADV_ATTR_MULTICAST_MODE]		= { .type = NLA_U8 },
>> >  };
>> 
>> Since the name is more generic than just a flag, would it make
>> sense to make this a U32, just to stay flexible for the future?

If the attribute is supposed to be just a bool, the name would be
probably better to change to "BATADV_ATTR_MULTICAST_ENABLED" or
something.


>> 
>> (I don't have any specific ideas or plans to use more
>> values for it right now, though)
>
>Please discuss this with Jiro because he told us to use u8.
>
>Kind regards,
>	Sven
>



^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 14/19] batman-adv: Add multicast_mode mesh genl configuration
  2019-01-04  8:51       ` Jiri Pirko
@ 2019-01-05 15:02         ` Linus Lüssing
  0 siblings, 0 replies; 43+ messages in thread
From: Linus Lüssing @ 2019-01-05 15:02 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Sven Eckelmann,
	The list for a Better Approach To Mobile Ad-hoc Networking

On Fri, Jan 04, 2019 at 08:51:56AM +0000, Jiri Pirko wrote:
> Fri, Jan 04, 2019 at 08:44:38AM CET, sven@narfation.org wrote:
> >On Friday, 4 January 2019 02.57.26 CET Linus Lüssing wrote:
> >> On Fri, Dec 07, 2018 at 02:58:41PM +0100, Sven Eckelmann wrote:
> >> > diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
> >> > index 8e3a1b6e..32762003 100644
> >> > --- a/net/batman-adv/netlink.c
> >> > +++ b/net/batman-adv/netlink.c
> >> > @@ -155,6 +155,7 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
> >> >  	[BATADV_ATTR_GW_SEL_CLASS]		= { .type = NLA_U32 },
> >> >  	[BATADV_ATTR_HOP_PENALTY]		= { .type = NLA_U8 },
> >> >  	[BATADV_ATTR_LOG_LEVEL]			= { .type = NLA_U32 },
> >> > +	[BATADV_ATTR_MULTICAST_MODE]		= { .type = NLA_U8 },
> >> >  };
> >> 
> >> Since the name is more generic than just a flag, would it make
> >> sense to make this a U32, just to stay flexible for the future?
> 
> If the attribute is supposed to be just a bool, the name would be
> probably better to change to "BATADV_ATTR_MULTICAST_ENABLED" or
> something.

Hm, BATADV_ATTR_MULTICAST_ENABLED sounds confusing to me. In a
layer 2 mesh network, multicast always needs to be enabled for
things like IP to work.

So setting this to 0 does not disable multicast.

What this option does is using "classic flooding" (0) for
multicast packets or dropping/unicasting if possible, if IGMP/MLD
snooping detected such potential (1).

And since there were many discussions regarding which additional
techniques and algorithms could be implemented I would expect more
options to follow.

And for complementary techniques, a bitfield of 32 bits size
could be useful, I guess?

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 19/19] batman-adv: Trigger genl notification on sysfs config change
  2019-01-04  7:58     ` Sven Eckelmann
@ 2019-01-05 15:03       ` Linus Lüssing
  0 siblings, 0 replies; 43+ messages in thread
From: Linus Lüssing @ 2019-01-05 15:03 UTC (permalink / raw)
  To: Sven Eckelmann; +Cc: b.a.t.m.a.n, jiri

On Fri, Jan 04, 2019 at 08:58:32AM +0100, Sven Eckelmann wrote:
> On Friday, 4 January 2019 03.29.16 CET Linus Lüssing wrote:
> [...]
> > I'm wondering, before it was quite easy to add new sysfs
> > attributes with just a few lines thanks to macros. Now we
> > need to add code in four more places in netlink.c whenever we introduce a
> > new configuration option.
> > 
> > Would it be possible (and maybe even reduce code size?) if the
> > sysfs and netlink parts were wrapped into some (macro) functions and/or
> > structs, to still be able to add options from a central place and with
> > only a few lines?
> > 
> > Or would that become too ugly? Or not worth the effort for the few
> > options we have right now?
> 
> You only need a couple of lines to add netlink things. And we don't want sysfs 
> anymore. So no need to add ugly hacks to add both netlink+sysfs with a "couple 
> of lines".
> 
> Kind regards,
> 	Sven

Ok

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 03/19] batman-adv: Prepare framework for hardif genl config
  2019-01-04  7:52     ` Sven Eckelmann
@ 2019-01-05 15:12       ` Linus Lüssing
  2019-01-05 17:22         ` Sven Eckelmann
  0 siblings, 1 reply; 43+ messages in thread
From: Linus Lüssing @ 2019-01-05 15:12 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Fri, Jan 04, 2019 at 08:52:22AM +0100, Sven Eckelmann wrote:
> > It seems unnecessary to keep holding a reference to hard_dev on
> > successful return here (and releasing it in post_doit).
> [...]
> 
> Ok.
> 
> > often with these net_device reference counters...) Same for
> > batadv_get_softif_from_info().
> 
> No, no, no, no, no, no, no and again no. The net_device is the only thing with 
> a refcounter here. The bat_priv doesn't have a refcounter because it is just a 
> memory region in the net_device.

With "Same for batadv_get_softif_from_info()" I was talking about
the

> In any case, maybe it would make sense to mention increased refcounts in
> the kerneldoc?

That is to add a line like "Increases the refcount of foo and
bar." So that users know which references to release and how to
use this function just from reading the kerneldoc.

I'm not talking about bat_priv here.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 03/19] batman-adv: Prepare framework for hardif genl config
  2019-01-05 15:12       ` Linus Lüssing
@ 2019-01-05 17:22         ` Sven Eckelmann
  0 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2019-01-05 17:22 UTC (permalink / raw)
  To: b.a.t.m.a.n

[-- Attachment #1: Type: text/plain, Size: 837 bytes --]

On Saturday, 5 January 2019 16.12.24 CET Linus Lüssing wrote:
[...]
> > > often with these net_device reference counters...) Same for
> > > batadv_get_softif_from_info().
> > 
> > No, no, no, no, no, no, no and again no. The net_device is the only thing with 
> > a refcounter here. The bat_priv doesn't have a refcounter because it is just a 
> > memory region in the net_device.
> 
> With "Same for batadv_get_softif_from_info()" I was talking about
> the
> 
> > In any case, maybe it would make sense to mention increased refcounts in
> > the kerneldoc?
> 
> That is to add a line like "Increases the refcount of foo and
> bar." So that users know which references to release and how to
> use this function just from reading the kerneldoc.
> 
> I'm not talking about bat_priv here.

Ok

Kind regards,
	Sven


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 02/19] batman-adv: Prepare framework for mesh genl config
  2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 02/19] batman-adv: Prepare framework for mesh genl config Sven Eckelmann
  2018-12-31 11:09   ` Linus Lüssing
@ 2019-01-07 18:49   ` Linus Lüssing
  2019-01-08  7:54     ` Sven Eckelmann
  1 sibling, 1 reply; 43+ messages in thread
From: Linus Lüssing @ 2019-01-07 18:49 UTC (permalink / raw)
  To: The list for a Better Approach To Mobile Ad-hoc Networking

On Fri, Dec 07, 2018 at 02:58:29PM +0100, Sven Eckelmann wrote:
> diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
> index b20801a3..d89761f8 100644
> --- a/net/batman-adv/netlink.c
> +++ b/net/batman-adv/netlink.c
[...]
> -static int
> -batadv_netlink_mesh_info_put(struct sk_buff *msg, struct net_device *soft_iface)
> +static int batadv_netlink_mesh_put(struct sk_buff *msg,
> +				   struct batadv_priv *bat_priv,
> +				   enum batadv_nl_commands cmd,
> +				   u32 portid, u32 seq, int flags)
>  {
> -	struct batadv_priv *bat_priv = netdev_priv(soft_iface);
> +	struct net_device *soft_iface = bat_priv->soft_iface;
>  	struct batadv_hard_iface *primary_if = NULL;
>  	struct net_device *hard_iface;
> -	int ret = -ENOBUFS;
> +	void *hdr;
> +
> +	hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, flags, cmd);
> +	if (!hdr)
> +		return -ENOBUFS;
>  
>  	if (nla_put_string(msg, BATADV_ATTR_VERSION, BATADV_SOURCE_VERSION) ||
>  	    nla_put_string(msg, BATADV_ATTR_ALGO_NAME,
> @@ -162,16 +173,16 @@ batadv_netlink_mesh_info_put(struct sk_buff *msg, struct net_device *soft_iface)
>  		    soft_iface->dev_addr) ||
>  	    nla_put_u8(msg, BATADV_ATTR_TT_TTVN,
>  		       (u8)atomic_read(&bat_priv->tt.vn)))
> -		goto out;
> +		goto nla_put_failure;
>  
>  #ifdef CONFIG_BATMAN_ADV_BLA
>  	if (nla_put_u16(msg, BATADV_ATTR_BLA_CRC,
>  			ntohs(bat_priv->bla.claim_dest.group)))
> -		goto out;
> +		goto nla_put_failure;
>  #endif
>  
>  	if (batadv_mcast_mesh_info_put(msg, bat_priv))
> -		goto out;
> +		goto nla_put_failure;
>  
>  	primary_if = batadv_primary_if_get_selected(bat_priv);
>  	if (primary_if && primary_if->if_status == BATADV_IF_ACTIVE) {
> @@ -183,77 +194,94 @@ batadv_netlink_mesh_info_put(struct sk_buff *msg, struct net_device *soft_iface)
>  				   hard_iface->name) ||
>  		    nla_put(msg, BATADV_ATTR_HARD_ADDRESS, ETH_ALEN,
>  			    hard_iface->dev_addr))
> -			goto out;
> +			goto nla_put_failure;
>  	}
>  
> -	ret = 0;
> +	batadv_hardif_put(primary_if);

I seem to be able to trigger a null pointer dereference for this
batadv_hardif_put() call here. With the following steps I end up
with a primary_if == NULL:

$ batctl if add 1

root@Linus-Debian:~# batctl o
Error - interface bat0 is not present or not a batman-adv interface
root@Linus-Debian:~# batctl if add 1
Error - interface does not exist: 1
root@Linus-Debian:~# batctl o
Killed
root@Linus-Debian:~#
root@Linus-Debian:~#
root@Linus-Debian:~# batctl o

>  
> - out:
> +	genlmsg_end(msg, hdr);
> +	return 0;
> +
> +nla_put_failure:
>  	if (primary_if)
>  		batadv_hardif_put(primary_if);
>  
> -	return ret;
> +	genlmsg_cancel(msg, hdr);
> +	return -EMSGSIZE;
>  }

The panic looks like this then:

[ 2309.363754] batman_adv: bat0: Interface deactivated: ens3
[ 2309.364709] batman_adv: bat0: Removing interface: ens3
[ 2309.365662] batman_adv: bat0: Interface deactivated: ens5
[ 2309.366624] batman_adv: bat0: Removing interface: ens5
[ 2310.402540] batman_adv: B.A.T.M.A.N. advanced 2018.4-38-g25676ce7-dirty (compatibility version 15) loaded
[ 2321.727530] BUG: unable to handle kernel NULL pointer dereference at 0000000000000028
[ 2321.728869] IP: [<ffffffffc091df19>] batadv_netlink_mesh_put.constprop.13+0x459/0x630 [batman_adv]
[ 2321.730060] PGD 0 [ 2321.730311]
[ 2321.730533] Oops: 0002 [#1] SMP 
[ 2321.730952] Modules linked in: batman_adv(O) cfg80211 rfkill evdev joydev serio_raw pcspkr button nfsd bridge auth_rpcgss oid_registry stp nfs_acl lockd llc grace sunrpc crc16 ip_tables x_tables autofs4 btrfs raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx xor raid6_pq libcrc32c crc32c_generic raid1 raid0 multipath linear md_mod dm_mirror dm_region_hash dm_log dm_mod 9pnet_rdma rdma_cm configfs iw_cm ib_cm ib_core 9p fscache 8139too ata_generic 9pnet_virtio 9pnet psmouse floppy virtio_pci virtio_ring virtio 8139cp mii ata_piix e1000 i2c_piix4 libata scsi_mod [last unloaded: batman_adv] 
[ 2321.731472] CPU: 0 PID: 2948 Comm: batctl Tainted: G           O    4.9.0-7-amd64 #1 Debian 4.9.110-3+deb9u2
[ 2321.731472] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.10.2-1 04/01/2014
[ 2321.731472] task: ffff9fa5d9cde100 task.stack: ffffc0d7805e8000
[ 2321.731472] RIP: 0010:[<ffffffffc091df19>]  [<ffffffffc091df19>] batadv_netlink_mesh_put.constprop.13+0x459/0x630 [batman_adv]
[ 2321.731472] RSP: 0018:ffffc0d7805ebae0  EFLAGS: 00010282
[ 2321.731472] RAX: 0000000000000000 RBX: ffff9fa5dcf4c800 RCX: 00000000000003e8
[ 2321.731472] RDX: ffffffffc091a010 RSI: ffffc0d7805ebaec RDI: ffff9fa5db9c80f8
[ 2321.731472] RBP: ffff9fa5d9d538c0 R08: 00000000000003e8 R09: 0000000000000004
[ 2321.731472] R10: ffff9fa5db9c80fc R11: 0079747269642d37 R12: ffff9fa5db9c8014
[ 2321.731472] R13: 0000000000000028 R14: 0000000000000000 R15: ffffffff8bedbe00
[ 2321.731472] FS:  00007fa18cf5a740(0000) GS:ffff9fa5de800000(0000) knlGS:0000000000000000
[ 2321.731472] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 2321.731472] CR2: 0000000000000028 CR3: 0000000018d9f000 CR4: 00000000000006f0
[ 2321.731472] Stack:
[ 2321.731472]  ffffffff8b6f6cb6 000003e88b6f5d3e 7c37bd74f749c6fc ffffc0d7805ebb90
[ 2321.731472]  ffff9fa5dcf4c800 ffff9fa5d9d538c0 ffff9fa5dfa6e500 ffff9fa5db925c00
[ 2321.731472]  ffffffff8bedbe00 ffffffffc091e138 ffffffffc092d180 ffffffffc092d180
[ 2321.731472] Call Trace:
[ 2321.731472]  [<ffffffff8b6f6cb6>] ? __alloc_skb+0x96/0x1e0
[ 2321.731472]  [<ffffffffc091e138>] ? batadv_netlink_get_mesh+0x48/0xa0 [batman_adv]
[ 2321.731472]  [<ffffffff8b7445f5>] ? genl_family_rcv_msg+0x1c5/0x360
[ 2321.731472]  [<ffffffff8b6f5d3e>] ? __kmalloc_reserve.isra.35+0x2e/0x80
[ 2321.731472]  [<ffffffff8b3e4906>] ? kmem_cache_alloc_node_trace+0x156/0x5a0
[ 2321.731472]  [<ffffffff8b744790>] ? genl_family_rcv_msg+0x360/0x360
[ 2321.731472]  [<ffffffff8b744812>] ? genl_rcv_msg+0x82/0xc0
[ 2321.731472]  [<ffffffff8b743d94>] ? netlink_rcv_skb+0xa4/0xc0
[ 2321.731472]  [<ffffffff8b744414>] ? genl_rcv+0x24/0x40
[ 2321.731472]  [<ffffffff8b74376a>] ? netlink_unicast+0x18a/0x230
[ 2321.731472]  [<ffffffff8b743b67>] ? netlink_sendmsg+0x357/0x3b0
[ 2321.731472]  [<ffffffff8b6ee946>] ? sock_sendmsg+0x36/0x40
[ 2321.731472]  [<ffffffff8b6ef3d8>] ? ___sys_sendmsg+0x2c8/0x2e0
[ 2321.731472]  [<ffffffff8b3fe078>] ? mem_cgroup_commit_charge+0x78/0x4b0
[ 2321.731472]  [<ffffffff8b3b8a6e>] ? handle_mm_fault+0xe7e/0x1280
[ 2321.731472]  [<ffffffff8b6ed905>] ? move_addr_to_user+0xb5/0xd0
[ 2321.731472]  [<ffffffff8b6efce1>] ? __sys_sendmsg+0x51/0x90
[ 2321.731472]  [<ffffffff8b203b7d>] ? do_syscall_64+0x8d/0xf0
[ 2321.731472]  [<ffffffff8b814c4e>] ? entry_SYSCALL_64_after_swapgs+0x58/0xc6
[ 2321.731472] Code: 00 00 be 39 00 00 00 48 89 df 89 44 24 0c e8 3f 03 c4 ca 85 c0 75 48 48 c7 c2 10 a0 91 c0 49 83 c5 28 48 85 d2 0f 84 ae 01 00 00 <f0> 41 83 6d 00 01 75 10 4c 89 ef 89 44 24 04 e8 e3 c0 ff ff 8b
[ 2321.731472] RIP  [<ffffffffc091df19>] batadv_netlink_mesh_put.constprop.13+0x459/0x630 [batman_adv]
[ 2321.731472]  RSP <ffffc0d7805ebae0>
[ 2321.731472] CR2: 0000000000000028
[ 2321.770447] ---[ end trace cdc14a8e37e47f7e ]---


Next to a missing bailout for a primary_if == NULL, it's also odd
that this "batctl if add" does seem to change something in the
kernel even though it returns an error. I haven't looked into why
that happens yet, though.

PS: In these tests I had also commented out all items in the *_attrs[] arrays
in sysfs.c to make sure that I'm using netlink for everything.

^ permalink raw reply	[flat|nested] 43+ messages in thread

* Re: [B.A.T.M.A.N.] [RFC v3 02/19] batman-adv: Prepare framework for mesh genl config
  2019-01-07 18:49   ` Linus Lüssing
@ 2019-01-08  7:54     ` Sven Eckelmann
  0 siblings, 0 replies; 43+ messages in thread
From: Sven Eckelmann @ 2019-01-08  7:54 UTC (permalink / raw)
  To: b.a.t.m.a.n

[-- Attachment #1: Type: text/plain, Size: 1141 bytes --]

On Monday, 7 January 2019 19.49.06 CET Linus Lüssing wrote:
[...]
> I seem to be able to trigger a null pointer dereference for this
> batadv_hardif_put() call here. With the following steps I end up
> with a primary_if == NULL:
> 
> $ batctl if add 1
> 
> root@Linus-Debian:~# batctl o
> Error - interface bat0 is not present or not a batman-adv interface
> root@Linus-Debian:~# batctl if add 1
> Error - interface does not exist: 1
> root@Linus-Debian:~# batctl o
> Killed
> root@Linus-Debian:~#
> root@Linus-Debian:~#
> root@Linus-Debian:~# batctl o

You can reproduce it easier with (destroy is only there to make sure that the 
bat0 is really empty before the originator dump):

    batctl if destroy
    batctl if create
    batctl o

The check before 

    	batadv_hardif_put(primary_if);

is missing. So it should actually be (like in the nla_put_failure case):

    	if (primary_if)
    		batadv_hardif_put(primary_if);


And "batctl if add" is basically a short version of:

   batctl if create
   batctl if add -M XXXX

And in your test, only the second part failed.

Kind regards,
	Sven

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 43+ messages in thread

end of thread, other threads:[~2019-01-08  7:54 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-07 13:58 [B.A.T.M.A.N.] [RFC v3 00/19] batman-adv: netlink restructuring, part 2 Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 01/19] batman-adv: Move common genl doit code pre/post hooks Sven Eckelmann
2018-12-30 16:57   ` Linus Lüssing
2018-12-31 19:08     ` Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 02/19] batman-adv: Prepare framework for mesh genl config Sven Eckelmann
2018-12-31 11:09   ` Linus Lüssing
2018-12-31 19:11     ` Sven Eckelmann
2019-01-07 18:49   ` Linus Lüssing
2019-01-08  7:54     ` Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 03/19] batman-adv: Prepare framework for hardif " Sven Eckelmann
2018-12-31 11:59   ` Linus Lüssing
2018-12-31 19:17     ` Sven Eckelmann
2019-01-04  0:39   ` Linus Lüssing
2019-01-04  7:52     ` Sven Eckelmann
2019-01-05 15:12       ` Linus Lüssing
2019-01-05 17:22         ` Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 04/19] batman-adv: Prepare framework for vlan " Sven Eckelmann
2019-01-04  1:53   ` Linus Lüssing
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 05/19] batman-adv: Add aggregated_ogms mesh genl configuration Sven Eckelmann
2019-01-04  1:40   ` Linus Lüssing
2019-01-04  7:59     ` Sven Eckelmann
2019-01-04  2:06   ` Linus Lüssing
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 06/19] batman-adv: Add ap_isolation mesh/vlan " Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 07/19] batman-adv: Add bonding mesh " Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 08/19] batman-adv: Add bridge_loop_avoidance " Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 09/19] batman-adv: Add distributed_arp_table " Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 10/19] batman-adv: Add fragmentation " Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 11/19] batman-adv: Add gateway " Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 12/19] batman-adv: Add hop_penalty " Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 13/19] batman-adv: Add log_level " Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 14/19] batman-adv: Add multicast_mode " Sven Eckelmann
2019-01-04  1:57   ` Linus Lüssing
2019-01-04  7:44     ` Sven Eckelmann
2019-01-04  8:51       ` Jiri Pirko
2019-01-05 15:02         ` Linus Lüssing
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 15/19] batman-adv: Add network_coding " Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 16/19] batman-adv: Add orig_interval " Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 17/19] batman-adv: Add elp_interval hardif " Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 18/19] batman-adv: Add throughput_override " Sven Eckelmann
2018-12-07 13:58 ` [B.A.T.M.A.N.] [RFC v3 19/19] batman-adv: Trigger genl notification on sysfs config change Sven Eckelmann
2019-01-04  2:29   ` Linus Lüssing
2019-01-04  7:58     ` Sven Eckelmann
2019-01-05 15:03       ` Linus Lüssing

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.