From: Sven Eckelmann <sven@narfation.org>
To: b.a.t.m.a.n@lists.open-mesh.org
Subject: [B.A.T.M.A.N.] [RFC v3 04/19] batman-adv: Prepare framework for vlan genl config
Date: Fri, 7 Dec 2018 14:58:31 +0100 [thread overview]
Message-ID: <20181207135846.6152-5-sven@narfation.org> (raw)
In-Reply-To: <20181207135846.6152-1-sven@narfation.org>
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
next prev parent reply other threads:[~2018-12-07 13:58 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
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 ` Sven Eckelmann [this message]
2019-01-04 1:53 ` [B.A.T.M.A.N.] [RFC v3 04/19] batman-adv: Prepare framework for vlan " 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181207135846.6152-5-sven@narfation.org \
--to=sven@narfation.org \
--cc=b.a.t.m.a.n@lists.open-mesh.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.