* [RFC v2 18/19] batman-adv: Add throughput_override hardif genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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 a4ab6bda..49ab118e 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 70ab010e..970490a4 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.1
^ permalink raw reply related
* [RFC v2 17/19] batman-adv: Add elp_interval hardif genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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 f8661657..a4ab6bda 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 61a3e6f1..70ab010e 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.1
^ permalink raw reply related
* [RFC v2 16/19] batman-adv: Add orig_interval mesh genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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 8a3f8920..f8661657 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 7f42c5ec..61a3e6f1 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_ISOLATION_MASK];
+ 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.1
^ permalink raw reply related
* [RFC v2 15/19] batman-adv: Add network_coding mesh genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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 c2ee1818..8a3f8920 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 1b2ea342..7f42c5ec 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.1
^ permalink raw reply related
* [RFC v2 14/19] batman-adv: Add multicast_mode mesh genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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 1c7d325f..c2ee1818 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 a38e28e3..1b2ea342 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.1
^ permalink raw reply related
* [RFC v2 13/19] batman-adv: Add log_level mesh genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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 b6d0eaf6..1c7d325f 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 4d3a23df..a38e28e3 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.1
^ permalink raw reply related
* [RFC v2 12/19] batman-adv: Add hop_penalty mesh genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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 e9c48dbd..b6d0eaf6 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 4e806e48..4d3a23df 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.1
^ permalink raw reply related
* [RFC v2 11/19] batman-adv: Add gateway mesh genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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..e9c48dbd 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_CLIENT: 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..4e806e48 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.1
^ permalink raw reply related
* [RFC v2 10/19] batman-adv: Add fragmentation mesh genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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.1
^ permalink raw reply related
* [RFC v2 09/19] batman-adv: Add distributed_arp_table mesh genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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.1
^ permalink raw reply related
* [RFC v2 08/19] batman-adv: Add bridge_loop_avoidance mesh genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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.1
^ permalink raw reply related
* [RFC v2 07/19] batman-adv: Add bonding mesh genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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.1
^ permalink raw reply related
* [RFC v2 06/19] batman-adv: Add ap_isolation mesh/vlan genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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.1
^ permalink raw reply related
* [RFC v2 05/19] batman-adv: Add aggregated_ogms mesh genl configuration
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
---
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.1
^ permalink raw reply related
* [RFC v2 04/19] batman-adv: Prepare framework for vlan genl config
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.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.1
^ permalink raw reply related
* [RFC v2 03/19] batman-adv: Prepare framework for hardif genl config
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.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
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.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.1
^ permalink raw reply related
* [RFC v2 02/19] batman-adv: Prepare framework for mesh genl config
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.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.
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.
Cc: Jiri Pirko <jiri-VPRAkNaXOzVWk0Htik3J/w@public.gmane.org>
Signed-off-by: Sven Eckelmann <sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.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.1
^ permalink raw reply related
* [RFC v2 01/19] batman-adv: Move common genl doit code pre/post hooks
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
In-Reply-To: <20181123161359.13342-1-sven-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.org>
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-KaDOiPu9UxWEi8DpZVb4nw@public.gmane.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.1
^ permalink raw reply related
* [RFC v2 00/19] batman-adv: netlink restructuring, part 2
From: Sven Eckelmann @ 2018-11-23 16:13 UTC (permalink / raw)
To: b.a.t.m.a.n-ZwoEplunGu2X36UT3dwllkB+6BGkLq7r
Cc: netdev-u79uwXL29TY76Z2rM5mHXA, Jiri Pirko
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.
Luckily, Jiri Pirko told us that he will have a look at patches. I would
also 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.
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.1
^ permalink raw reply
* [PATCH 0/1] drivers/i40iw: out of bound access in i40iw_net_event()
From: Konstantin Khorenko @ 2018-11-23 16:10 UTC (permalink / raw)
To: Jeff Kirsher
Cc: Konstantin Khorenko, netdev, linux-kernel, intel-wired-lan,
David S . Miller
Running debug kernel on a node with infiniband card, got a KASan complain:
==================================================================
BUG: KASAN: slab-out-of-bounds in i40iw_copy_ip_ntohl+0x1c0/0x220
Read of size 4 at addr ffff88852d477380 by task swapper/6/0
CPU: 6 PID: 0 Comm: swapper/6 Not tainted 4.20.0-rc3-00087-gc8ce94b8fe53-dirty #15
Hardware name: DEPO Computers Super Server/X10DRL-i, BIOS 2.0b 05/05/2017
Call Trace:
<IRQ>
dump_stack+0x92/0xeb
print_address_description+0x6a/0x280
kasan_report+0x260/0x380
i40iw_copy_ip_ntohl+0x1c0/0x220
i40iw_net_event+0x150/0x200
notifier_call_chain+0x90/0x160
atomic_notifier_call_chain+0x6c/0x100
neigh_update+0x82f/0x15c0
neigh_event_ns+0x4c/0xe0
arp_process+0x1733/0x1f60
__netif_receive_skb_one_core+0xe6/0x150
netif_receive_skb_internal+0xe5/0x4c0
napi_gro_receive+0x2d1/0x3b0
i40e_clean_rx_irq+0x9a5/0x2eb0
i40e_napi_poll+0x11fd/0x2410
net_rx_action+0x62f/0xbf0
__do_softirq+0x256/0x9de
irq_exit+0x29b/0x2d0
do_IRQ+0x87/0x1a0
common_interrupt+0xf/0xf
Allocated by task 0:
kasan_kmalloc+0xa0/0xd0
__kmalloc+0x177/0x390
__neigh_create+0x1e3/0x1820
neigh_event_ns+0x6b/0xe0
arp_process+0x1733/0x1f60
__netif_receive_skb_one_core+0xe6/0x150
netif_receive_skb_internal+0xe5/0x4c0
napi_gro_receive+0x2d1/0x3b0
i40e_clean_rx_irq+0x9a5/0x2eb0
i40e_napi_poll+0x11fd/0x2410
net_rx_action+0x62f/0xbf0
__do_softirq+0x256/0x9de
Freed by task 0:
(stack is not available)
The buggy address belongs to the object at ffff88852d477080
to the cache kmalloc-1k of size 1024
The buggy address is located 768 bytes inside of 1024-byte region [ffff88852d477080, ffff88852d477480)
The buggy address belongs to the page:
page:ffffea0014b51c00 count:1 mapcount:0 mapping:ffff888107c0ea00 index:0x0 compound_mapcount: 0
flags: 0x17ffffc0010200(slab|head)
raw: 0017ffffc0010200 dead000000000100 dead000000000200 ffff888107c0ea00
raw: 0000000000000000 00000000801c001c 00000001ffffffff 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff88852d477280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff88852d477300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff88852d477380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
^
ffff88852d477400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
ffff88852d477480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
==================================================================
The complain is valid:
i40iw_net_event() reads unconditionally 16 bytes from neigh->primary_key
while the memory allocated for "neighbour" struct is evaluated in neigh_alloc() as
tbl->entry_size + dev->neigh_priv_len
where "dev" is a net_device.
But the driver does not setup dev->neigh_priv_len and we read beyond the neigh
entry allocated memory, so the patch in the next mail fixes this.
More debug details:
crash> list net_device.dev_list -H 0xffffffffa908ec88 -s net_device.name -s net_device.neigh_priv_len
ffff88065a92a200
name = "lo\000\000\000\000\000\000\000\000\000\000\000\000\000"
neigh_priv_len = 0
ffff880642340000
name = "eno1\000\000\071:00.0\000\000\000"
neigh_priv_len = 0
ffff88064aa6a200
name = "enp6s0f0\000\000\000\000\000\000\000"
neigh_priv_len = 0
ffff880641180000
name = "eno2\000\000a:00.0\000\000\000"
neigh_priv_len = 0
ffff88063e8fd500
name = "enp6s0f1\000\000\000\000\000\000\000"
neigh_priv_len = 0
ffff880031400000
name = "ens11f0\000\000\000\000\000\000\000\000"
neigh_priv_len = 0
ffff88063c800000
name = "ens11f1\000\000\000\000\000\000\000\000"
neigh_priv_len = 0
ffff8808ff4ea100
name = "bond0\000\000\000\000\000\000\000\000\000\000"
neigh_priv_len = 0
ffff88101e334400
name = "ib0\000\000\000\000\000\000\000\000\000\000\000\000"
neigh_priv_len = 200
=========================================
crash> list i40iw_handler.list -H i40iw_handlers
ffff88004bbc0000 ldev.netdev == 0xffff88063e8fd500
struct net_device {
name = "enp6s0f1\000\000\000\000\000\000\000",
ffff881049120000 ldev.netdev == 0xffff88064aa6a200
struct net_device {
name = "enp6s0f0\000\000\000\000\000\000\000",
=========================================
net_device allocation stack:
alloc_netdev_mqs
alloc_etherdev_mq
i40e_config_netdev
i40e_vsi_setup
i40e_setup_pf_switch
i40e_probe
=========================================
After the patch:
crash> list net_device.dev_list -H 0xffffffff92a19b48 -s net_device.name -s net_device.neigh_priv_len
ffff88065a2dc400
name = "lo\000\000\000\000\000\000\000\000\000\000\000\000\000"
neigh_priv_len = 0
ffff8808fb6dc200
name = "bond0\000\000\000\000\000\000\000\000\000\000"
neigh_priv_len = 0
ffff880652600000
name = "ens11f0\000\000\000\000\000\000\000\000"
neigh_priv_len = 0
ffff880651a00000
name = "ens11f1\000\000\000\000\000\000\000\000"
neigh_priv_len = 0
ffff880651454000
name = "eno1\000\000\071:00.0\000\000\000"
neigh_priv_len = 0
ffff880651550000
name = "eno2\000\000a:00.0\000\000\000"
neigh_priv_len = 0
ffff8806515cc400
name = "enp6s0f0\000\000\000\000\000\000\000"
neigh_priv_len = 16
ffff880650932200
name = "enp6s0f1\000\000\000\000\000\000\000"
neigh_priv_len = 16
ffff880642903300
name = "ib0\000\000\000\000\000\000\000\000\000\000\000\000"
neigh_priv_len = 200
=========================================
Konstantin Khorenko (1):
drivers/net/i40e: define proper net_device::neigh_priv_len
drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +++
1 file changed, 3 insertions(+)
--
2.15.1
^ permalink raw reply
* Re: [PATCH net-next 2/3] vhost_net: support in order feature
From: Michael S. Tsirkin @ 2018-11-23 15:49 UTC (permalink / raw)
To: Jason Wang; +Cc: kvm, virtualization, netdev, linux-kernel
In-Reply-To: <20181123030016.4924-3-jasowang@redhat.com>
On Fri, Nov 23, 2018 at 11:00:15AM +0800, Jason Wang wrote:
> This makes vhost_net to support in order feature. This is as simple as
> use datacopy path when it was negotiated. An alternative is not to
> advertise in order when zerocopy is enabled which tends to be
> suboptimal consider zerocopy may suffer from e.g HOL issues.
Well IIRC vhost_zerocopy_signal_used is used to
actually reorder used ring to match available ring.
So with a big comment explaining why it is so,
we could just enable IN_ORDER there too.
>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
> drivers/vhost/net.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
> index d919284f103b..bdf5de5a7eb2 100644
> --- a/drivers/vhost/net.c
> +++ b/drivers/vhost/net.c
> @@ -74,7 +74,8 @@ enum {
> VHOST_NET_FEATURES = VHOST_FEATURES |
> (1ULL << VHOST_NET_F_VIRTIO_NET_HDR) |
> (1ULL << VIRTIO_NET_F_MRG_RXBUF) |
> - (1ULL << VIRTIO_F_IOMMU_PLATFORM)
> + (1ULL << VIRTIO_F_IOMMU_PLATFORM) |
> + (1ULL << VIRTIO_F_IN_ORDER)
> };
>
> enum {
> @@ -971,7 +972,8 @@ static void handle_tx(struct vhost_net *net)
> vhost_disable_notify(&net->dev, vq);
> vhost_net_disable_vq(net, vq);
>
> - if (vhost_sock_zcopy(sock))
> + if (vhost_sock_zcopy(sock) &&
> + !vhost_has_feature(vq, VIRTIO_F_IN_ORDER))
> handle_tx_zerocopy(net, sock);
> else
> handle_tx_copy(net, sock);
> --
> 2.17.1
^ permalink raw reply
* Re: [PATCH net-next 3/3] vhost: don't touch avail ring if in_order is negotiated
From: Michael S. Tsirkin @ 2018-11-23 15:41 UTC (permalink / raw)
To: Jason Wang; +Cc: kvm, virtualization, netdev, linux-kernel
In-Reply-To: <20181123030016.4924-4-jasowang@redhat.com>
On Fri, Nov 23, 2018 at 11:00:16AM +0800, Jason Wang wrote:
> Device use descriptors table in order, so there's no need to read
> index from available ring. This eliminate the cache contention on
> avail ring completely.
Well this isn't what the in order feature says in the spec.
It forces the used ring to be in the same order as
the available ring. So I don't think you can skip
checking the available ring. And in fact depending on
ring size and workload, using all of descriptor buffer might
cause a slowdown.
Rather you should be able to get
about the same speedup, but from skipping checking
the used ring in virtio.
> Virito-user + vhost_kernel + XDP_DROP gives about ~10% improvement on
> TX from 4.8Mpps to 5.3Mpps on Intel(R) Core(TM) i7-5600U CPU @
> 2.60GHz.
>
> Signed-off-by: Jason Wang <jasowang@redhat.com>
> ---
> drivers/vhost/vhost.c | 19 ++++++++++++-------
> 1 file changed, 12 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index 3a5f81a66d34..c8be151bc897 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -2002,6 +2002,7 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
> __virtio16 avail_idx;
> __virtio16 ring_head;
> int ret, access;
> + bool in_order = vhost_has_feature(vq, VIRTIO_F_IN_ORDER);
>
> /* Check it isn't doing very strange things with descriptor numbers. */
> last_avail_idx = vq->last_avail_idx;
> @@ -2034,15 +2035,19 @@ int vhost_get_vq_desc(struct vhost_virtqueue *vq,
>
> /* Grab the next descriptor number they're advertising, and increment
> * the index we've seen. */
> - if (unlikely(vhost_get_avail(vq, ring_head,
> - &vq->avail->ring[last_avail_idx & (vq->num - 1)]))) {
> - vq_err(vq, "Failed to read head: idx %d address %p\n",
> - last_avail_idx,
> - &vq->avail->ring[last_avail_idx % vq->num]);
> - return -EFAULT;
> + if (!in_order) {
> + if (unlikely(vhost_get_avail(vq, ring_head,
> + &vq->avail->ring[last_avail_idx & (vq->num - 1)]))) {
> + vq_err(vq, "Failed to read head: idx %d address %p\n",
> + last_avail_idx,
> + &vq->avail->ring[last_avail_idx % vq->num]);
> + return -EFAULT;
> + }
> + head = vhost16_to_cpu(vq, ring_head);
> + } else {
> + head = last_avail_idx & (vq->num - 1);
> }
>
> - head = vhost16_to_cpu(vq, ring_head);
>
> /* If their number is silly, that's an error. */
> if (unlikely(head >= vq->num)) {
> --
> 2.17.1
^ permalink raw reply
* Re: [PATCH net v2] net: phy: mscc: fix deadlock in vsc85xx_default_config
From: Andrew Lunn @ 2018-11-23 15:08 UTC (permalink / raw)
To: Quentin Schulz
Cc: davem, f.fainelli, allan.nielsen, linux-kernel, netdev,
thomas.petazzoni, alexandre.belloni
In-Reply-To: <20181123081636.18795-1-quentin.schulz@bootlin.com>
On Fri, Nov 23, 2018 at 09:16:36AM +0100, Quentin Schulz wrote:
> The vsc85xx_default_config function called in the vsc85xx_config_init
> function which is used by VSC8530, VSC8531, VSC8540 and VSC8541 PHYs
> mistakenly calls phy_read and phy_write in-between phy_select_page and
> phy_restore_page.
>
> phy_select_page and phy_restore_page actually take and release the MDIO
> bus lock and phy_write and phy_read take and release the lock to write
> or read to a PHY register.
>
> Let's fix this deadlock by using phy_modify_paged which handles
> correctly a read followed by a write in a non-standard page.
>
> Fixes: 6a0bfbbe20b0 ("net: phy: mscc: migrate to phy_select/restore_page functions")
>
> Signed-off-by: Quentin Schulz <quentin.schulz@bootlin.com>
> ---
>
> v2:
> - use phy_modify_paged instead of
> phy_select_page -> __phy_read -> __phy_write -> phy_restore_page
>
> drivers/net/phy/mscc.c | 13 ++++++-------
> 1 file changed, 6 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/net/phy/mscc.c b/drivers/net/phy/mscc.c
> index 62269e578718..4dcf7ad06259 100644
> --- a/drivers/net/phy/mscc.c
> +++ b/drivers/net/phy/mscc.c
> @@ -810,17 +810,16 @@ static int vsc85xx_default_config(struct phy_device *phydev)
>
> phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
> mutex_lock(&phydev->lock);
> - rc = phy_select_page(phydev, MSCC_PHY_PAGE_EXTENDED_2);
> +
> + reg_val = RGMII_RX_CLK_DELAY_1_1_NS << RGMII_RX_CLK_DELAY_POS;
> +
> + rc = phy_modify_paged(phydev, MSCC_PHY_PAGE_EXTENDED_2,
> + MSCC_PHY_RGMII_CNTL, RGMII_RX_CLK_DELAY_MASK,
> + reg_val);
> if (rc < 0)
> goto out_unlock;
Hi Quentin
Isn't this goto now pointless. You are not jumping over anything.
Andrew
>
> - reg_val = phy_read(phydev, MSCC_PHY_RGMII_CNTL);
> - reg_val &= ~(RGMII_RX_CLK_DELAY_MASK);
> - reg_val |= (RGMII_RX_CLK_DELAY_1_1_NS << RGMII_RX_CLK_DELAY_POS);
> - phy_write(phydev, MSCC_PHY_RGMII_CNTL, reg_val);
> -
> out_unlock:
> - rc = phy_restore_page(phydev, rc, rc > 0 ? 0 : rc);
> mutex_unlock(&phydev->lock);
>
> return rc;
> --
> 2.17.1
>
^ permalink raw reply
* Re: [PATCH v2 net] phy: Micrel KSZ8061: link failure after cable connect
From: Andrew Lunn @ 2018-11-23 15:00 UTC (permalink / raw)
To: Onnasch, Alexander (EXT)
Cc: Florian Fainelli, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org
In-Reply-To: <1542965762-26822-1-git-send-email-alexander.onnasch@landisgyr.com>
On Fri, Nov 23, 2018 at 09:36:11AM +0000, Onnasch, Alexander (EXT) wrote:
> With Micrel KSZ8061 PHY, the link may occasionally not come up after
> Ethernet cable connect. The vendor's (Microchip, former Micrel) errata
> sheet 80000688A.pdf describes the problem and possible workarounds in
> detail, see below.
> The patch implements workaround 1, which permanently fixes the issue.
>
> DESCRIPTION
> Link-up may not occur properly when the Ethernet cable is initially
> connected. This issue occurs more commonly when the cable is connected
> slowly, but it may occur any time a cable is connected. This issue occurs
> in the auto-negotiation circuit, and will not occur if auto-negotiation
> is disabled (which requires that the two link partners be set to the
> same speed and duplex).
>
> END USER IMPLICATIONS
> When this issue occurs, link is not established. Subsequent cable
> plug/unplug cycles will not correct the issue.
>
> WORK AROUND
> There are four approaches to work around this issue:
> 1. This issue can be prevented by setting bit 15 in MMD device address 1,
> register 2, prior to connecting the cable or prior to setting the
> Restart Auto-Negotiation bit in register 0h.The MMD registers are
> accessed via the indirect access registers Dh and Eh, or via the Micrel
> EthUtil utility as shown here:
> • If using the EthUtil utility (usually with a Micrel KSZ8061
> Evaluation Board), type the following commands:
> > address 1
> > mmd 1
> > iw 2 b61a
> • Alternatively, write the following registers to write to the
> indirect MMD register:
> Write register Dh, data 0001h
> Write register Eh, data 0002h
> Write register Dh, data 4001h
> Write register Eh, data B61Ah
> 2. The issue can be avoided by disabling auto-negotiation in the KSZ8061,
> either by the strapping option, or by clearing bit 12 in register 0h.
> Care must be taken to ensure that the KSZ8061 and the link partner
> will link with the same speed and duplex. Note that the KSZ8061
> defaults to full-duplex when auto-negotiation is off, but other
> devices may default to half-duplex in the event of failed
> auto-negotiation.
> 3. The issue can be avoided by connecting the cable prior to powering-up
> or resetting the KSZ8061, and leaving it plugged in thereafter.
> 4. If the above measures are not taken and the problem occurs, link can
> be recovered by setting the Restart Auto-Negotiation bit in
> register 0h, or by resetting or power cycling the device. Reset may
> be either hardware reset or software reset (register 0h, bit 15).
>
> PLAN
> This errata will not be corrected in a future revision.
>
> Signed-off-by: Alexander Onnasch <alexander.onnasch@landisgyr.com>
> Reviewed-by: Andrew Lunn <andrew@lunn.ch>
> ---
Hi Alexander
Thanks for correctly formatting the commit message, etc.
Fixes: 7ab59dc15e2f ("drivers/net/phy/micrel_phy: Add support for new PHYs")
Andrew
^ permalink raw reply
* [PATCH net-next 1/3] virtio: introduce in order feature bit
From: Jason Wang @ 2018-11-23 3:00 UTC (permalink / raw)
To: mst, jasowang, kvm, virtualization, netdev, linux-kernel
In-Reply-To: <20181123030016.4924-1-jasowang@redhat.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
include/uapi/linux/virtio_config.h | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/include/uapi/linux/virtio_config.h b/include/uapi/linux/virtio_config.h
index 449132c76b1c..64496afc016d 100644
--- a/include/uapi/linux/virtio_config.h
+++ b/include/uapi/linux/virtio_config.h
@@ -75,6 +75,12 @@
*/
#define VIRTIO_F_IOMMU_PLATFORM 33
+/*
+ * Device uses buffers in the same order in which they have been
+ * available.
+ */
+#define VIRTIO_F_IN_ORDER 35
+
/*
* Does the device support Single Root I/O Virtualization?
*/
--
2.17.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox