Skip to contentSkip to conversation

batctl: netlink restructuring, part 3

RFC Superseded Sven Eckelmann 1 participant 5 messages Nov 24, 2018

v3 of 5 Superseded Latest is v5 →

lore
Share & tools
lore
#0 lore raw

v3 cover batctl: netlink restructuring, part 3

As mentioned earlier, the netlink config restructuring in batctl will be splitted in multiple steps. The first step was already merged and the RFC changes for the netlink interface in batman-adv were just posted.

The batman-adv weren't directly rejected by Jiro and thus I've started to convert all settings to netlink while still allowing sysfs as fallback.

v3:
* fix kernel-doc in batman_adv.h
* add three patches to use the netlink interface with the already existing setting commands
v2:
* drop of generic config command
* reimplementation of the event command

Sven Eckelmann (4):
batctl: Add support for config mcast group in event monitor
batctl: Don't allocate new buffer for vlan parent device
batctl: Automatically translate vlan to mesh_iface
batctl: Use netlink as new configuration interface

 aggregation.c           |  45 ++++-
 ap_isolation.c          |  67 ++++++-
 batman_adv.h            | 188 +++++++++++++++++-
 bonding.c               |  45 ++++-
 bridge_loop_avoidance.c |  46 ++++-
 distributed_arp_table.c |  46 ++++-
 event.c                 | 234 ++++++++++++++++++++++
 fragmentation.c         |  45 ++++-
 functions.c             | 160 +++++++++++++---
 functions.h             |  24 ++-
 gateways.c              |  10 +-
 gw_mode.c               | 415 +++++++++++++++++++++++++++++++---------
 isolation_mark.c        | 123 +++++++++++-
 loglevel.c              | 138 ++++++++++---
 main.c                  |  10 +-
 main.h                  |   6 +-
 mcast_flags.c           |  10 +-
 multicast_mode.c        |  45 ++++-
 netlink.c               | 108 ++++++++++-
 netlink.h               |   2 +
 network_coding.c        |  45 ++++-
 orig_interval.c         |  84 +++++++-
 originators.c           |  10 +-
 routing_algo.c          |   1 -
 sys.c                   | 220 ++++++++++++++++-----
 sys.h                   |  26 ++-
 26 files changed, 1897 insertions(+), 256 deletions(-)
Signature · 1 line
2.19.1
#1 lore raw

RFC v3 1/4 batctl: Add support for config mcast group in event monitor

The netlink set netlink messages issued by the config subcommands get as reply a multicast message with the new value. The event monitor should show these messages similar to the tp_meter results.

---
 batman_adv.h | 188 +++++++++++++++++++++++++++++++++++++++--
 event.c      | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++
 netlink.c    |  20 +++++
 3 files changed, 437 insertions(+), 5 deletions(-)
batman_adv.h +183 -5
index 324a0e1..b5a245e 100644
@@ -27,6 +27,7 @@
 
 #define BATADV_NL_NAME "batadv"
 
+#define BATADV_NL_MCAST_GROUP_CONFIG	"config"
 #define BATADV_NL_MCAST_GROUP_TPMETER	"tpmeter"
 
 /**
@@ -138,6 +139,20 @@ enum batadv_mcast_flags_priv {
 	BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING	= (1 << 4),
 };
 
+/**
+ * enum batadv_gw_modes - gateway mode of node
+ */
+enum batadv_gw_modes {
+	/** @BATADV_GW_MODE_OFF: gw mode disabled */
+	BATADV_GW_MODE_OFF,
+
+	/** @BATADV_GW_MODE_CLIENT: send DHCP requests to gw servers */
+	BATADV_GW_MODE_CLIENT,
+
+	/** @BATADV_GW_MODE_SERVER: announce itself as gatway server */
+	BATADV_GW_MODE_SERVER,
+};
+
 /**
  * enum batadv_nl_attrs - batman-adv netlink attributes
  */
@@ -344,6 +359,136 @@ enum batadv_nl_attrs {
 	 */
 	BATADV_ATTR_MCAST_FLAGS_PRIV,
 
+	/**
+	 * @BATADV_ATTR_VLANID: VLAN id on top of soft interface
+	 */
+	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,
+
+	/**
+	 * @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,
+
+	/**
+	 * @BATADV_ATTR_BONDING: whether the data traffic going through the
+	 *  mesh will be sent using multiple interfaces at the same time.
+	 */
+	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,
+
+	/**
+	 * @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,
+
+	/**
+	 * @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,
+
+	/**
+	 * @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,
+
+	/**
+	 * @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,
+
+	/**
+	 * @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,
+
+	/**
+	 * @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,
+
+	/**
+	 * @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,
+
+	/**
+	 * @BATADV_ATTR_ORIG_INTERVAL: defines the interval in milliseconds in
+	 *  which batman sends its protocol messages.
+	 */
+	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,
+
+	/**
+	 * @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 */
 
 	/**
@@ -372,10 +517,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,
+
+	/**
+	 * @BATADV_CMD_GET_MESH_INFO: Alias for @BATADV_CMD_GET_MESH
 	 */
-	BATADV_CMD_GET_MESH_INFO,
+	BATADV_CMD_GET_MESH_INFO = BATADV_CMD_GET_MESH,
 
 	/**
 	 * @BATADV_CMD_TP_METER: Start a tp meter session
@@ -393,9 +542,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
@@ -443,6 +598,29 @@ enum batadv_nl_commands {
 	 */
 	BATADV_CMD_GET_MCAST_FLAGS,
 
+	/**
+	 * @BATADV_CMD_SET_MESH: Set attributes for softif/mesh
+	 */
+	BATADV_CMD_SET_MESH,
+
+	/**
+	 * @BATADV_CMD_SET_HARDIF: Set attributes for hardif of the
+	 *  current softif
+	 */
+	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 */
 
 	/**
event.c +234 -0

264 lines not on this page · raw message

netlink.c +20 -0
index 5285759..1829544 100644
@@ -107,6 +107,26 @@ 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 },
+	[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 },
+	[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 },
+	[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 },
+	[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 },
+	[BATADV_ATTR_ORIG_INTERVAL]		= { .type = NLA_U32 },
+	[BATADV_ATTR_ELP_INTERVAL]		= { .type = NLA_U32 },
+	[BATADV_ATTR_THROUGHPUT_OVERRIDE]	= { .type = NLA_U32 },
 };
 
 int netlink_create(struct state *state)
Signature · 1 line
2.19.1
#2 lore raw

RFC v3 2/4 batctl: Don't allocate new buffer for vlan parent device

In reply to Sven Eckelmann

The buffer size is limited by IF_NAMESIZE and can easily be stored on the stack. This will also make it easier to store this as part of the the state of batctl.

---
 functions.c | 23 ++++++-----------------
 functions.h |  2 +-
 sys.c       |  6 +++---
 3 files changed, 10 insertions(+), 21 deletions(-)
functions.c +6 -17
index bdede8b..ecfd202 100644
@@ -830,10 +830,6 @@ static int vlan_get_link_parse(struct nl_msg *msg, void *arg)
 
 	/* get parent link name */
 	idx = *(int *)nla_data(tb[IFLA_LINK]);
-	free(nl_arg->iface);
-	nl_arg->iface = malloc(IFNAMSIZ + 1);
-	if (!nl_arg->iface)
-		goto err;
 
 	if (!if_indextoname(idx, nl_arg->iface))
 		goto err;
@@ -851,12 +847,12 @@ static int vlan_get_link_parse(struct nl_msg *msg, void *arg)
 /**
  * vlan_get_link - convert a VLAN interface into its parent one
  * @ifname: the interface to convert
- * @parent: buffer where the parent interface name will be written (allocated by
- *  this function)
+ * @parent: buffer where the parent interface name will be written
+ *  (minimum IF_NAMESIZE)
  *
  * Returns the vlan identifier on success or -1 on error
  */
-int vlan_get_link(const char *ifname, char **parent)
+int vlan_get_link(const char *ifname, char *parent)
 {
 	struct nl_sock *sock;
 	int ret;
@@ -866,12 +862,10 @@ int vlan_get_link(const char *ifname, char **parent)
 	};
 	struct nl_cb *cb = NULL;
 	struct vlan_get_link_nl_arg arg = {
-		.iface = NULL,
+		.iface = parent,
 		.vid = -1,
 	};
 
-	*parent = NULL;
-
 	sock = nl_socket_alloc();
 	if (!sock)
 		goto err;
@@ -894,8 +888,6 @@ int vlan_get_link(const char *ifname, char **parent)
 	if (ret < 0)
 		goto err;
 
-	*parent = arg.iface;
-
 err:
 	if (cb)
 		nl_cb_put(cb);
@@ -1029,13 +1021,13 @@ int netlink_simple_request(struct nl_msg *msg)
 
 int check_mesh_iface(char *mesh_iface)
 {
-	char *base_dev = NULL;
 	char path_buff[PATH_BUFF_LEN];
+	char base_dev[IF_NAMESIZE];
 	int ret = -1, vid;
 	DIR *dir;
 
 	/* use the parent interface if this is a VLAN */
-	vid = vlan_get_link(mesh_iface, &base_dev);
+	vid = vlan_get_link(mesh_iface, base_dev);
 	if (vid >= 0)
 		snprintf(path_buff, PATH_BUFF_LEN, SYS_VLAN_PATH, base_dev, vid);
 	else
@@ -1050,9 +1042,6 @@ int check_mesh_iface(char *mesh_iface)
 
 	ret = 0;
 out:
-	if (base_dev)
-		free(base_dev);
-
 	return ret;
 }
 
functions.h +1 -1
index c16ba2e..2680e6d 100644
@@ -48,7 +48,7 @@ int write_file(const char *dir, const char *fname, const char *arg1,
 struct ether_addr *translate_mac(const char *mesh_iface,
 				 const struct ether_addr *mac);
 struct ether_addr *resolve_mac(const char *asc);
-int vlan_get_link(const char *ifname, char **parent);\
+int vlan_get_link(const char *ifname, char *parent);
 int query_rtnl_link(int ifindex, nl_recvmsg_msg_cb_t func, void *arg);
 int netlink_simple_request(struct nl_msg *msg);
 int check_mesh_iface(char *mesh_iface);
sys.c +3 -3
index 6b98ac4..5c54f08 100644
@@ -67,7 +67,8 @@ int handle_sys_setting(struct state *state, int argc, char **argv)
 {
 	struct settings_data *settings = state->cmd->arg;
 	int vid, optchar, res = EXIT_FAILURE;
-	char *path_buff, *base_dev = NULL;
+	char base_dev[IF_NAMESIZE];
+	char *path_buff;
 	const char **ptr;
 
 	while ((optchar = getopt(argc, argv, "h")) != -1) {
@@ -93,7 +94,7 @@ int handle_sys_setting(struct state *state, int argc, char **argv)
 	/* if the specified interface is a VLAN then change the path to point
 	 * to the proper "vlan%{vid}" subfolder in the sysfs tree.
 	 */
-	vid = vlan_get_link(state->mesh_iface, &base_dev);
+	vid = vlan_get_link(state->mesh_iface, base_dev);
 	if (vid >= 0)
 		snprintf(path_buff, PATH_BUFF_LEN, SYS_VLAN_PATH, base_dev, vid);
 
@@ -133,6 +134,5 @@ int handle_sys_setting(struct state *state, int argc, char **argv)
 
 out:
 	free(path_buff);
-	free(base_dev);
 	return res;
 }
Signature · 1 line
2.19.1
#3 lore raw

RFC v3 3/4 batctl: Automatically translate vlan to mesh_iface

In reply to Sven Eckelmann

The way batctl is implementing support for VLANs is rather suboptimal. The program has to guess whether it is started with an batadv or vlan interface as argument.

Instead of distributing this over the whole program, do it on startup and already retrieve the required mesh interface index and vid before the rest of the program runs.

---
 functions.c   | 34 ++++++++++++++++++++++++++--------
 functions.h   |  6 ++++--
 gateways.c    | 10 ++--------
 main.c        | 10 ++++++----
 main.h        |  6 +++++-
 mcast_flags.c | 10 ++--------
 netlink.c     | 12 ++----------
 originators.c | 10 ++--------
 sys.c         | 14 +++++++-------
 9 files changed, 56 insertions(+), 56 deletions(-)
functions.c +26 -8
index ecfd202..600c29a 100644
@@ -852,7 +852,7 @@ static int vlan_get_link_parse(struct nl_msg *msg, void *arg)
  *
  * Returns the vlan identifier on success or -1 on error
  */
-int vlan_get_link(const char *ifname, char *parent)
+static int vlan_get_link(const char *ifname, char *parent)
 {
 	struct nl_sock *sock;
 	int ret;
@@ -1019,19 +1019,33 @@ int netlink_simple_request(struct nl_msg *msg)
 	return err;
 }
 
-int check_mesh_iface(char *mesh_iface)
+int translate_mesh_iface(struct state *state)
+{
+	state->vid = vlan_get_link(state->arg_iface, state->mesh_iface);
+	if (state->vid < 0) {
+		/* if there is no iface then the argument must be the
+		 * mesh interface
+		 */
+		snprintf(state->mesh_iface, sizeof(state->mesh_iface), "%s",
+			 state->arg_iface);
+	}
+
+	return 0;
+}
+
+int check_mesh_iface(struct state *state)
 {
 	char path_buff[PATH_BUFF_LEN];
-	char base_dev[IF_NAMESIZE];
-	int ret = -1, vid;
+	int ret = -1;
 	DIR *dir;
 
 	/* use the parent interface if this is a VLAN */
-	vid = vlan_get_link(mesh_iface, base_dev);
-	if (vid >= 0)
-		snprintf(path_buff, PATH_BUFF_LEN, SYS_VLAN_PATH, base_dev, vid);
+	if (state->vid >= 0)
+		snprintf(path_buff, PATH_BUFF_LEN, SYS_VLAN_PATH,
+			 state->mesh_iface, state->vid);
 	else
-		snprintf(path_buff, PATH_BUFF_LEN, SYS_BATIF_PATH_FMT, mesh_iface);
+		snprintf(path_buff, PATH_BUFF_LEN, SYS_BATIF_PATH_FMT,
+			 state->mesh_iface);
 
 	/* try to open the mesh sys directory */
 	dir = opendir(path_buff);
@@ -1040,6 +1054,10 @@ int check_mesh_iface(char *mesh_iface)
 
 	closedir(dir);
 
+	state->mesh_ifindex = if_nametoindex(state->mesh_iface);
+	if (state->mesh_ifindex == 0)
+		goto out;
+
 	ret = 0;
 out:
 	return ret;
functions.h +4 -2
index 2680e6d..ea3c307 100644
@@ -34,6 +34,8 @@
 
 #define PATH_BUFF_LEN 400
 
+struct state;
+
 /* return time delta from start to end in milliseconds */
 void start_timer(void);
 double end_timer(void);
@@ -48,10 +50,10 @@ int write_file(const char *dir, const char *fname, const char *arg1,
 struct ether_addr *translate_mac(const char *mesh_iface,
 				 const struct ether_addr *mac);
 struct ether_addr *resolve_mac(const char *asc);
-int vlan_get_link(const char *ifname, char *parent);
 int query_rtnl_link(int ifindex, nl_recvmsg_msg_cb_t func, void *arg);
 int netlink_simple_request(struct nl_msg *msg);
-int check_mesh_iface(char *mesh_iface);
+int translate_mesh_iface(struct state *state);
+int check_mesh_iface(struct state *state);
 int check_mesh_iface_ownership(char *mesh_iface, char *hard_iface);
 
 void get_random_bytes(void *buf, size_t buflen);
gateways.c +2 -8
index ff7693f..5beddc7 100644
@@ -133,17 +133,11 @@ static int netlink_print_gateways(struct state *state, char *orig_iface,
 {
 	char *header = NULL;
 	char *info_header;
-	int ifindex;
-
-	ifindex = if_nametoindex(state->mesh_iface);
-	if (!ifindex) {
-		fprintf(stderr, "Interface %s is unknown\n", state->mesh_iface);
-		return -ENODEV;
-	}
 
 	/* only parse routing algorithm name */
 	last_err = -EINVAL;
-	info_header = netlink_get_info(ifindex, BATADV_CMD_GET_ORIGINATORS, NULL);
+	info_header = netlink_get_info(state->mesh_ifindex,
+				       BATADV_CMD_GET_ORIGINATORS, NULL);
 	free(info_header);
 
 	if (strlen(algo_name_buf) == 0)
main.c +6 -4
index ab7da45..37a2b5a 100644
@@ -125,7 +125,7 @@ int main(int argc, char **argv)
 {
 	const struct command *cmd;
 	struct state state = {
-		.mesh_iface = mesh_dfl_iface,
+		.arg_iface = mesh_dfl_iface,
 		.cmd = NULL,
 	};
 	int opt;
@@ -138,13 +138,13 @@ int main(int argc, char **argv)
 			exit(EXIT_SUCCESS);
 			break;
 		case 'm':
-			if (state.mesh_iface != mesh_dfl_iface) {
+			if (state.arg_iface != mesh_dfl_iface) {
 				fprintf(stderr,
 					"Error - multiple mesh interfaces specified\n");
 				goto err;
 			}
 
-			state.mesh_iface = argv[2];
+			state.arg_iface = argv[2];
 			break;
 		case 'v':
 			version();
@@ -173,8 +173,10 @@ int main(int argc, char **argv)
 
 	state.cmd = cmd;
 
+	translate_mesh_iface(&state);
+
 	if (cmd->flags & COMMAND_FLAG_MESH_IFACE &&
-	    check_mesh_iface(state.mesh_iface) < 0) {
+	    check_mesh_iface(&state) < 0) {
 		fprintf(stderr,
 			"Error - interface %s is not present or not a batman-adv interface\n",
 			state.mesh_iface);
main.h +5 -1
index 276a018..274fae5 100644
@@ -25,6 +25,7 @@
 
 #include <stdint.h>
 
+#include <net/if.h>
 #include <netlink/genl/ctrl.h>
 #include <netlink/genl/genl.h>
 #include <netlink/netlink.h>
@@ -74,7 +75,10 @@ enum command_type {
 };
 
 struct state {
-	char *mesh_iface;
+	char *arg_iface;
+	char mesh_iface[IF_NAMESIZE];
+	unsigned int mesh_ifindex;
+	int vid;
 	const struct command *cmd;
 
 	struct nl_sock *sock;
mcast_flags.c +2 -8
index 0dc4227..eb9734e 100644
@@ -113,17 +113,11 @@ static int netlink_print_mcast_flags(struct state *state, char *orig_iface,
 	char *info_header;
 	char *header;
 	bool bridged;
-	int ifindex;
 	int ret;
 
-	ifindex = if_nametoindex(state->mesh_iface);
-	if (!ifindex) {
-		fprintf(stderr, "Interface %s is unknown\n", state->mesh_iface);
-		return -ENODEV;
-	}
-
 	/* only parse own multicast flags */
-	info_header = netlink_get_info(ifindex, BATADV_CMD_GET_MCAST_FLAGS, NULL);
+	info_header = netlink_get_info(state->mesh_ifindex,
+				       BATADV_CMD_GET_MCAST_FLAGS, NULL);
 	free(info_header);
 
 	if (mcast_flags == -EOPNOTSUPP || mcast_flags_priv == -EOPNOTSUPP)
netlink.c +2 -10
index 1829544..b0d57b1 100644
@@ -443,20 +443,12 @@ int netlink_print_common(struct state *state, char *orig_iface, int read_opt,
 	};
 	int hardifindex = 0;
 	struct nl_msg *msg;
-	int ifindex;
 
 	if (!state->sock) {
 		last_err = -EOPNOTSUPP;
 		return last_err;
 	}
 
-	ifindex = if_nametoindex(state->mesh_iface);
-	if (!ifindex) {
-		fprintf(stderr, "Interface %s is unknown\n", state->mesh_iface);
-		last_err = -ENODEV;
-		return last_err;
-	}
-
 	if (orig_iface) {
 		hardifindex = if_nametoindex(orig_iface);
 		if (!hardifindex) {
@@ -479,7 +471,7 @@ int netlink_print_common(struct state *state, char *orig_iface, int read_opt,
 			printf("\033[2J\033[0;0f");
 
 		if (!(read_opt & SKIP_HEADER))
-			opts.remaining_header = netlink_get_info(ifindex,
+			opts.remaining_header = netlink_get_info(state->mesh_ifindex,
 								 nl_cmd,
 								 header);
 
@@ -490,7 +482,7 @@ int netlink_print_common(struct state *state, char *orig_iface, int read_opt,
 		genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, state->batadv_family,
 			    0, NLM_F_DUMP, nl_cmd, 1);
 
-		nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, ifindex);
+		nla_put_u32(msg, BATADV_ATTR_MESH_IFINDEX, state->mesh_ifindex);
 		if (hardifindex)
 			nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX,
 				    hardifindex);
originators.c +2 -8
index c29300a..3c13c66 100644
@@ -185,17 +185,11 @@ static int netlink_print_originators(struct state *state, char *orig_iface,
 {
 	char *header = NULL;
 	char *info_header;
-	int ifindex;
-
-	ifindex = if_nametoindex(state->mesh_iface);
-	if (!ifindex) {
-		fprintf(stderr, "Interface %s is unknown\n", state->mesh_iface);
-		return -ENODEV;
-	}
 
 	/* only parse routing algorithm name */
 	last_err = -EINVAL;
-	info_header = netlink_get_info(ifindex, BATADV_CMD_GET_ORIGINATORS, NULL);
+	info_header = netlink_get_info(state->mesh_ifindex,
+				       BATADV_CMD_GET_ORIGINATORS, NULL);
 	free(info_header);
 
 	if (strlen(algo_name_buf) == 0)
sys.c +7 -7
index 5c54f08..be20be7 100644
@@ -66,8 +66,7 @@ static void settings_usage(struct state *state)
 int handle_sys_setting(struct state *state, int argc, char **argv)
 {
 	struct settings_data *settings = state->cmd->arg;
-	int vid, optchar, res = EXIT_FAILURE;
-	char base_dev[IF_NAMESIZE];
+	int optchar, res = EXIT_FAILURE;
 	char *path_buff;
 	const char **ptr;
 
@@ -89,14 +88,15 @@ int handle_sys_setting(struct state *state, int argc, char **argv)
 		return EXIT_FAILURE;
 	}
 
-	snprintf(path_buff, PATH_BUFF_LEN, SYS_BATIF_PATH_FMT, state->mesh_iface);
-
 	/* if the specified interface is a VLAN then change the path to point
 	 * to the proper "vlan%{vid}" subfolder in the sysfs tree.
 	 */
-	vid = vlan_get_link(state->mesh_iface, base_dev);
-	if (vid >= 0)
-		snprintf(path_buff, PATH_BUFF_LEN, SYS_VLAN_PATH, base_dev, vid);
+	if (state->vid >= 0)
+		snprintf(path_buff, PATH_BUFF_LEN, SYS_VLAN_PATH,
+			 state->mesh_iface, state->vid);
+	else
+		snprintf(path_buff, PATH_BUFF_LEN, SYS_BATIF_PATH_FMT,
+			 state->mesh_iface);
 
 	if (argc == 1) {
 		res = read_file(path_buff, settings->sysfs_name,
Signature · 1 line
2.19.1
#4 lore raw

RFC v3 4/4 batctl: Use netlink as new configuration interface

In reply to Sven Eckelmann

sysfs should be avoided for new settings of network interfaces. To still provide a common configuration infrastructure, all the existing settings subcommands were also reimplemented via generic netlink.

To still support older batman-adv versions, the old sysfs infrastructure is still used in case that the generic netlink command returned an error.

---
 aggregation.c           |  45 ++++-
 ap_isolation.c          |  67 ++++++-
 bonding.c               |  45 ++++-
 bridge_loop_avoidance.c |  46 ++++-
 distributed_arp_table.c |  46 ++++-
 fragmentation.c         |  45 ++++-
 functions.c             | 109 +++++++++++
 functions.h             |  18 ++
 gw_mode.c               | 415 +++++++++++++++++++++++++++++++---------
 isolation_mark.c        | 123 +++++++++++-
 loglevel.c              | 138 ++++++++++---
 multicast_mode.c        |  45 ++++-
 netlink.c               |  76 ++++++++
 netlink.h               |   2 +
 network_coding.c        |  45 ++++-
 orig_interval.c         |  84 +++++++-
 routing_algo.c          |   1 -
 sys.c                   | 204 ++++++++++++++++----
 sys.h                   |  26 ++-
 19 files changed, 1400 insertions(+), 180 deletions(-)
aggregation.c +43 -2
index 57c1dbb..673e0ca 100644
@@ -21,13 +21,54 @@
  */
 
 #include "main.h"
+
+#include <errno.h>
+#include <linux/genetlink.h>
+#include <netlink/genl/genl.h>
+
+#include "batman_adv.h"
+#include "netlink.h"
 #include "sys.h"
 
+static struct simple_boolean_data aggregated_ogms;
+
+static int print_aggregated_ogms(struct nl_msg *msg, void *arg)
+{
+	return sys_simple_print_boolean(msg, arg, BATADV_ATTR_AGGREGATED_OGMS);
+}
+
+static int get_aggregated_ogms(struct state *state)
+{
+	return sys_simple_nlquery(state, BATADV_CMD_GET_MESH,
+				  NULL, print_aggregated_ogms);
+}
+
+static int set_attrs_aggregated_ogms(struct nl_msg *msg, void *arg)
+{
+	struct state *state = arg;
+	struct settings_data *settings = state->cmd->arg;
+	struct simple_boolean_data *data = settings->data;
+
+	nla_put_u8(msg, BATADV_ATTR_AGGREGATED_OGMS, data->val);
+
+	return 0;
+}
+
+static int set_aggregated_ogms(struct state *state)
+{
+	return sys_simple_nlquery(state, BATADV_CMD_SET_MESH,
+				  set_attrs_aggregated_ogms, NULL);
+}
+
 static struct settings_data batctl_settings_aggregation = {
 	.sysfs_name = "aggregated_ogms",
-	.params = sysfs_param_enable,
+	.data = &aggregated_ogms,
+	.parse = parse_simple_boolean,
+	.netlink_get = get_aggregated_ogms,
+	.netlink_set = set_aggregated_ogms,
 };
 
 COMMAND_NAMED(SUBCOMMAND, aggregation, "ag", handle_sys_setting,
-	      COMMAND_FLAG_MESH_IFACE, &batctl_settings_aggregation,
+	      COMMAND_FLAG_MESH_IFACE| COMMAND_FLAG_NETLINK,
+	      &batctl_settings_aggregation,
 	      "[0|1]             \tdisplay or modify aggregation setting");
ap_isolation.c +65 -2

78 lines not on this page · raw message

bonding.c +43 -2

56 lines not on this page · raw message

bridge_loop_avoidance.c +44 -2

57 lines not on this page · raw message

distributed_arp_table.c +44 -2

57 lines not on this page · raw message

fragmentation.c +43 -2

56 lines not on this page · raw message

functions.c +109 -0

118 lines not on this page · raw message

functions.h +18 -0
index ea3c307..0331c8b 100644
@@ -26,9 +26,22 @@
 #include <net/ethernet.h>
 #include <netlink/netlink.h>
 #include <netlink/handlers.h>
+#include <stdbool.h>
 #include <stddef.h>
+#include <stdint.h>
 
 
+/**
+ * enum batadv_bandwidth_units - bandwidth unit types
+ */
+enum batadv_bandwidth_units {
+	/** @BATADV_BW_UNIT_KBIT: unit type kbit */
+	BATADV_BW_UNIT_KBIT,
+
+	/** @BATADV_BW_UNIT_MBIT: unit type mbit */
+	BATADV_BW_UNIT_MBIT,
+};
+
 #define ETH_STR_LEN 17
 #define BATMAN_ADV_TAG "batman-adv:"
 
@@ -53,12 +66,17 @@ struct ether_addr *resolve_mac(const char *asc);
 int query_rtnl_link(int ifindex, nl_recvmsg_msg_cb_t func, void *arg);
 int netlink_simple_request(struct nl_msg *msg);
 int translate_mesh_iface(struct state *state);
+int get_algoname(const char *mesh_iface, char *algoname, size_t algoname_len);
 int check_mesh_iface(struct state *state);
 int check_mesh_iface_ownership(char *mesh_iface, char *hard_iface);
 
 void get_random_bytes(void *buf, size_t buflen);
 void check_root_or_die(const char *cmd);
 
+int parse_bool(const char *val, bool *res);
+bool parse_throughput(char *buff, const char *description,
+		      uint32_t *throughput);
+
 extern char *line_ptr;
 
 enum {
gw_mode.c +327 -88

477 lines not on this page · raw message

isolation_mark.c +121 -2

137 lines not on this page · raw message

loglevel.c +110 -28

205 lines not on this page · raw message

multicast_mode.c +43 -2

56 lines not on this page · raw message

netlink.c +76 -0

79 lines not on this page · raw message

netlink.h +2 -0
index b91ca10..9be49cd 100644
@@ -50,6 +50,8 @@ int translate_mac_netlink(const char *mesh_iface, const struct ether_addr *mac,
 int get_nexthop_netlink(const char *mesh_iface, const struct ether_addr *mac,
 			uint8_t *nexthop, char *ifname);
 int get_primarymac_netlink(const char *mesh_iface, uint8_t *primarymac);
+int get_algoname_netlink(const char *mesh_iface, char *algoname,
+			 size_t algoname_len);
 
 extern struct nla_policy batadv_netlink_policy[];
 
network_coding.c +43 -2

56 lines not on this page · raw message

orig_interval.c +82 -2

98 lines not on this page · raw message

routing_algo.c +0 -1
index 18d9ef7..69eac34 100644
@@ -41,7 +41,6 @@
 #include "sys.h"
 
 #define SYS_SELECTED_RA_PATH	"/sys/module/batman_adv/parameters/routing_algo"
-#define SYS_ROUTING_ALGO_FMT	SYS_IFACE_PATH"/%s/mesh/routing_algo"
 
 static void ra_mode_usage(void)
 {
sys.c +164 -40

234 lines not on this page · raw message

sys.h +23 -3
index 20e1934..2eaa8be 100644
@@ -25,6 +25,13 @@
 
 #include "main.h"
 
+#include <linux/genetlink.h>
+#include <netlink/genl/genl.h>
+#include <stdbool.h>
+
+#include "batman_adv.h"
+#include "netlink.h"
+
 #define SYS_BATIF_PATH_FMT	"/sys/class/net/%s/mesh/"
 #define SYS_LOG_LEVEL		"log_level"
 #define SYS_LOG			"log"
@@ -37,16 +44,29 @@
 #define SYS_MESH_IFACE_FMT	SYS_IFACE_PATH"/%s/batman_adv/mesh_iface"
 #define SYS_IFACE_STATUS_FMT	SYS_IFACE_PATH"/%s/batman_adv/iface_status"
 #define SYS_VLAN_PATH		SYS_IFACE_PATH"/%s/mesh/vlan%d/"
+#define SYS_ROUTING_ALGO_FMT	SYS_IFACE_PATH"/%s/mesh/routing_algo"
 #define VLAN_ID_MAX_LEN		4
 
 struct settings_data {
 	const char *sysfs_name;
-	const char **params;
+	void *data;
+	int (*parse)(struct state *state, int argc, char *argv[]);
+	int (*netlink_get)(struct state *state);
+	int (*netlink_set)(struct state *state);
 };
 
-extern const char *sysfs_param_enable[];
-extern const char *sysfs_param_server[];
+struct simple_boolean_data {
+	bool val;
+};
 
 int handle_sys_setting(struct state *state, int argc, char **argv);
+int parse_simple_boolean(struct state *state, int argc, char *argv[]);
+
+
+int sys_simple_nlquery(struct state *state, enum batadv_nl_commands nl_cmd,
+		       nl_recvmsg_msg_cb_t attribute_cb,
+		       nl_recvmsg_msg_cb_t callback);
+int sys_simple_print_boolean(struct nl_msg *msg, void *arg,
+			     enum batadv_nl_attrs attr);
 
 #endif
Signature · 1 line
2.19.1