223 lines
6.5 KiB
Diff
223 lines
6.5 KiB
Diff
From: Sven Eckelmann <sven@narfation.org>
|
|
Date: Tue, 9 Jul 2019 19:26:47 +0200
|
|
Subject: batctl: Integrate hardif setting framework
|
|
|
|
batctl currently supports settings which are either mesh interface or vlan
|
|
specific. But B.A.T.M.A.N. V introduced two additional settings which are
|
|
hard (slave) interface specific.
|
|
|
|
To support these, an additional command prefix called hardif is implemented
|
|
for some sysfs commands:
|
|
|
|
$ batctl hardif eth0 ...
|
|
|
|
Signed-off-by: Sven Eckelmann <sven@narfation.org>
|
|
|
|
Origin: upstream, https://git.open-mesh.org/batctl.git/commit/6ed4dfc5459fd3b9ed221308075db592e538c92f
|
|
|
|
diff --git a/functions.c b/functions.c
|
|
index 61ea4879ebffbdadf8ef5bb12bb737c1ed7ff76f..4ffa86ca7830dea3ed2599656831b56f6fec9e33 100644
|
|
--- a/functions.c
|
|
+++ b/functions.c
|
|
@@ -998,6 +998,28 @@ int translate_vid(struct state *state, const char *vidstr)
|
|
return 0;
|
|
}
|
|
|
|
+int translate_hard_iface(struct state *state, const char *hardif)
|
|
+{
|
|
+ struct rtnl_link_iface_data link_data;
|
|
+ unsigned int arg_ifindex;
|
|
+
|
|
+ arg_ifindex = if_nametoindex(hardif);
|
|
+ if (arg_ifindex == 0)
|
|
+ return -ENODEV;
|
|
+
|
|
+ query_rtnl_link_single(arg_ifindex, &link_data);
|
|
+ if (!link_data.master_found)
|
|
+ return -ENOLINK;
|
|
+
|
|
+ if (!if_indextoname(link_data.master, state->mesh_iface))
|
|
+ return -ENOLINK;
|
|
+
|
|
+ state->hif = arg_ifindex;
|
|
+ state->selector = SP_HARDIF;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static int check_mesh_iface_netlink(struct state *state)
|
|
{
|
|
struct rtnl_link_iface_data link_data;
|
|
diff --git a/functions.h b/functions.h
|
|
index 7474c40bbcdcb8fac8865def2e82514aede62b69..0a08870cee651ee676e67d3e55677c53f59e41c4 100644
|
|
--- a/functions.h
|
|
+++ b/functions.h
|
|
@@ -53,6 +53,7 @@ int netlink_simple_request(struct nl_msg *msg);
|
|
int translate_mesh_iface_vlan(struct state *state, const char *vlandev);
|
|
int translate_vlan_iface(struct state *state, const char *vlandev);
|
|
int translate_vid(struct state *state, const char *vidstr);
|
|
+int translate_hard_iface(struct state *state, const char *hardif);
|
|
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(struct state *state, char *hard_iface);
|
|
diff --git a/main.c b/main.c
|
|
index 309087799b839848029bd5cbec60cbe1213f9190..3b3a16f4c1caffdd2be897e6bf2a00564e5580f8 100644
|
|
--- a/main.c
|
|
+++ b/main.c
|
|
@@ -35,7 +35,8 @@ static void print_usage(void)
|
|
{
|
|
.label = "commands:\n",
|
|
.types = BIT(SUBCOMMAND) |
|
|
- BIT(SUBCOMMAND_VID),
|
|
+ BIT(SUBCOMMAND_VID) |
|
|
+ BIT(SUBCOMMAND_HIF),
|
|
},
|
|
{
|
|
.label = "debug tables: \tdisplay the corresponding debug table\n",
|
|
@@ -51,6 +52,10 @@ static void print_usage(void)
|
|
"vid <vid> ",
|
|
NULL,
|
|
};
|
|
+ const char *hardif_prefixes[] = {
|
|
+ "hardif <netdev> ",
|
|
+ NULL,
|
|
+ };
|
|
const struct command **p;
|
|
const char **prefixes;
|
|
const char **prefix;
|
|
@@ -81,6 +86,9 @@ static void print_usage(void)
|
|
case SUBCOMMAND_VID:
|
|
prefixes = vlan_prefixes;
|
|
break;
|
|
+ case SUBCOMMAND_HIF:
|
|
+ prefixes = hardif_prefixes;
|
|
+ break;
|
|
default:
|
|
prefixes = default_prefixes;
|
|
break;
|
|
@@ -153,6 +161,9 @@ static const struct command *find_command(struct state *state, const char *name)
|
|
case SP_VLAN:
|
|
types = BIT(SUBCOMMAND_VID);
|
|
break;
|
|
+ case SP_HARDIF:
|
|
+ types = BIT(SUBCOMMAND_HIF);
|
|
+ break;
|
|
default:
|
|
return NULL;
|
|
}
|
|
@@ -171,6 +182,9 @@ static int detect_selector_prefix(int argc, char *argv[],
|
|
if (strcmp(argv[0], "vlan") == 0) {
|
|
*selector = SP_VLAN;
|
|
return 2;
|
|
+ } else if (strcmp(argv[0], "hardif") == 0) {
|
|
+ *selector = SP_HARDIF;
|
|
+ return 2;
|
|
}
|
|
|
|
return 0;
|
|
@@ -197,7 +211,17 @@ static int parse_meshif_args(struct state *state, int argc, char *argv[])
|
|
dev_arg, strerror(-ret));
|
|
return ret;
|
|
}
|
|
+ return parsed_args;
|
|
+ case SP_HARDIF:
|
|
+ ret = translate_hard_iface(state, dev_arg);
|
|
+ if (ret < 0) {
|
|
+ fprintf(stderr, "Error - invalid hardif %s: %s\n",
|
|
+ dev_arg, strerror(-ret));
|
|
+ return ret;
|
|
+ }
|
|
|
|
+ snprintf(state->hard_iface, sizeof(state->hard_iface), "%s",
|
|
+ dev_arg);
|
|
return parsed_args;
|
|
case SP_NONE_OR_MESHIF:
|
|
/* not allowed - see detect_selector_prefix */
|
|
diff --git a/main.h b/main.h
|
|
index efc277c5465942d7b4dba284d29f653273b42dce..a97b26fe7b969e01cbdb848e58824e36e3d236ab 100644
|
|
--- a/main.h
|
|
+++ b/main.h
|
|
@@ -59,11 +59,13 @@ enum command_flags {
|
|
enum selector_prefix {
|
|
SP_NONE_OR_MESHIF,
|
|
SP_VLAN,
|
|
+ SP_HARDIF,
|
|
};
|
|
|
|
enum command_type {
|
|
SUBCOMMAND,
|
|
SUBCOMMAND_VID,
|
|
+ SUBCOMMAND_HIF,
|
|
DEBUGTABLE,
|
|
};
|
|
|
|
@@ -72,7 +74,11 @@ struct state {
|
|
enum selector_prefix selector;
|
|
char mesh_iface[IF_NAMESIZE];
|
|
unsigned int mesh_ifindex;
|
|
- int vid;
|
|
+ char hard_iface[IF_NAMESIZE];
|
|
+ union {
|
|
+ unsigned int hif;
|
|
+ int vid;
|
|
+ };
|
|
const struct command *cmd;
|
|
|
|
struct nl_sock *sock;
|
|
diff --git a/sys.c b/sys.c
|
|
index 61a314d88010ef34507ec9dd6a77b53f318f63a8..b9555ee484f89c1022c0b4e74e18154d18b7af6b 100644
|
|
--- a/sys.c
|
|
+++ b/sys.c
|
|
@@ -150,6 +150,10 @@ static void settings_usage(struct state *state)
|
|
"vid <vid> ",
|
|
NULL,
|
|
};
|
|
+ const char *hardif_prefixes[] = {
|
|
+ "hardif <netdev> ",
|
|
+ NULL,
|
|
+ };
|
|
const char *linestart = "Usage:";
|
|
const char **prefixes;
|
|
const char **prefix;
|
|
@@ -158,6 +162,9 @@ static void settings_usage(struct state *state)
|
|
case SUBCOMMAND_VID:
|
|
prefixes = vlan_prefixes;
|
|
break;
|
|
+ case SUBCOMMAND_HIF:
|
|
+ prefixes = hardif_prefixes;
|
|
+ break;
|
|
default:
|
|
prefixes = default_prefixes;
|
|
break;
|
|
@@ -271,6 +278,14 @@ int handle_sys_setting(struct state *state, int argc, char **argv)
|
|
snprintf(path_buff, PATH_BUFF_LEN, SYS_VLAN_PATH,
|
|
state->mesh_iface, state->vid);
|
|
break;
|
|
+ case SP_HARDIF:
|
|
+ /* if a hard interface was specified then change the path to
|
|
+ * point to the proper ${hardif}/batman-adv path in the sysfs
|
|
+ * tree.
|
|
+ */
|
|
+ snprintf(path_buff, PATH_BUFF_LEN, SYS_HARDIF_PATH,
|
|
+ state->hard_iface);
|
|
+ break;
|
|
}
|
|
|
|
if (argc == 1) {
|
|
diff --git a/sys.h b/sys.h
|
|
index d4f2fcf542bc66b2b1c6ec55a9ac16e10fdc5cac..b6f0f9043a9af8e3c4d4f8bf7e4af4cab0aa5df9 100644
|
|
--- a/sys.h
|
|
+++ b/sys.h
|
|
@@ -21,8 +21,9 @@
|
|
#define SYS_BATIF_PATH_FMT "/sys/class/net/%s/mesh/"
|
|
#define SYS_IFACE_PATH "/sys/class/net"
|
|
#define SYS_IFACE_DIR SYS_IFACE_PATH"/%s/"
|
|
-#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_HARDIF_PATH SYS_IFACE_DIR "batman_adv/"
|
|
+#define SYS_MESH_IFACE_FMT SYS_HARDIF_PATH "mesh_iface"
|
|
+#define SYS_IFACE_STATUS_FMT SYS_HARDIF_PATH "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
|