Hi,
the batctl command already has support to get (previously debugfs) tables via netlink. It does this while still being able to fall back to the old debugfs tables on kernels which don't support the new generic netlink family.
Something similar should be done in the future for the settings which are currently part of sysfs. But we can already see that the current integration of netlink in batctl only done in a single file - netlink.c But this file is already starting to be so big that working with it is rather cumbersome.
So as first steps:
* restructure command registration * move commands in separate files (which should store their actual implementation) * add a new helper command to receive multicast group messages from the kernel
More things will follow in the future.
Changes:
v3:
* correctly split ap_isolation and bonding patch * fix copyright headers for new files * move more routing_algo specific code to its command specific file * fix build problems with musl in OpenWrt 18.06 * switch Makefile's OBJ + OBJ_BISECT to obj-y and obj-n * add way to "freely" disable some commands for size optimization reasons
- it is for example now possible to reduce the size of the batctl on mips_24kc_musl from 64604 bytes to 14252 bytes when only the interface commands are required (I know, stupid example) - the binary to generate the debug tables output for the same architectur used 26988 bytes
v2:
* Add missing orig_interval.c
Kind regards, Sven
Sven Eckelmann (42): batctl: Drop unused define SOCKET_PATH_FMT batctl: Use common code organization for statistics batctl: Drop legacy vis_* related warning messages batctl: Move loglevel command to separate file batctl: Move log command to separate file batctl: Move gw_mode command to separate file batctl: Move routing_algo command to separate file batctl: Rename tp_meter to throughputmeter batctl: Introduce datastructure for subcommands batctl: Add per command flags batctl: Use command structure for remaining subcommands batctl: Use getopt to parse main options batctl: Store usage line next to command batctl: Prepare command infrastructure for shared functions batctl: Add type to command to structure usage output batctl: Convert debug table to command infrastructure batctl: Convert sysfs settings to command infrastructure batctl: Move backbonetable debug table to own file batctl: Move claimtable debug table to own file batctl: Move dat_cache debug table to own file batctl: Move gateways debug table to own file batctl: Move mcast_flags debug table to own file batctl: Move nc_nodes debug table to own file batctl: Move neighbors debug table to own file batctl: Move originators debug table to own file batctl: Move transglobal debug table to own file batctl: Move translocal debug table to own file batctl: Move aggregation setting to own file batctl: Move ap_isolation setting to own file batctl: Move bonding setting to own file batctl: Move bridge_loop_avoidance setting to own file batctl: Move distributed_arp_table setting to own file batctl: Move fragmentation setting to own file batctl: Move isolation_mark setting to own file batctl: Move multicast_mode setting to own file batctl: Move network_coding setting to own file batctl: Move orig_interval setting to own file batctl: Use external netlink socket for debug tables batctl: Move routing_algo specific code it command source file batctl: Add command to monitor for netlink events batctl: Simplify enabling for bisect_iv subcommand batctl: Allow to enable/disable subcommands
Makefile | 91 ++- translate.h => aggregation.c | 15 +- ap_isolation.c | 33 + backbonetable.c | 126 ++++ bisect_iv.c | 6 +- bisect_iv.h | 4 - traceroute.h => bonding.c | 15 +- bridge_loop_avoidance.c | 33 + claimtable.c | 131 ++++ dat_cache.c | 147 +++++ debug.c | 218 +------ debug.h | 38 +- distributed_arp_table.c | 33 + event.c | 246 ++++++++ ping.h => fragmentation.c | 15 +- functions.c | 28 +- functions.h | 1 - gateways.c | 175 +++++ gw_mode.c | 171 +++++ interface.c | 23 +- ioctl.h | 28 - isolation_mark.c | 35 + log.c | 73 +++ loglevel.c | 147 +++++ main.c | 274 ++++---- main.h | 65 +- man/batctl.8 | 4 + mcast_flags.c | 180 ++++++ multicast_mode.c | 33 + interface.h => nc_nodes.c | 14 +- neighbors.c | 142 +++++ netlink.c | 1332 ++++----------------------------------- netlink.h | 55 +- network_coding.c | 33 + orig_interval.c | 35 + originators.c | 228 +++++++ ping.c | 10 +- routing_algo.c | 263 ++++++++ ioctl.c => statistics.c | 10 +- sys.c | 432 +------------ sys.h | 39 +- tcpdump.c | 5 +- tcpdump.h | 2 - tp_meter.c => throughputmeter.c | 10 +- tp_meter.h | 28 - traceroute.c | 10 +- transglobal.c | 162 +++++ translate.c | 8 +- translocal.c | 158 +++++ 49 files changed, 3156 insertions(+), 2208 deletions(-) rename translate.h => aggregation.c (67%) create mode 100644 ap_isolation.c create mode 100644 backbonetable.c rename traceroute.h => bonding.c (68%) create mode 100644 bridge_loop_avoidance.c create mode 100644 claimtable.c create mode 100644 dat_cache.c create mode 100644 distributed_arp_table.c create mode 100644 event.c rename ping.h => fragmentation.c (67%) create mode 100644 gateways.c create mode 100644 gw_mode.c delete mode 100644 ioctl.h create mode 100644 isolation_mark.c create mode 100644 log.c create mode 100644 loglevel.c create mode 100644 mcast_flags.c create mode 100644 multicast_mode.c rename interface.h => nc_nodes.c (73%) create mode 100644 neighbors.c create mode 100644 network_coding.c create mode 100644 orig_interval.c create mode 100644 originators.c create mode 100644 routing_algo.c rename ioctl.c => statistics.c (90%) rename tp_meter.c => throughputmeter.c (97%) delete mode 100644 tp_meter.h create mode 100644 transglobal.c create mode 100644 translocal.c
The commit 4bd751eed4dc ("batctl: Implement non-routing batadv_icmp in userspace") removed the last code section which referenced SOCKET_PATH_FMT.
Signed-off-by: Sven Eckelmann sven@narfation.org --- main.h | 2 -- 1 file changed, 2 deletions(-)
diff --git a/main.h b/main.h index 5cd2f46..e8c6db7 100644 --- a/main.h +++ b/main.h @@ -29,8 +29,6 @@ #define SOURCE_VERSION "2018.4" #endif
-#define SOCKET_PATH_FMT "%s/batman_adv/%s/socket" - #define EXIT_NOSUCCESS 2
#define OPT_LONG_MAX_LEN 25
Most commands have a separate file which is called like command itself. They also tend to share the same function signature to make it easier to use. Do the same for the ethtool statistics to make it easier to find.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 2 +- main.c | 4 ++-- ioctl.c => statistics.c | 6 ++++-- ioctl.h => statistics.h | 6 +++--- 4 files changed, 10 insertions(+), 8 deletions(-) rename ioctl.c => statistics.c (95%) rename ioctl.h => statistics.h (88%)
diff --git a/Makefile b/Makefile index 4b417d5..6f620be 100755 --- a/Makefile +++ b/Makefile @@ -34,10 +34,10 @@ OBJ += genl.o OBJ += hash.o OBJ += icmp_helper.o OBJ += interface.o -OBJ += ioctl.o OBJ += main.o OBJ += netlink.o OBJ += ping.o +OBJ += statistics.o OBJ += sys.o OBJ += tcpdump.o OBJ += tp_meter.o diff --git a/main.c b/main.c index d5504e0..e904a1f 100644 --- a/main.c +++ b/main.c @@ -37,7 +37,7 @@ #include "tcpdump.h" #include "tp_meter.h" #include "bisect_iv.h" -#include "ioctl.h" +#include "statistics.h" #include "functions.h"
char mesh_dfl_iface[] = "bat0"; @@ -187,7 +187,7 @@ int main(int argc, char **argv)
} else if ((strcmp(argv[1], "statistics") == 0) || (strcmp(argv[1], "s") == 0)) {
- ret = ioctl_statistics_get(mesh_iface); + ret = statistics(mesh_iface, argc - 1, argv + 1);
} else if ((strcmp(argv[1], "translate") == 0) || (strcmp(argv[1], "t") == 0)) {
diff --git a/ioctl.c b/statistics.c similarity index 95% rename from ioctl.c rename to statistics.c index 6f9a056..8a889ca 100644 --- a/ioctl.c +++ b/statistics.c @@ -34,7 +34,8 @@ #include <linux/ethtool.h> #include <stdint.h>
-#include "ioctl.h" +#include "main.h" +#include "statistics.h"
void check_root_or_die(const char *cmd);
@@ -102,7 +103,8 @@ static int statistics_custom_get(int fd, struct ifreq *ifr) return ret; }
-int ioctl_statistics_get(char *mesh_iface) +int statistics(char *mesh_iface, int argc __maybe_unused, + char **argv __maybe_unused) { struct ifreq ifr; int fd = -1, ret = EXIT_FAILURE; diff --git a/ioctl.h b/statistics.h similarity index 88% rename from ioctl.h rename to statistics.h index 1b216c0..3737a48 100644 --- a/ioctl.h +++ b/statistics.h @@ -20,9 +20,9 @@ * License-Filename: LICENSES/preferred/GPL-2.0 */
-#ifndef _BATCTL_IOCTL_H -#define _BATCTL_IOCTL_H +#ifndef _BATCTL_STATISTICS_H +#define _BATCTL_STATISTICS_H
-int ioctl_statistics_get(char *mesh_iface); +int statistics(char *mesh_iface, int argc, char **argv);
#endif
The vis support code was removed with batman-adv 2014.0.0 (Linux 3.13). All kernel versions with up to this version are EOL for a while and also batctl warned now about this problem for nearly 5 years. It should therefore no (serious) problem to remove these warning messages.
Signed-off-by: Sven Eckelmann sven@narfation.org --- debug.c | 28 ---------------------------- debug.h | 1 - main.c | 6 ------ 3 files changed, 35 deletions(-)
diff --git a/debug.c b/debug.c index 63fb633..185e26d 100644 --- a/debug.c +++ b/debug.c @@ -269,34 +269,6 @@ int debug_print_routing_algos(void) return read_file(full_path, DEBUG_ROUTING_ALGOS, 0, 0, 0, 0); }
-int print_vis_info(char *mesh_iface) -{ - char full_path[MAX_PATH+1]; - char *debugfs_mnt; - FILE *fp; - - check_root_or_die("batctl vis_data"); - - debugfs_mnt = debugfs_mount(NULL); - if (!debugfs_mnt) { - fprintf(stderr, "Error - can't mount or find debugfs\n"); - return -1; - } - - debugfs_make_path(DEBUG_BATIF_PATH_FMT "/vis_data", mesh_iface, full_path, sizeof(full_path)); - fp = fopen(full_path, "r"); - if (fp) { - fclose(fp); - fprintf(stderr, "Error - batctl version is newer than kernel module - the kernel module still supports\n" - "vis, but later versions will not. The vis functionality has been moved to the userspace\n" - "daemon ''alfred''. Please either downgrade to an older (compatible) batctl version or use alfred.\n"); - } else { - fprintf(stderr, "Error - The installed batctl version and kernel module don't have vis support. The vis functionality\n" - "has been moved to the userspace daemon ''alfred''.\n"); - } - return 0; -} - static void log_usage(void) { fprintf(stderr, "Usage: batctl [options] log [parameters]\n"); diff --git a/debug.h b/debug.h index 9c57aa6..5508eaf 100644 --- a/debug.h +++ b/debug.h @@ -59,6 +59,5 @@ extern const struct debug_table_data batctl_debug_tables[BATCTL_TABLE_NUM]; int handle_debug_table(char *mesh_iface, int debug_table, int argc, char **argv); int log_print(char *mesh_iface, int argc, char **argv); int debug_print_routing_algos(void); -int print_vis_info(char *mesh_iface);
#endif diff --git a/main.c b/main.c index e904a1f..3a6011b 100644 --- a/main.c +++ b/main.c @@ -175,12 +175,6 @@ int main(int argc, char **argv)
ret = log_print(mesh_iface, argc - 1, argv + 1);
- /* vis legacy support */ - } else if ((strcmp(argv[1], "vis_data") == 0) || (strcmp(argv[1], "vd") == 0) || - (strcmp(argv[1], "vis_mode") == 0) || (strcmp(argv[1], "vm") == 0)) { - - ret = print_vis_info(mesh_iface); - } else if ((strcmp(argv[1], "gw_mode") == 0) || (strcmp(argv[1], "gw") == 0)) {
ret = handle_gw_setting(mesh_iface, argc - 1, argv + 1);
More complex commands in batctl are stored in separate files which are called like the actual command name. This makes it easier to group functionality and detect which parts belong to a more complex construct.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + loglevel.c | 144 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ loglevel.h | 28 ++++++++++++ main.c | 3 +- sys.c | 114 ------------------------------------------------ sys.h | 1 - 6 files changed, 175 insertions(+), 116 deletions(-) create mode 100644 loglevel.c create mode 100644 loglevel.h
diff --git a/Makefile b/Makefile index 6f620be..1271200 100755 --- a/Makefile +++ b/Makefile @@ -34,6 +34,7 @@ OBJ += genl.o OBJ += hash.o OBJ += icmp_helper.o OBJ += interface.o +OBJ += loglevel.o OBJ += main.o OBJ += netlink.o OBJ += ping.o diff --git a/loglevel.c b/loglevel.c new file mode 100644 index 0000000..584cb37 --- /dev/null +++ b/loglevel.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <getopt.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "functions.h" +#include "main.h" +#include "sys.h" + +static void log_level_usage(void) +{ + fprintf(stderr, "Usage: batctl [options] loglevel [parameters] [level[ level[ level]]...]\n"); + fprintf(stderr, "parameters:\n"); + fprintf(stderr, " \t -h print this help\n"); + fprintf(stderr, "levels:\n"); + fprintf(stderr, " \t none Debug logging is disabled\n"); + fprintf(stderr, " \t all Print messages from all below\n"); + fprintf(stderr, " \t batman Messages related to routing / flooding / broadcasting\n"); + fprintf(stderr, " \t routes Messages related to route added / changed / deleted\n"); + fprintf(stderr, " \t tt Messages related to translation table operations\n"); + fprintf(stderr, " \t bla Messages related to bridge loop avoidance\n"); + fprintf(stderr, " \t dat Messages related to arp snooping and distributed arp table\n"); + fprintf(stderr, " \t nc Messages related to network coding\n"); + fprintf(stderr, " \t mcast Messages related to multicast\n"); + fprintf(stderr, " \t tp Messages related to throughput meter\n"); +} + +int loglevel(char *mesh_iface, int argc, char **argv) +{ + int optchar, res = EXIT_FAILURE; + int log_level = 0; + char *path_buff; + char str[4]; + int i; + + while ((optchar = getopt(argc, argv, "h")) != -1) { + switch (optchar) { + case 'h': + log_level_usage(); + return EXIT_SUCCESS; + default: + log_level_usage(); + return EXIT_FAILURE; + } + } + + path_buff = malloc(PATH_BUFF_LEN); + if (!path_buff) { + fprintf(stderr, "Error - could not allocate path buffer: out of memory ?\n"); + return EXIT_FAILURE; + } + + snprintf(path_buff, PATH_BUFF_LEN, SYS_BATIF_PATH_FMT, mesh_iface); + + if (argc != 1) { + check_root_or_die("batctl loglevel"); + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "none") == 0) { + log_level = 0; + break; + } else if (strcmp(argv[i], "all") == 0) { + log_level = 255; + break; + } else if (strcmp(argv[i], "batman") == 0) + log_level |= BIT(0); + else if (strcmp(argv[i], "routes") == 0) + log_level |= BIT(1); + else if (strcmp(argv[i], "tt") == 0) + log_level |= BIT(2); + else if (strcmp(argv[i], "bla") == 0) + log_level |= BIT(3); + else if (strcmp(argv[i], "dat") == 0) + log_level |= BIT(4); + else if (strcmp(argv[i], "nc") == 0) + log_level |= BIT(5); + else if (strcmp(argv[i], "mcast") == 0) + log_level |= BIT(6); + else if (strcmp(argv[i], "tp") == 0) + log_level |= BIT(7); + else { + log_level_usage(); + goto out; + } + } + + snprintf(str, sizeof(str), "%i", log_level); + res = write_file(path_buff, SYS_LOG_LEVEL, str, NULL); + goto out; + } + + res = read_file(path_buff, SYS_LOG_LEVEL, USE_READ_BUFF, 0, 0, 0); + + if (res != EXIT_SUCCESS) + goto out; + + log_level = strtol(line_ptr, (char **) NULL, 10); + + printf("[%c] %s (%s)\n", (!log_level) ? 'x' : ' ', + "all debug output disabled", "none"); + printf("[%c] %s (%s)\n", (log_level & BIT(0)) ? 'x' : ' ', + "messages related to routing / flooding / broadcasting", + "batman"); + printf("[%c] %s (%s)\n", (log_level & BIT(1)) ? 'x' : ' ', + "messages related to route added / changed / deleted", "routes"); + printf("[%c] %s (%s)\n", (log_level & BIT(2)) ? 'x' : ' ', + "messages related to translation table operations", "tt"); + printf("[%c] %s (%s)\n", (log_level & BIT(3)) ? 'x' : ' ', + "messages related to bridge loop avoidance", "bla"); + printf("[%c] %s (%s)\n", (log_level & BIT(4)) ? 'x' : ' ', + "messages related to arp snooping and distributed arp table", "dat"); + printf("[%c] %s (%s)\n", (log_level & BIT(5)) ? 'x' : ' ', + "messages related to network coding", "nc"); + printf("[%c] %s (%s)\n", (log_level & BIT(6)) ? 'x' : ' ', + "messages related to multicast", "mcast"); + printf("[%c] %s (%s)\n", (log_level & BIT(7)) ? 'x' : ' ', + "messages related to throughput meter", "tp"); + +out: + free(path_buff); + return res; +} diff --git a/loglevel.h b/loglevel.h new file mode 100644 index 0000000..2644f46 --- /dev/null +++ b/loglevel.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#ifndef _BATCTL_LOGLEVEL_H +#define _BATCTL_LOGLEVEL_H + +int loglevel(char *mesh_iface, int argc, char **argv); + +#endif diff --git a/main.c b/main.c index 3a6011b..ac4bc47 100644 --- a/main.c +++ b/main.c @@ -38,6 +38,7 @@ #include "tp_meter.h" #include "bisect_iv.h" #include "statistics.h" +#include "loglevel.h" #include "functions.h"
char mesh_dfl_iface[] = "bat0"; @@ -169,7 +170,7 @@ int main(int argc, char **argv)
} else if ((strcmp(argv[1], "loglevel") == 0) || (strcmp(argv[1], "ll") == 0)) {
- ret = handle_loglevel(mesh_iface, argc - 1, argv + 1); + ret = loglevel(mesh_iface, argc - 1, argv + 1);
} else if ((strcmp(argv[1], "log") == 0) || (strcmp(argv[1], "l") == 0)) {
diff --git a/sys.c b/sys.c index e0c2073..366f7a2 100644 --- a/sys.c +++ b/sys.c @@ -117,120 +117,6 @@ const struct settings_data batctl_settings[BATCTL_SETTINGS_NUM] = { }, };
-static void log_level_usage(void) -{ - fprintf(stderr, "Usage: batctl [options] loglevel [parameters] [level[ level[ level]]...]\n"); - fprintf(stderr, "parameters:\n"); - fprintf(stderr, " \t -h print this help\n"); - fprintf(stderr, "levels:\n"); - fprintf(stderr, " \t none Debug logging is disabled\n"); - fprintf(stderr, " \t all Print messages from all below\n"); - fprintf(stderr, " \t batman Messages related to routing / flooding / broadcasting\n"); - fprintf(stderr, " \t routes Messages related to route added / changed / deleted\n"); - fprintf(stderr, " \t tt Messages related to translation table operations\n"); - fprintf(stderr, " \t bla Messages related to bridge loop avoidance\n"); - fprintf(stderr, " \t dat Messages related to arp snooping and distributed arp table\n"); - fprintf(stderr, " \t nc Messages related to network coding\n"); - fprintf(stderr, " \t mcast Messages related to multicast\n"); - fprintf(stderr, " \t tp Messages related to throughput meter\n"); -} - -int handle_loglevel(char *mesh_iface, int argc, char **argv) -{ - int optchar, res = EXIT_FAILURE; - int log_level = 0; - char *path_buff; - char str[4]; - int i; - - while ((optchar = getopt(argc, argv, "h")) != -1) { - switch (optchar) { - case 'h': - log_level_usage(); - return EXIT_SUCCESS; - default: - log_level_usage(); - return EXIT_FAILURE; - } - } - - path_buff = malloc(PATH_BUFF_LEN); - if (!path_buff) { - fprintf(stderr, "Error - could not allocate path buffer: out of memory ?\n"); - return EXIT_FAILURE; - } - - snprintf(path_buff, PATH_BUFF_LEN, SYS_BATIF_PATH_FMT, mesh_iface); - - if (argc != 1) { - check_root_or_die("batctl loglevel"); - - for (i = 1; i < argc; i++) { - if (strcmp(argv[i], "none") == 0) { - log_level = 0; - break; - } else if (strcmp(argv[i], "all") == 0) { - log_level = 255; - break; - } else if (strcmp(argv[i], "batman") == 0) - log_level |= BIT(0); - else if (strcmp(argv[i], "routes") == 0) - log_level |= BIT(1); - else if (strcmp(argv[i], "tt") == 0) - log_level |= BIT(2); - else if (strcmp(argv[i], "bla") == 0) - log_level |= BIT(3); - else if (strcmp(argv[i], "dat") == 0) - log_level |= BIT(4); - else if (strcmp(argv[i], "nc") == 0) - log_level |= BIT(5); - else if (strcmp(argv[i], "mcast") == 0) - log_level |= BIT(6); - else if (strcmp(argv[i], "tp") == 0) - log_level |= BIT(7); - else { - log_level_usage(); - goto out; - } - } - - snprintf(str, sizeof(str), "%i", log_level); - res = write_file(path_buff, SYS_LOG_LEVEL, str, NULL); - goto out; - } - - res = read_file(path_buff, SYS_LOG_LEVEL, USE_READ_BUFF, 0, 0, 0); - - if (res != EXIT_SUCCESS) - goto out; - - log_level = strtol(line_ptr, (char **) NULL, 10); - - printf("[%c] %s (%s)\n", (!log_level) ? 'x' : ' ', - "all debug output disabled", "none"); - printf("[%c] %s (%s)\n", (log_level & BIT(0)) ? 'x' : ' ', - "messages related to routing / flooding / broadcasting", - "batman"); - printf("[%c] %s (%s)\n", (log_level & BIT(1)) ? 'x' : ' ', - "messages related to route added / changed / deleted", "routes"); - printf("[%c] %s (%s)\n", (log_level & BIT(2)) ? 'x' : ' ', - "messages related to translation table operations", "tt"); - printf("[%c] %s (%s)\n", (log_level & BIT(3)) ? 'x' : ' ', - "messages related to bridge loop avoidance", "bla"); - printf("[%c] %s (%s)\n", (log_level & BIT(4)) ? 'x' : ' ', - "messages related to arp snooping and distributed arp table", "dat"); - printf("[%c] %s (%s)\n", (log_level & BIT(5)) ? 'x' : ' ', - "messages related to network coding", "nc"); - printf("[%c] %s (%s)\n", (log_level & BIT(6)) ? 'x' : ' ', - "messages related to multicast", "mcast"); - printf("[%c] %s (%s)\n", (log_level & BIT(7)) ? 'x' : ' ', - "messages related to throughput meter", "tp"); - -out: - free(path_buff); - return res; -} - static void settings_usage(int setting) { fprintf(stderr, "Usage: batctl [options] %s|%s [parameters]", diff --git a/sys.h b/sys.h index 95b2a1e..5e98ab1 100644 --- a/sys.h +++ b/sys.h @@ -71,7 +71,6 @@ extern const char *sysfs_param_enable[]; extern const char *sysfs_param_server[]; extern const struct settings_data batctl_settings[BATCTL_SETTINGS_NUM];
-int handle_loglevel(char *mesh_iface, int argc, char **argv); int handle_sys_setting(char *mesh_iface, int setting, int argc, char **argv); int handle_gw_setting(char *mesh_iface, int argc, char **argv); int handle_ra_setting(int argc, char **argv);
More complex commands in batctl are stored in separate files which are called like the actual command name. This makes it easier to group functionality and detect which parts belong to a more complex construct.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + debug.c | 41 ------------------------------------- debug.h | 1 - log.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ log.h | 28 ++++++++++++++++++++++++++ main.c | 1 + 6 files changed, 100 insertions(+), 42 deletions(-) create mode 100644 log.c create mode 100644 log.h
diff --git a/Makefile b/Makefile index 1271200..a988058 100755 --- a/Makefile +++ b/Makefile @@ -35,6 +35,7 @@ OBJ += hash.o OBJ += icmp_helper.o OBJ += interface.o OBJ += loglevel.o +OBJ += log.o OBJ += main.o OBJ += netlink.o OBJ += ping.o diff --git a/debug.c b/debug.c index 185e26d..9bc4d0c 100644 --- a/debug.c +++ b/debug.c @@ -268,44 +268,3 @@ int debug_print_routing_algos(void) debugfs_make_path(DEBUG_BATIF_PATH_FMT, "", full_path, sizeof(full_path)); return read_file(full_path, DEBUG_ROUTING_ALGOS, 0, 0, 0, 0); } - -static void log_usage(void) -{ - fprintf(stderr, "Usage: batctl [options] log [parameters]\n"); - fprintf(stderr, "parameters:\n"); - fprintf(stderr, " \t -h print this help\n"); - fprintf(stderr, " \t -n don't replace mac addresses with bat-host names\n"); -} - -int log_print(char *mesh_iface, int argc, char **argv) -{ - int optchar, res, read_opt = USE_BAT_HOSTS | LOG_MODE; - char full_path[MAX_PATH+1]; - char *debugfs_mnt; - - while ((optchar = getopt(argc, argv, "hn")) != -1) { - switch (optchar) { - case 'h': - log_usage(); - return EXIT_SUCCESS; - case 'n': - read_opt &= ~USE_BAT_HOSTS; - break; - default: - log_usage(); - return EXIT_FAILURE; - } - } - - check_root_or_die("batctl log"); - - debugfs_mnt = debugfs_mount(NULL); - if (!debugfs_mnt) { - fprintf(stderr, "Error - can't mount or find debugfs\n"); - return EXIT_FAILURE; - } - - debugfs_make_path(DEBUG_BATIF_PATH_FMT "/", mesh_iface, full_path, sizeof(full_path)); - res = read_file(full_path, DEBUG_LOG, read_opt, 0, 0, 0); - return res; -} diff --git a/debug.h b/debug.h index 5508eaf..d9a2e3a 100644 --- a/debug.h +++ b/debug.h @@ -57,7 +57,6 @@ struct debug_table_data { extern const struct debug_table_data batctl_debug_tables[BATCTL_TABLE_NUM];
int handle_debug_table(char *mesh_iface, int debug_table, int argc, char **argv); -int log_print(char *mesh_iface, int argc, char **argv); int debug_print_routing_algos(void);
#endif diff --git a/log.c b/log.c new file mode 100644 index 0000000..fc31c66 --- /dev/null +++ b/log.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <getopt.h> +#include <stdio.h> +#include <stdlib.h> + +#include "debug.h" +#include "debugfs.h" +#include "functions.h" + +static void log_usage(void) +{ + fprintf(stderr, "Usage: batctl [options] log [parameters]\n"); + fprintf(stderr, "parameters:\n"); + fprintf(stderr, " \t -h print this help\n"); + fprintf(stderr, " \t -n don't replace mac addresses with bat-host names\n"); +} + +int log_print(char *mesh_iface, int argc, char **argv) +{ + int optchar, res, read_opt = USE_BAT_HOSTS | LOG_MODE; + char full_path[MAX_PATH+1]; + char *debugfs_mnt; + + while ((optchar = getopt(argc, argv, "hn")) != -1) { + switch (optchar) { + case 'h': + log_usage(); + return EXIT_SUCCESS; + case 'n': + read_opt &= ~USE_BAT_HOSTS; + break; + default: + log_usage(); + return EXIT_FAILURE; + } + } + + check_root_or_die("batctl log"); + + debugfs_mnt = debugfs_mount(NULL); + if (!debugfs_mnt) { + fprintf(stderr, "Error - can't mount or find debugfs\n"); + return EXIT_FAILURE; + } + + debugfs_make_path(DEBUG_BATIF_PATH_FMT "/", mesh_iface, full_path, sizeof(full_path)); + res = read_file(full_path, DEBUG_LOG, read_opt, 0, 0, 0); + return res; +} diff --git a/log.h b/log.h new file mode 100644 index 0000000..4ba00e3 --- /dev/null +++ b/log.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#ifndef _BATCTL_LOG_H +#define _BATCTL_LOG_H + +int log_print(char *mesh_iface, int argc, char **argv); + +#endif diff --git a/main.c b/main.c index ac4bc47..5b3e570 100644 --- a/main.c +++ b/main.c @@ -39,6 +39,7 @@ #include "bisect_iv.h" #include "statistics.h" #include "loglevel.h" +#include "log.h" #include "functions.h"
char mesh_dfl_iface[] = "bat0";
More complex commands in batctl are stored in separate files which are called like the actual command name. This makes it easier to group functionality and detect which parts belong to a more complex construct.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + gw_mode.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gw_mode.h | 28 +++++++++++ main.c | 3 +- sys.c | 129 ----------------------------------------------- sys.h | 10 ---- 6 files changed, 199 insertions(+), 140 deletions(-) create mode 100644 gw_mode.c create mode 100644 gw_mode.h
diff --git a/Makefile b/Makefile index a988058..9b960b6 100755 --- a/Makefile +++ b/Makefile @@ -31,6 +31,7 @@ OBJ += debugfs.o OBJ += debug.o OBJ += functions.o OBJ += genl.o +OBJ += gw_mode.o OBJ += hash.o OBJ += icmp_helper.o OBJ += interface.o diff --git a/gw_mode.c b/gw_mode.c new file mode 100644 index 0000000..a92644e --- /dev/null +++ b/gw_mode.c @@ -0,0 +1,168 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <getopt.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "functions.h" +#include "sys.h" + +#define SYS_GW_MODE "gw_mode" +#define SYS_GW_SEL "gw_sel_class" +#define SYS_GW_BW "gw_bandwidth" + +enum gw_modes { + GW_MODE_OFF, + GW_MODE_CLIENT, + GW_MODE_SERVER, +}; + +static void gw_mode_usage(void) +{ + fprintf(stderr, "Usage: batctl [options] gw_mode [mode] [sel_class|bandwidth]\n"); + fprintf(stderr, "options:\n"); + fprintf(stderr, " \t -h print this help\n"); +} + +int gw_mode(char *mesh_iface, int argc, char **argv) +{ + int optchar, res = EXIT_FAILURE; + char *path_buff, gw_mode; + const char **ptr; + + while ((optchar = getopt(argc, argv, "h")) != -1) { + switch (optchar) { + case 'h': + gw_mode_usage(); + return EXIT_SUCCESS; + default: + gw_mode_usage(); + return EXIT_FAILURE; + } + } + + path_buff = malloc(PATH_BUFF_LEN); + if (!path_buff) { + fprintf(stderr, "Error - could not allocate path buffer: out of memory ?\n"); + return EXIT_FAILURE; + } + + snprintf(path_buff, PATH_BUFF_LEN, SYS_BATIF_PATH_FMT, mesh_iface); + + if (argc == 1) { + res = read_file(path_buff, SYS_GW_MODE, USE_READ_BUFF, 0, 0, 0); + + if (res != EXIT_SUCCESS) + goto out; + + if (line_ptr[strlen(line_ptr) - 1] == '\n') + line_ptr[strlen(line_ptr) - 1] = '\0'; + + if (strcmp(line_ptr, "client") == 0) + gw_mode = GW_MODE_CLIENT; + else if (strcmp(line_ptr, "server") == 0) + gw_mode = GW_MODE_SERVER; + else + gw_mode = GW_MODE_OFF; + + free(line_ptr); + line_ptr = NULL; + + switch (gw_mode) { + case GW_MODE_CLIENT: + res = read_file(path_buff, SYS_GW_SEL, USE_READ_BUFF, 0, 0, 0); + break; + case GW_MODE_SERVER: + res = read_file(path_buff, SYS_GW_BW, USE_READ_BUFF, 0, 0, 0); + break; + default: + printf("off\n"); + goto out; + } + + if (res != EXIT_SUCCESS) + goto out; + + if (line_ptr[strlen(line_ptr) - 1] == '\n') + line_ptr[strlen(line_ptr) - 1] = '\0'; + + switch (gw_mode) { + case GW_MODE_CLIENT: + printf("client (selection class: %s)\n", line_ptr); + break; + case GW_MODE_SERVER: + printf("server (announced bw: %s)\n", line_ptr); + break; + default: + goto out; + } + + free(line_ptr); + line_ptr = NULL; + goto out; + } + + check_root_or_die("batctl gw_mode"); + + if (strcmp(argv[1], "client") == 0) + gw_mode = GW_MODE_CLIENT; + else if (strcmp(argv[1], "server") == 0) + gw_mode = GW_MODE_SERVER; + else if (strcmp(argv[1], "off") == 0) + gw_mode = GW_MODE_OFF; + else + goto opt_err; + + res = write_file(path_buff, SYS_GW_MODE, argv[1], NULL); + if (res != EXIT_SUCCESS) + goto out; + + if (argc == 2) + goto out; + + switch (gw_mode) { + case GW_MODE_CLIENT: + res = write_file(path_buff, SYS_GW_SEL, argv[2], NULL); + break; + case GW_MODE_SERVER: + res = write_file(path_buff, SYS_GW_BW, argv[2], NULL); + break; + } + + goto out; + +opt_err: + fprintf(stderr, "Error - the supplied argument is invalid: %s\n", argv[1]); + fprintf(stderr, "The following values are allowed:\n"); + + ptr = sysfs_param_server; + while (*ptr) { + fprintf(stderr, " * %s\n", *ptr); + ptr++; + } + +out: + free(path_buff); + return res; +} diff --git a/gw_mode.h b/gw_mode.h new file mode 100644 index 0000000..d4d3fb5 --- /dev/null +++ b/gw_mode.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#ifndef _BATCTL_GW_MODE_H +#define _BATCTL_GW_MODE_H + +int gw_mode(char *mesh_iface, int argc, char **argv); + +#endif diff --git a/main.c b/main.c index 5b3e570..6160a72 100644 --- a/main.c +++ b/main.c @@ -40,6 +40,7 @@ #include "statistics.h" #include "loglevel.h" #include "log.h" +#include "gw_mode.h" #include "functions.h"
char mesh_dfl_iface[] = "bat0"; @@ -179,7 +180,7 @@ int main(int argc, char **argv)
} else if ((strcmp(argv[1], "gw_mode") == 0) || (strcmp(argv[1], "gw") == 0)) {
- ret = handle_gw_setting(mesh_iface, argc - 1, argv + 1); + ret = gw_mode(mesh_iface, argc - 1, argv + 1);
} else if ((strcmp(argv[1], "statistics") == 0) || (strcmp(argv[1], "s") == 0)) {
diff --git a/sys.c b/sys.c index 366f7a2..14f322c 100644 --- a/sys.c +++ b/sys.c @@ -206,135 +206,6 @@ int handle_sys_setting(char *mesh_iface, int setting, int argc, char **argv) return res; }
-static void gw_mode_usage(void) -{ - fprintf(stderr, "Usage: batctl [options] gw_mode [mode] [sel_class|bandwidth]\n"); - fprintf(stderr, "options:\n"); - fprintf(stderr, " \t -h print this help\n"); -} - -int handle_gw_setting(char *mesh_iface, int argc, char **argv) -{ - int optchar, res = EXIT_FAILURE; - char *path_buff, gw_mode; - const char **ptr; - - while ((optchar = getopt(argc, argv, "h")) != -1) { - switch (optchar) { - case 'h': - gw_mode_usage(); - return EXIT_SUCCESS; - default: - gw_mode_usage(); - return EXIT_FAILURE; - } - } - - path_buff = malloc(PATH_BUFF_LEN); - if (!path_buff) { - fprintf(stderr, "Error - could not allocate path buffer: out of memory ?\n"); - return EXIT_FAILURE; - } - - snprintf(path_buff, PATH_BUFF_LEN, SYS_BATIF_PATH_FMT, mesh_iface); - - if (argc == 1) { - res = read_file(path_buff, SYS_GW_MODE, USE_READ_BUFF, 0, 0, 0); - - if (res != EXIT_SUCCESS) - goto out; - - if (line_ptr[strlen(line_ptr) - 1] == '\n') - line_ptr[strlen(line_ptr) - 1] = '\0'; - - if (strcmp(line_ptr, "client") == 0) - gw_mode = GW_MODE_CLIENT; - else if (strcmp(line_ptr, "server") == 0) - gw_mode = GW_MODE_SERVER; - else - gw_mode = GW_MODE_OFF; - - free(line_ptr); - line_ptr = NULL; - - switch (gw_mode) { - case GW_MODE_CLIENT: - res = read_file(path_buff, SYS_GW_SEL, USE_READ_BUFF, 0, 0, 0); - break; - case GW_MODE_SERVER: - res = read_file(path_buff, SYS_GW_BW, USE_READ_BUFF, 0, 0, 0); - break; - default: - printf("off\n"); - goto out; - } - - if (res != EXIT_SUCCESS) - goto out; - - if (line_ptr[strlen(line_ptr) - 1] == '\n') - line_ptr[strlen(line_ptr) - 1] = '\0'; - - switch (gw_mode) { - case GW_MODE_CLIENT: - printf("client (selection class: %s)\n", line_ptr); - break; - case GW_MODE_SERVER: - printf("server (announced bw: %s)\n", line_ptr); - break; - default: - goto out; - } - - free(line_ptr); - line_ptr = NULL; - goto out; - } - - check_root_or_die("batctl gw_mode"); - - if (strcmp(argv[1], "client") == 0) - gw_mode = GW_MODE_CLIENT; - else if (strcmp(argv[1], "server") == 0) - gw_mode = GW_MODE_SERVER; - else if (strcmp(argv[1], "off") == 0) - gw_mode = GW_MODE_OFF; - else - goto opt_err; - - res = write_file(path_buff, SYS_GW_MODE, argv[1], NULL); - if (res != EXIT_SUCCESS) - goto out; - - if (argc == 2) - goto out; - - switch (gw_mode) { - case GW_MODE_CLIENT: - res = write_file(path_buff, SYS_GW_SEL, argv[2], NULL); - break; - case GW_MODE_SERVER: - res = write_file(path_buff, SYS_GW_BW, argv[2], NULL); - break; - } - - goto out; - -opt_err: - fprintf(stderr, "Error - the supplied argument is invalid: %s\n", argv[1]); - fprintf(stderr, "The following values are allowed:\n"); - - ptr = sysfs_param_server; - while (*ptr) { - fprintf(stderr, " * %s\n", *ptr); - ptr++; - } - -out: - free(path_buff); - return res; -} - static void ra_mode_usage(void) { fprintf(stderr, "Usage: batctl [options] routing_algo [algorithm]\n"); diff --git a/sys.h b/sys.h index 5e98ab1..e1d0f9b 100644 --- a/sys.h +++ b/sys.h @@ -28,9 +28,6 @@ #define SYS_BATIF_PATH_FMT "/sys/class/net/%s/mesh/" #define SYS_LOG_LEVEL "log_level" #define SYS_LOG "log" -#define SYS_GW_MODE "gw_mode" -#define SYS_GW_SEL "gw_sel_class" -#define SYS_GW_BW "gw_bandwidth" #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" @@ -54,12 +51,6 @@ enum batctl_settings_list { BATCTL_SETTINGS_NUM, };
-enum gw_modes { - GW_MODE_OFF, - GW_MODE_CLIENT, - GW_MODE_SERVER, -}; - struct settings_data { const char opt_long[OPT_LONG_MAX_LEN]; const char opt_short[OPT_SHORT_MAX_LEN]; @@ -72,7 +63,6 @@ extern const char *sysfs_param_server[]; extern const struct settings_data batctl_settings[BATCTL_SETTINGS_NUM];
int handle_sys_setting(char *mesh_iface, int setting, int argc, char **argv); -int handle_gw_setting(char *mesh_iface, int argc, char **argv); int handle_ra_setting(int argc, char **argv);
#endif
More complex commands in batctl are stored in separate files which are called like the actual command name. This makes it easier to group functionality and detect which parts belong to a more complex construct.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + main.c | 3 +- routing_algo.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ routing_algo.h | 28 +++++++++++++ sys.c | 92 ----------------------------------------- sys.h | 3 -- 6 files changed, 158 insertions(+), 96 deletions(-) create mode 100644 routing_algo.c create mode 100644 routing_algo.h
diff --git a/Makefile b/Makefile index 9b960b6..9ff4fe4 100755 --- a/Makefile +++ b/Makefile @@ -40,6 +40,7 @@ OBJ += log.o OBJ += main.o OBJ += netlink.o OBJ += ping.o +OBJ += routing_algo.o OBJ += statistics.o OBJ += sys.o OBJ += tcpdump.o diff --git a/main.c b/main.c index 6160a72..4abee13 100644 --- a/main.c +++ b/main.c @@ -41,6 +41,7 @@ #include "loglevel.h" #include "log.h" #include "gw_mode.h" +#include "routing_algo.h" #include "functions.h"
char mesh_dfl_iface[] = "bat0"; @@ -153,7 +154,7 @@ int main(int argc, char **argv) #endif } else if ((strcmp(argv[1], "routing_algo") == 0) || (strcmp(argv[1], "ra") == 0)) {
- ret = handle_ra_setting(argc - 1, argv + 1); + ret = routing_algo(mesh_iface, argc - 1, argv + 1);
} else if (check_mesh_iface(mesh_iface) < 0) { fprintf(stderr, "Error - interface %s is not present or not a batman-adv interface\n", mesh_iface); diff --git a/routing_algo.c b/routing_algo.c new file mode 100644 index 0000000..89af6c5 --- /dev/null +++ b/routing_algo.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <dirent.h> +#include <errno.h> +#include <getopt.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "functions.h" +#include "main.h" +#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) +{ + fprintf(stderr, "Usage: batctl [options] routing_algo [algorithm]\n"); + fprintf(stderr, "options:\n"); + fprintf(stderr, " \t -h print this help\n"); +} + +int routing_algo(char *mesh_iface __maybe_unused, int argc, char **argv) +{ + DIR *iface_base_dir; + struct dirent *iface_dir; + int optchar; + char *path_buff; + int res = EXIT_FAILURE; + int first_iface = 1; + + while ((optchar = getopt(argc, argv, "h")) != -1) { + switch (optchar) { + case 'h': + ra_mode_usage(); + return EXIT_SUCCESS; + default: + ra_mode_usage(); + return EXIT_FAILURE; + } + } + + check_root_or_die("batctl routing_algo"); + + if (argc == 2) { + res = write_file(SYS_SELECTED_RA_PATH, "", argv[1], NULL); + goto out; + } + + path_buff = malloc(PATH_BUFF_LEN); + if (!path_buff) { + fprintf(stderr, "Error - could not allocate path buffer: out of memory ?\n"); + goto out; + } + + iface_base_dir = opendir(SYS_IFACE_PATH); + if (!iface_base_dir) { + fprintf(stderr, "Error - the directory '%s' could not be read: %s\n", + SYS_IFACE_PATH, strerror(errno)); + fprintf(stderr, "Is the batman-adv module loaded and sysfs mounted ?\n"); + goto free_buff; + } + + while ((iface_dir = readdir(iface_base_dir)) != NULL) { + snprintf(path_buff, PATH_BUFF_LEN, SYS_ROUTING_ALGO_FMT, iface_dir->d_name); + res = read_file("", path_buff, USE_READ_BUFF | SILENCE_ERRORS, 0, 0, 0); + if (res != EXIT_SUCCESS) + continue; + + if (line_ptr[strlen(line_ptr) - 1] == '\n') + line_ptr[strlen(line_ptr) - 1] = '\0'; + + if (first_iface) { + first_iface = 0; + printf("Active routing protocol configuration:\n"); + } + + printf(" * %s: %s\n", iface_dir->d_name, line_ptr); + + free(line_ptr); + line_ptr = NULL; + } + + closedir(iface_base_dir); + free(path_buff); + + if (!first_iface) + printf("\n"); + + res = read_file("", SYS_SELECTED_RA_PATH, USE_READ_BUFF, 0, 0, 0); + if (res != EXIT_SUCCESS) + return EXIT_FAILURE; + + printf("Selected routing algorithm (used when next batX interface is created):\n"); + printf(" => %s\n", line_ptr); + free(line_ptr); + line_ptr = NULL; + + print_routing_algos(); + return EXIT_SUCCESS; + +free_buff: + free(path_buff); +out: + return res; +} diff --git a/routing_algo.h b/routing_algo.h new file mode 100644 index 0000000..db246c6 --- /dev/null +++ b/routing_algo.h @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#ifndef _BATCTL_ROUTING_ALGO_H +#define _BATCTL_ROUTING_ALGO_H + +int routing_algo(char *mesh_iface, int argc, char **argv); + +#endif diff --git a/sys.c b/sys.c index 14f322c..2cb288e 100644 --- a/sys.c +++ b/sys.c @@ -205,95 +205,3 @@ int handle_sys_setting(char *mesh_iface, int setting, int argc, char **argv) free(base_dev); return res; } - -static void ra_mode_usage(void) -{ - fprintf(stderr, "Usage: batctl [options] routing_algo [algorithm]\n"); - fprintf(stderr, "options:\n"); - fprintf(stderr, " \t -h print this help\n"); -} - -int handle_ra_setting(int argc, char **argv) -{ - DIR *iface_base_dir; - struct dirent *iface_dir; - int optchar; - char *path_buff; - int res = EXIT_FAILURE; - int first_iface = 1; - - while ((optchar = getopt(argc, argv, "h")) != -1) { - switch (optchar) { - case 'h': - ra_mode_usage(); - return EXIT_SUCCESS; - default: - ra_mode_usage(); - return EXIT_FAILURE; - } - } - - check_root_or_die("batctl routing_algo"); - - if (argc == 2) { - res = write_file(SYS_SELECTED_RA_PATH, "", argv[1], NULL); - goto out; - } - - path_buff = malloc(PATH_BUFF_LEN); - if (!path_buff) { - fprintf(stderr, "Error - could not allocate path buffer: out of memory ?\n"); - goto out; - } - - iface_base_dir = opendir(SYS_IFACE_PATH); - if (!iface_base_dir) { - fprintf(stderr, "Error - the directory '%s' could not be read: %s\n", - SYS_IFACE_PATH, strerror(errno)); - fprintf(stderr, "Is the batman-adv module loaded and sysfs mounted ?\n"); - goto free_buff; - } - - while ((iface_dir = readdir(iface_base_dir)) != NULL) { - snprintf(path_buff, PATH_BUFF_LEN, SYS_ROUTING_ALGO_FMT, iface_dir->d_name); - res = read_file("", path_buff, USE_READ_BUFF | SILENCE_ERRORS, 0, 0, 0); - if (res != EXIT_SUCCESS) - continue; - - if (line_ptr[strlen(line_ptr) - 1] == '\n') - line_ptr[strlen(line_ptr) - 1] = '\0'; - - if (first_iface) { - first_iface = 0; - printf("Active routing protocol configuration:\n"); - } - - printf(" * %s: %s\n", iface_dir->d_name, line_ptr); - - free(line_ptr); - line_ptr = NULL; - } - - closedir(iface_base_dir); - free(path_buff); - - if (!first_iface) - printf("\n"); - - res = read_file("", SYS_SELECTED_RA_PATH, USE_READ_BUFF, 0, 0, 0); - if (res != EXIT_SUCCESS) - return EXIT_FAILURE; - - printf("Selected routing algorithm (used when next batX interface is created):\n"); - printf(" => %s\n", line_ptr); - free(line_ptr); - line_ptr = NULL; - - print_routing_algos(); - return EXIT_SUCCESS; - -free_buff: - free(path_buff); -out: - return res; -} diff --git a/sys.h b/sys.h index e1d0f9b..5f0280f 100644 --- a/sys.h +++ b/sys.h @@ -33,8 +33,6 @@ #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 SYS_SELECTED_RA_PATH "/sys/module/batman_adv/parameters/routing_algo" #define VLAN_ID_MAX_LEN 4
enum batctl_settings_list { @@ -63,6 +61,5 @@ extern const char *sysfs_param_server[]; extern const struct settings_data batctl_settings[BATCTL_SETTINGS_NUM];
int handle_sys_setting(char *mesh_iface, int setting, int argc, char **argv); -int handle_ra_setting(int argc, char **argv);
#endif
The command itself is called throughputmeter but the file and function is called tp_meter. Use "throughputmeter" for both to make it easier to identify the correct source file.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 2 +- main.c | 4 ++-- tp_meter.c => throughputmeter.c | 4 ++-- tp_meter.h => throughputmeter.h | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) rename tp_meter.c => throughputmeter.c (99%) rename tp_meter.h => throughputmeter.h (83%)
diff --git a/Makefile b/Makefile index 9ff4fe4..b4777b7 100755 --- a/Makefile +++ b/Makefile @@ -44,7 +44,7 @@ OBJ += routing_algo.o OBJ += statistics.o OBJ += sys.o OBJ += tcpdump.o -OBJ += tp_meter.o +OBJ += throughputmeter.o OBJ += traceroute.o OBJ += translate.o OBJ_BISECT = bisect_iv.o diff --git a/main.c b/main.c index 4abee13..34f5a62 100644 --- a/main.c +++ b/main.c @@ -35,7 +35,7 @@ #include "translate.h" #include "traceroute.h" #include "tcpdump.h" -#include "tp_meter.h" +#include "throughputmeter.h" #include "bisect_iv.h" #include "statistics.h" #include "loglevel.h" @@ -165,7 +165,7 @@ int main(int argc, char **argv)
} else if ((strcmp(argv[1], "throughputmeter") == 0) || (strcmp(argv[1], "tp") == 0)) {
- ret = tp_meter (mesh_iface, argc -1, argv + 1); + ret = throughputmeter(mesh_iface, argc -1, argv + 1);
} else if ((strcmp(argv[1], "traceroute") == 0) || (strcmp(argv[1], "tr") == 0)) {
diff --git a/tp_meter.c b/throughputmeter.c similarity index 99% rename from tp_meter.c rename to throughputmeter.c index c790485..bb53d56 100644 --- a/tp_meter.c +++ b/throughputmeter.c @@ -21,7 +21,7 @@ */
#include "main.h" -#include "tp_meter.h" +#include "throughputmeter.h"
#include <netinet/ether.h> #include <netinet/in.h> @@ -389,7 +389,7 @@ static void tp_meter_usage(void) fprintf(stderr, "\t -n don't convert addresses to bat-host names\n"); }
-int tp_meter(char *mesh_iface, int argc, char **argv) +int throughputmeter(char *mesh_iface, int argc, char **argv) { struct bat_host *bat_host; uint64_t throughput; diff --git a/tp_meter.h b/throughputmeter.h similarity index 83% rename from tp_meter.h rename to throughputmeter.h index 72006ba..2c04c12 100644 --- a/tp_meter.h +++ b/throughputmeter.h @@ -20,9 +20,9 @@ * License-Filename: LICENSES/preferred/GPL-2.0 */
-#ifndef _BATCTL_TP_METER_H -#define _BATCTL_TP_METER_H +#ifndef _BATCTL_THROUGHPUTMETER_H +#define _BATCTL_THROUGHPUTMETER_H
-int tp_meter(char *mesh_iface, int argc, char **argv); +int throughputmeter(char *mesh_iface, int argc, char **argv);
-#endif /* _BATCTL_TP_METER_H */ +#endif /* _BATCTL_THROUGHPUTMETER_H */
The registration of more complex subcommands in batctl required a lot of extra code to get it integrated in the main routine. This lead to a hard to read main function which switches between the subcommand which performs an action.
The command structure allows us to provide an simpler way to insert functionality. It currently only works for complete separated commands which operates on already existing batman-adv interface. But it is flexible enough to later also support the rest of the commands.
Signed-off-by: Sven Eckelmann sven@narfation.org --- gw_mode.c | 4 +++- gw_mode.h | 28 ------------------------- log.c | 4 +++- log.h | 28 ------------------------- loglevel.c | 4 +++- loglevel.h | 28 ------------------------- main.c | 63 ++++++++++++++++++++----------------------------------- main.h | 18 ++++++++++++++++ ping.c | 5 +++-- ping.h | 28 ------------------------- statistics.c | 7 ++++--- statistics.h | 28 ------------------------- throughputmeter.c | 5 +++-- throughputmeter.h | 28 ------------------------- traceroute.c | 5 +++-- traceroute.h | 28 ------------------------- translate.c | 5 +++-- translate.h | 28 ------------------------- 18 files changed, 66 insertions(+), 278 deletions(-) delete mode 100644 gw_mode.h delete mode 100644 log.h delete mode 100644 loglevel.h delete mode 100644 ping.h delete mode 100644 statistics.h delete mode 100644 throughputmeter.h delete mode 100644 traceroute.h delete mode 100644 translate.h
diff --git a/gw_mode.c b/gw_mode.c index a92644e..884f38e 100644 --- a/gw_mode.c +++ b/gw_mode.c @@ -45,7 +45,7 @@ static void gw_mode_usage(void) fprintf(stderr, " \t -h print this help\n"); }
-int gw_mode(char *mesh_iface, int argc, char **argv) +static int gw_mode(char *mesh_iface, int argc, char **argv) { int optchar, res = EXIT_FAILURE; char *path_buff, gw_mode; @@ -166,3 +166,5 @@ int gw_mode(char *mesh_iface, int argc, char **argv) free(path_buff); return res; } + +COMMAND(gw_mode, "gw"); diff --git a/gw_mode.h b/gw_mode.h deleted file mode 100644 index d4d3fb5..0000000 --- a/gw_mode.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: - * - * Marek Lindner mareklindner@neomailbox.ch - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - * License-Filename: LICENSES/preferred/GPL-2.0 - */ - -#ifndef _BATCTL_GW_MODE_H -#define _BATCTL_GW_MODE_H - -int gw_mode(char *mesh_iface, int argc, char **argv); - -#endif diff --git a/log.c b/log.c index fc31c66..66594f6 100644 --- a/log.c +++ b/log.c @@ -36,7 +36,7 @@ static void log_usage(void) fprintf(stderr, " \t -n don't replace mac addresses with bat-host names\n"); }
-int log_print(char *mesh_iface, int argc, char **argv) +static int log_print(char *mesh_iface, int argc, char **argv) { int optchar, res, read_opt = USE_BAT_HOSTS | LOG_MODE; char full_path[MAX_PATH+1]; @@ -68,3 +68,5 @@ int log_print(char *mesh_iface, int argc, char **argv) res = read_file(full_path, DEBUG_LOG, read_opt, 0, 0, 0); return res; } + +COMMAND_NAMED(log, "l", log_print); diff --git a/log.h b/log.h deleted file mode 100644 index 4ba00e3..0000000 --- a/log.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: - * - * Marek Lindner mareklindner@neomailbox.ch - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - * License-Filename: LICENSES/preferred/GPL-2.0 - */ - -#ifndef _BATCTL_LOG_H -#define _BATCTL_LOG_H - -int log_print(char *mesh_iface, int argc, char **argv); - -#endif diff --git a/loglevel.c b/loglevel.c index 584cb37..3d9cf3a 100644 --- a/loglevel.c +++ b/loglevel.c @@ -47,7 +47,7 @@ static void log_level_usage(void) fprintf(stderr, " \t tp Messages related to throughput meter\n"); }
-int loglevel(char *mesh_iface, int argc, char **argv) +static int loglevel(char *mesh_iface, int argc, char **argv) { int optchar, res = EXIT_FAILURE; int log_level = 0; @@ -142,3 +142,5 @@ int loglevel(char *mesh_iface, int argc, char **argv) free(path_buff); return res; } + +COMMAND(loglevel, "ll"); diff --git a/loglevel.h b/loglevel.h deleted file mode 100644 index 2644f46..0000000 --- a/loglevel.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: - * - * Marek Lindner mareklindner@neomailbox.ch - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - * License-Filename: LICENSES/preferred/GPL-2.0 - */ - -#ifndef _BATCTL_LOGLEVEL_H -#define _BATCTL_LOGLEVEL_H - -int loglevel(char *mesh_iface, int argc, char **argv); - -#endif diff --git a/main.c b/main.c index 34f5a62..14f4774 100644 --- a/main.c +++ b/main.c @@ -31,22 +31,17 @@ #include "sys.h" #include "debug.h" #include "interface.h" -#include "ping.h" -#include "translate.h" -#include "traceroute.h" #include "tcpdump.h" -#include "throughputmeter.h" #include "bisect_iv.h" -#include "statistics.h" -#include "loglevel.h" -#include "log.h" -#include "gw_mode.h" #include "routing_algo.h" #include "functions.h"
char mesh_dfl_iface[] = "bat0"; char module_ver_path[] = "/sys/module/batman_adv/version";
+extern const struct command *__start___command[]; +extern const struct command *__stop___command[]; + static void print_usage(void) { int i, opt_indent; @@ -96,8 +91,26 @@ static void print_usage(void) #endif }
+static const struct command *find_command(const char *name) +{ + const struct command **p; + + for (p = __start___command; p < __stop___command; p++) { + const struct command *cmd = *p; + + if (strcmp(cmd->name, name) == 0) + return cmd; + + if (strcmp(cmd->abbr, name) == 0) + return cmd; + } + + return NULL; +} + int main(int argc, char **argv) { + const struct command *cmd; int i, ret = EXIT_FAILURE; char *mesh_iface = mesh_dfl_iface;
@@ -159,38 +172,8 @@ int main(int argc, char **argv) } else if (check_mesh_iface(mesh_iface) < 0) { fprintf(stderr, "Error - interface %s is not present or not a batman-adv interface\n", mesh_iface); exit(EXIT_FAILURE); - } else if ((strcmp(argv[1], "ping") == 0) || (strcmp(argv[1], "p") == 0)) { - - ret = ping(mesh_iface, argc - 1, argv + 1); - - } else if ((strcmp(argv[1], "throughputmeter") == 0) || (strcmp(argv[1], "tp") == 0)) { - - ret = throughputmeter(mesh_iface, argc -1, argv + 1); - - } else if ((strcmp(argv[1], "traceroute") == 0) || (strcmp(argv[1], "tr") == 0)) { - - ret = traceroute(mesh_iface, argc - 1, argv + 1); - - } else if ((strcmp(argv[1], "loglevel") == 0) || (strcmp(argv[1], "ll") == 0)) { - - ret = loglevel(mesh_iface, argc - 1, argv + 1); - - } else if ((strcmp(argv[1], "log") == 0) || (strcmp(argv[1], "l") == 0)) { - - ret = log_print(mesh_iface, argc - 1, argv + 1); - - } else if ((strcmp(argv[1], "gw_mode") == 0) || (strcmp(argv[1], "gw") == 0)) { - - ret = gw_mode(mesh_iface, argc - 1, argv + 1); - - } else if ((strcmp(argv[1], "statistics") == 0) || (strcmp(argv[1], "s") == 0)) { - - ret = statistics(mesh_iface, argc - 1, argv + 1); - - } else if ((strcmp(argv[1], "translate") == 0) || (strcmp(argv[1], "t") == 0)) { - - ret = translate(mesh_iface, argc - 1, argv + 1); - + } else if ((cmd = find_command(argv[1]))) { + ret = cmd->handler(mesh_iface, argc - 1, argv + 1); } else {
for (i = 0; i < BATCTL_SETTINGS_NUM; i++) { diff --git a/main.h b/main.h index e8c6db7..f7e2f64 100644 --- a/main.h +++ b/main.h @@ -57,4 +57,22 @@ extern char module_ver_path[]; #define BATADV_PRINT_VID(vid) (vid & BATADV_VLAN_HAS_TAG ? \ (int)(vid & VLAN_VID_MASK) : -1)
+struct command { + const char *name; + const char *abbr; + int (*handler)(char *mesh_iface, int argc, char **argv); +}; + +#define COMMAND_NAMED(_name, _abbr, _handler) \ + static const struct command command_ ## _name = { \ + .name = (#_name), \ + .abbr = _abbr, \ + .handler = (_handler), \ + }; \ + static const struct command *__command_ ## _name \ + __attribute__((__used__)) __attribute__ ((__section__ ("__command"))) = &command_ ## _name + +#define COMMAND(_handler, _abbr) \ + COMMAND_NAMED(_handler, _abbr, _handler) + #endif diff --git a/ping.c b/ping.c index dc88e22..a4a1851 100644 --- a/ping.c +++ b/ping.c @@ -39,7 +39,6 @@
#include "batadv_packet.h" #include "main.h" -#include "ping.h" #include "functions.h" #include "bat-hosts.h" #include "debugfs.h" @@ -73,7 +72,7 @@ static void sig_handler(int sig) } }
-int ping(char *mesh_iface, int argc, char **argv) +static int ping(char *mesh_iface, int argc, char **argv) { struct batadv_icmp_packet_rr icmp_packet_out, icmp_packet_in; struct timeval tv; @@ -345,3 +344,5 @@ int ping(char *mesh_iface, int argc, char **argv) bat_hosts_free(); return ret; } + +COMMAND(ping, "p"); diff --git a/ping.h b/ping.h deleted file mode 100644 index f09ffb2..0000000 --- a/ping.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: - * - * Marek Lindner mareklindner@neomailbox.ch - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - * License-Filename: LICENSES/preferred/GPL-2.0 - */ - -#ifndef _BATCTL_PING_H -#define _BATCTL_PING_H - -int ping(char *mesh_iface, int argc, char **argv); - -#endif diff --git a/statistics.c b/statistics.c index 8a889ca..dea3ac1 100644 --- a/statistics.c +++ b/statistics.c @@ -35,7 +35,6 @@ #include <stdint.h>
#include "main.h" -#include "statistics.h"
void check_root_or_die(const char *cmd);
@@ -103,8 +102,8 @@ static int statistics_custom_get(int fd, struct ifreq *ifr) return ret; }
-int statistics(char *mesh_iface, int argc __maybe_unused, - char **argv __maybe_unused) +static int statistics(char *mesh_iface, int argc __maybe_unused, + char **argv __maybe_unused) { struct ifreq ifr; int fd = -1, ret = EXIT_FAILURE; @@ -126,3 +125,5 @@ int statistics(char *mesh_iface, int argc __maybe_unused, close(fd); return ret; } + +COMMAND(statistics, "s"); diff --git a/statistics.h b/statistics.h deleted file mode 100644 index 3737a48..0000000 --- a/statistics.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2012-2018 B.A.T.M.A.N. contributors: - * - * Marek Lindner mareklindner@neomailbox.ch - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - * License-Filename: LICENSES/preferred/GPL-2.0 - */ - -#ifndef _BATCTL_STATISTICS_H -#define _BATCTL_STATISTICS_H - -int statistics(char *mesh_iface, int argc, char **argv); - -#endif diff --git a/throughputmeter.c b/throughputmeter.c index bb53d56..372bfc4 100644 --- a/throughputmeter.c +++ b/throughputmeter.c @@ -21,7 +21,6 @@ */
#include "main.h" -#include "throughputmeter.h"
#include <netinet/ether.h> #include <netinet/in.h> @@ -389,7 +388,7 @@ static void tp_meter_usage(void) fprintf(stderr, "\t -n don't convert addresses to bat-host names\n"); }
-int throughputmeter(char *mesh_iface, int argc, char **argv) +static int throughputmeter(char *mesh_iface, int argc, char **argv) { struct bat_host *bat_host; uint64_t throughput; @@ -543,3 +542,5 @@ int throughputmeter(char *mesh_iface, int argc, char **argv) bat_hosts_free(); return ret; } + +COMMAND(throughputmeter, "tp"); diff --git a/throughputmeter.h b/throughputmeter.h deleted file mode 100644 index 2c04c12..0000000 --- a/throughputmeter.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2013-2018 B.A.T.M.A.N. contributors: - * - * Antonio Quartulli a@unstable.cc - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - * License-Filename: LICENSES/preferred/GPL-2.0 - */ - -#ifndef _BATCTL_THROUGHPUTMETER_H -#define _BATCTL_THROUGHPUTMETER_H - -int throughputmeter(char *mesh_iface, int argc, char **argv); - -#endif /* _BATCTL_THROUGHPUTMETER_H */ diff --git a/traceroute.c b/traceroute.c index ba7e27d..5c55c7b 100644 --- a/traceroute.c +++ b/traceroute.c @@ -36,7 +36,6 @@
#include "batadv_packet.h" #include "main.h" -#include "traceroute.h" #include "functions.h" #include "bat-hosts.h" #include "debugfs.h" @@ -56,7 +55,7 @@ static void traceroute_usage(void) fprintf(stderr, " \t -T don't try to translate mac to originator address\n"); }
-int traceroute(char *mesh_iface, int argc, char **argv) +static int traceroute(char *mesh_iface, int argc, char **argv) { struct batadv_icmp_packet icmp_packet_out, icmp_packet_in; struct bat_host *bat_host; @@ -231,3 +230,5 @@ int traceroute(char *mesh_iface, int argc, char **argv) bat_hosts_free(); return ret; } + +COMMAND(traceroute, "tr"); diff --git a/traceroute.h b/traceroute.h deleted file mode 100644 index ffe0252..0000000 --- a/traceroute.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: - * - * Marek Lindner mareklindner@neomailbox.ch - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - * License-Filename: LICENSES/preferred/GPL-2.0 - */ - -#ifndef _BATCTL_TRACEROUTE_H -#define _BATCTL_TRACEROUTE_H - -int traceroute(char *mesh_iface, int argc, char **argv); - -#endif diff --git a/translate.c b/translate.c index 9059f20..ec6baaf 100644 --- a/translate.c +++ b/translate.c @@ -24,7 +24,6 @@ #include <stdlib.h>
#include "main.h" -#include "translate.h" #include "functions.h" #include "bat-hosts.h"
@@ -34,7 +33,7 @@ static void translate_usage(void) fprintf(stderr, "Usage: batctl [options] translate mac|bat-host|host_name|IPv4_address\n"); }
-int translate(char *mesh_iface, int argc, char **argv) +static int translate(char *mesh_iface, int argc, char **argv) { struct ether_addr *dst_mac = NULL; struct bat_host *bat_host; @@ -78,3 +77,5 @@ int translate(char *mesh_iface, int argc, char **argv) bat_hosts_free(); return ret; } + +COMMAND(translate, "t"); diff --git a/translate.h b/translate.h deleted file mode 100644 index 8155827..0000000 --- a/translate.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: - * - * Marek Lindner mareklindner@neomailbox.ch - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - * License-Filename: LICENSES/preferred/GPL-2.0 - */ - -#ifndef _BATCTL_TRANSLATE_H -#define _BATCTL_TRANSLATE_H - -int translate(char *mesh_iface, int argc, char **argv); - -#endif
Some commands have different prerequists than other commands. Using flags to specify them would allow batctl to use the same command structure for the non-mesh_iface based command as for mesh_iface based commands.
Signed-off-by: Sven Eckelmann sven@narfation.org --- gw_mode.c | 2 +- log.c | 2 +- loglevel.c | 2 +- main.c | 13 ++++++++++--- main.h | 12 +++++++++--- ping.c | 2 +- statistics.c | 2 +- throughputmeter.c | 2 +- traceroute.c | 2 +- translate.c | 2 +- 10 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/gw_mode.c b/gw_mode.c index 884f38e..f07dc99 100644 --- a/gw_mode.c +++ b/gw_mode.c @@ -167,4 +167,4 @@ static int gw_mode(char *mesh_iface, int argc, char **argv) return res; }
-COMMAND(gw_mode, "gw"); +COMMAND(gw_mode, "gw", COMMAND_FLAG_MESH_IFACE); diff --git a/log.c b/log.c index 66594f6..585f1c9 100644 --- a/log.c +++ b/log.c @@ -69,4 +69,4 @@ static int log_print(char *mesh_iface, int argc, char **argv) return res; }
-COMMAND_NAMED(log, "l", log_print); +COMMAND_NAMED(log, "l", log_print, COMMAND_FLAG_MESH_IFACE); diff --git a/loglevel.c b/loglevel.c index 3d9cf3a..06519e7 100644 --- a/loglevel.c +++ b/loglevel.c @@ -143,4 +143,4 @@ static int loglevel(char *mesh_iface, int argc, char **argv) return res; }
-COMMAND(loglevel, "ll"); +COMMAND(loglevel, "ll", COMMAND_FLAG_MESH_IFACE); diff --git a/main.c b/main.c index 14f4774..dacfb12 100644 --- a/main.c +++ b/main.c @@ -169,12 +169,19 @@ int main(int argc, char **argv)
ret = routing_algo(mesh_iface, argc - 1, argv + 1);
- } else if (check_mesh_iface(mesh_iface) < 0) { - fprintf(stderr, "Error - interface %s is not present or not a batman-adv interface\n", mesh_iface); - exit(EXIT_FAILURE); } else if ((cmd = find_command(argv[1]))) { + if (cmd->flags & COMMAND_FLAG_MESH_IFACE && + check_mesh_iface(mesh_iface) < 0) { + fprintf(stderr, "Error - interface %s is not present or not a batman-adv interface\n", mesh_iface); + exit(EXIT_FAILURE); + } + ret = cmd->handler(mesh_iface, argc - 1, argv + 1); } else { + if (check_mesh_iface(mesh_iface) < 0) { + fprintf(stderr, "Error - interface %s is not present or not a batman-adv interface\n", mesh_iface); + exit(EXIT_FAILURE); + }
for (i = 0; i < BATCTL_SETTINGS_NUM; i++) { if ((strcmp(argv[1], batctl_settings[i].opt_long) != 0) && diff --git a/main.h b/main.h index f7e2f64..c461d6b 100644 --- a/main.h +++ b/main.h @@ -57,22 +57,28 @@ extern char module_ver_path[]; #define BATADV_PRINT_VID(vid) (vid & BATADV_VLAN_HAS_TAG ? \ (int)(vid & VLAN_VID_MASK) : -1)
+enum command_flags { + COMMAND_FLAG_MESH_IFACE = BIT(0), +}; + struct command { const char *name; const char *abbr; int (*handler)(char *mesh_iface, int argc, char **argv); + uint32_t flags; };
-#define COMMAND_NAMED(_name, _abbr, _handler) \ +#define COMMAND_NAMED(_name, _abbr, _handler, _flags) \ static const struct command command_ ## _name = { \ .name = (#_name), \ .abbr = _abbr, \ .handler = (_handler), \ + .flags = (_flags), \ }; \ static const struct command *__command_ ## _name \ __attribute__((__used__)) __attribute__ ((__section__ ("__command"))) = &command_ ## _name
-#define COMMAND(_handler, _abbr) \ - COMMAND_NAMED(_handler, _abbr, _handler) +#define COMMAND(_handler, _abbr, _flags) \ + COMMAND_NAMED(_handler, _abbr, _handler, _flags)
#endif diff --git a/ping.c b/ping.c index a4a1851..2da49d4 100644 --- a/ping.c +++ b/ping.c @@ -345,4 +345,4 @@ static int ping(char *mesh_iface, int argc, char **argv) return ret; }
-COMMAND(ping, "p"); +COMMAND(ping, "p", COMMAND_FLAG_MESH_IFACE); diff --git a/statistics.c b/statistics.c index dea3ac1..cb6c1e8 100644 --- a/statistics.c +++ b/statistics.c @@ -126,4 +126,4 @@ static int statistics(char *mesh_iface, int argc __maybe_unused, return ret; }
-COMMAND(statistics, "s"); +COMMAND(statistics, "s", COMMAND_FLAG_MESH_IFACE); diff --git a/throughputmeter.c b/throughputmeter.c index 372bfc4..e9e318c 100644 --- a/throughputmeter.c +++ b/throughputmeter.c @@ -543,4 +543,4 @@ static int throughputmeter(char *mesh_iface, int argc, char **argv) return ret; }
-COMMAND(throughputmeter, "tp"); +COMMAND(throughputmeter, "tp", COMMAND_FLAG_MESH_IFACE); diff --git a/traceroute.c b/traceroute.c index 5c55c7b..1352201 100644 --- a/traceroute.c +++ b/traceroute.c @@ -231,4 +231,4 @@ static int traceroute(char *mesh_iface, int argc, char **argv) return ret; }
-COMMAND(traceroute, "tr"); +COMMAND(traceroute, "tr", COMMAND_FLAG_MESH_IFACE); diff --git a/translate.c b/translate.c index ec6baaf..d2d34f5 100644 --- a/translate.c +++ b/translate.c @@ -78,4 +78,4 @@ static int translate(char *mesh_iface, int argc, char **argv) return ret; }
-COMMAND(translate, "t"); +COMMAND(translate, "t", COMMAND_FLAG_MESH_IFACE);
The command datastructure was extended to be usable for mesh_iface and non-mesh_iface subcommands. The referenced subcommands only have to use the same function signature to work correctly.
The introduction of dummy parameter to the functions allows therefore to convert all non-settings and non-debug-tables subcommands to the new infrastructure.
Signed-off-by: Sven Eckelmann sven@narfation.org --- bisect_iv.c | 5 ++++- bisect_iv.h | 4 ---- interface.c | 6 +++--- interface.h | 30 ------------------------------ main.c | 23 +---------------------- routing_algo.c | 4 +++- routing_algo.h | 28 ---------------------------- tcpdump.c | 4 +++- tcpdump.h | 2 -- 9 files changed, 14 insertions(+), 92 deletions(-) delete mode 100644 interface.h delete mode 100644 routing_algo.h
diff --git a/bisect_iv.c b/bisect_iv.c index d71ceda..f87f915 100644 --- a/bisect_iv.c +++ b/bisect_iv.c @@ -32,6 +32,7 @@ #include "bisect_iv.h" #include "bat-hosts.h" #include "hash.h" +#include "main.h" #include "functions.h"
static struct hashtable_t *node_hash = NULL; @@ -1440,7 +1441,7 @@ static int get_orig_addr(char *orig_name, char *orig_addr) return 0; }
-int bisect_iv(int argc, char **argv) +static int bisect_iv(char *mesh_iface __maybe_unused, int argc, char **argv) { int ret = EXIT_FAILURE, res, optchar, found_args = 1; int read_opt = USE_BAT_HOSTS, num_parsed_files; @@ -1593,3 +1594,5 @@ int bisect_iv(int argc, char **argv) bat_hosts_free(); return ret; } + +COMMAND(bisect_iv, "bisect_iv", 0); diff --git a/bisect_iv.h b/bisect_iv.h index 7932c2f..5f5200c 100644 --- a/bisect_iv.h +++ b/bisect_iv.h @@ -33,10 +33,6 @@ #define RT_FLAG_UPDATE 2 #define RT_FLAG_DELETE 3
-int bisect_iv(int argc, char **argv); - - - struct bat_node { char name[NAME_LEN]; struct list_head orig_event_list; diff --git a/interface.c b/interface.c index 5951b47..485ed0a 100644 --- a/interface.c +++ b/interface.c @@ -20,8 +20,6 @@ * License-Filename: LICENSES/preferred/GPL-2.0 */
-#include "interface.h" - #include <unistd.h> #include <stdio.h> #include <stdbool.h> @@ -299,7 +297,7 @@ static int set_master_interface(const char *iface, unsigned int ifmaster) return err; }
-int interface(char *mesh_iface, int argc, char **argv) +static int interface(char *mesh_iface, int argc, char **argv) { int i, optchar; int ret; @@ -459,3 +457,5 @@ int interface(char *mesh_iface, int argc, char **argv) err: return EXIT_FAILURE; } + +COMMAND(interface, "if", 0); diff --git a/interface.h b/interface.h deleted file mode 100644 index 83ca129..0000000 --- a/interface.h +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: - * - * Marek Lindner mareklindner@neomailbox.ch - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - * License-Filename: LICENSES/preferred/GPL-2.0 - */ - -#ifndef _BATCTL_INTERFACE_H -#define _BATCTL_INTERFACE_H - -#include "main.h" - -int interface(char *mesh_iface, int argc, char **argv); - -#endif diff --git a/main.c b/main.c index dacfb12..fa4371c 100644 --- a/main.c +++ b/main.c @@ -30,10 +30,6 @@ #include "main.h" #include "sys.h" #include "debug.h" -#include "interface.h" -#include "tcpdump.h" -#include "bisect_iv.h" -#include "routing_algo.h" #include "functions.h"
char mesh_dfl_iface[] = "bat0"; @@ -152,24 +148,7 @@ int main(int argc, char **argv) exit(EXIT_SUCCESS); }
- if ((strcmp(argv[1], "interface") == 0) || (strcmp(argv[1], "if") == 0)) { - - ret = interface(mesh_iface, argc - 1, argv + 1); - - } else if ((strcmp(argv[1], "tcpdump") == 0) || (strcmp(argv[1], "td") == 0)) { - - ret = tcpdump(argc - 1, argv + 1); - -#ifdef BATCTL_BISECT - } else if ((strcmp(argv[1], "bisect_iv") == 0)) { - - ret = bisect_iv(argc - 1, argv + 1); -#endif - } else if ((strcmp(argv[1], "routing_algo") == 0) || (strcmp(argv[1], "ra") == 0)) { - - ret = routing_algo(mesh_iface, argc - 1, argv + 1); - - } else if ((cmd = find_command(argv[1]))) { + if ((cmd = find_command(argv[1]))) { if (cmd->flags & COMMAND_FLAG_MESH_IFACE && check_mesh_iface(mesh_iface) < 0) { fprintf(stderr, "Error - interface %s is not present or not a batman-adv interface\n", mesh_iface); diff --git a/routing_algo.c b/routing_algo.c index 89af6c5..2026224 100644 --- a/routing_algo.c +++ b/routing_algo.c @@ -41,7 +41,7 @@ static void ra_mode_usage(void) fprintf(stderr, " \t -h print this help\n"); }
-int routing_algo(char *mesh_iface __maybe_unused, int argc, char **argv) +static int routing_algo(char *mesh_iface __maybe_unused, int argc, char **argv) { DIR *iface_base_dir; struct dirent *iface_dir; @@ -125,3 +125,5 @@ int routing_algo(char *mesh_iface __maybe_unused, int argc, char **argv) out: return res; } + +COMMAND(routing_algo, "ra", 0); diff --git a/routing_algo.h b/routing_algo.h deleted file mode 100644 index db246c6..0000000 --- a/routing_algo.h +++ /dev/null @@ -1,28 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: - * - * Marek Lindner mareklindner@neomailbox.ch - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - * License-Filename: LICENSES/preferred/GPL-2.0 - */ - -#ifndef _BATCTL_ROUTING_ALGO_H -#define _BATCTL_ROUTING_ALGO_H - -int routing_algo(char *mesh_iface, int argc, char **argv); - -#endif diff --git a/tcpdump.c b/tcpdump.c index dc4ccd3..fd2b35a 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -1210,7 +1210,7 @@ static void sig_handler(int sig) } }
-int tcpdump(int argc, char **argv) +static int tcpdump(char *mesh_iface __maybe_unused, int argc, char **argv) { struct timeval tv; struct dump_if *dump_if, *dump_if_tmp; @@ -1351,3 +1351,5 @@ int tcpdump(int argc, char **argv) bat_hosts_free(); return ret; } + +COMMAND(tcpdump, "td", 0); diff --git a/tcpdump.h b/tcpdump.h index f73211b..db92fce 100644 --- a/tcpdump.h +++ b/tcpdump.h @@ -113,6 +113,4 @@ struct prism_header { #define PRISM_HEADER_LEN sizeof(struct prism_header) #define RADIOTAP_HEADER_LEN sizeof(struct radiotap_header)
-int tcpdump(int argc, char **argv); - #endif
The handwritten option parser is rather fragile and doesn't support all features of a normal commandline option parser. Instead use getopt to handle the most critical parts and keep it more flexible.
Signed-off-by: Sven Eckelmann sven@narfation.org --- main.c | 95 +++++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 56 insertions(+), 39 deletions(-)
diff --git a/main.c b/main.c index fa4371c..f5df477 100644 --- a/main.c +++ b/main.c @@ -22,6 +22,7 @@
+#include <getopt.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -87,6 +88,25 @@ static void print_usage(void) #endif }
+static void version(void) +{ + int ret; + + printf("batctl %s [batman-adv: ", SOURCE_VERSION); + + ret = read_file("", module_ver_path, USE_READ_BUFF | SILENCE_ERRORS, 0, 0, 0); + if ((line_ptr) && (line_ptr[strlen(line_ptr) - 1] == '\n')) + line_ptr[strlen(line_ptr) - 1] = '\0'; + + if (ret == EXIT_SUCCESS) + printf("%s]\n", line_ptr); + else + printf("module not loaded]\n"); + + free(line_ptr); + exit(EXIT_SUCCESS); +} + static const struct command *find_command(const char *name) { const struct command **p; @@ -109,53 +129,48 @@ int main(int argc, char **argv) const struct command *cmd; int i, ret = EXIT_FAILURE; char *mesh_iface = mesh_dfl_iface; - - if ((argc > 1) && (strcmp(argv[1], "-m") == 0)) { - if (argc < 3) { - fprintf(stderr, "Error - the option '-m' needs a parameter\n"); + int opt; + + while ((opt = getopt(argc, argv, "+hm:v")) != -1) { + switch (opt) { + case 'h': + print_usage(); + exit(EXIT_SUCCESS); + break; + case 'm': + if (mesh_iface != mesh_dfl_iface) { + fprintf(stderr, + "Error - multiple mesh interfaces specified\n"); + goto err; + } + + mesh_iface = argv[2]; + break; + case 'v': + version(); + break; + default: goto err; } - - mesh_iface = argv[2]; - - argv += 2; - argc -= 2; }
- if (argc < 2) { + if (optind >= argc) { fprintf(stderr, "Error - no command specified\n"); goto err; }
- if (strcmp(argv[1], "-h") == 0) { - print_usage(); - exit(EXIT_SUCCESS); - } - - if (strcmp(argv[1], "-v") == 0) { - printf("batctl %s [batman-adv: ", SOURCE_VERSION); - - ret = read_file("", module_ver_path, USE_READ_BUFF | SILENCE_ERRORS, 0, 0, 0); - if ((line_ptr) && (line_ptr[strlen(line_ptr) - 1] == '\n')) - line_ptr[strlen(line_ptr) - 1] = '\0'; - - if (ret == EXIT_SUCCESS) - printf("%s]\n", line_ptr); - else - printf("module not loaded]\n"); - - free(line_ptr); - exit(EXIT_SUCCESS); - } + argv += optind; + argc -= optind; + optind = 0;
- if ((cmd = find_command(argv[1]))) { + if ((cmd = find_command(argv[0]))) { if (cmd->flags & COMMAND_FLAG_MESH_IFACE && check_mesh_iface(mesh_iface) < 0) { fprintf(stderr, "Error - interface %s is not present or not a batman-adv interface\n", mesh_iface); exit(EXIT_FAILURE); }
- ret = cmd->handler(mesh_iface, argc - 1, argv + 1); + ret = cmd->handler(mesh_iface, argc, argv); } else { if (check_mesh_iface(mesh_iface) < 0) { fprintf(stderr, "Error - interface %s is not present or not a batman-adv interface\n", mesh_iface); @@ -163,24 +178,26 @@ int main(int argc, char **argv) }
for (i = 0; i < BATCTL_SETTINGS_NUM; i++) { - if ((strcmp(argv[1], batctl_settings[i].opt_long) != 0) && - (strcmp(argv[1], batctl_settings[i].opt_short) != 0)) + if ((strcmp(argv[0], batctl_settings[i].opt_long) != 0) && + (strcmp(argv[0], batctl_settings[i].opt_short) != 0)) continue;
- ret = handle_sys_setting(mesh_iface, i, argc - 1, argv + 1); + ret = handle_sys_setting(mesh_iface, i, argc, argv); goto out; }
for (i = 0; i < BATCTL_TABLE_NUM; i++) { - if ((strcmp(argv[1], batctl_debug_tables[i].opt_long) != 0) && - (strcmp(argv[1], batctl_debug_tables[i].opt_short) != 0)) + if ((strcmp(argv[0], batctl_debug_tables[i].opt_long) != 0) && + (strcmp(argv[0], batctl_debug_tables[i].opt_short) != 0)) continue;
- ret = handle_debug_table(mesh_iface, i, argc - 1, argv + 1); + ret = handle_debug_table(mesh_iface, i, argc, argv); goto out; }
- fprintf(stderr, "Error - no valid command or debug table specified: %s\n", argv[1]); + fprintf(stderr, + "Error - no valid command or debug table specified: %s\n", + argv[0]); print_usage(); }
The single line usage information for a subcommand is the simplest way to learn how to use a command. It is displayed when either the -h option is used or when the initial part of the batctl command is incorrect.
Since the commands are no longer registered manually in the main function, the usage line should also no longer be stored there. Instead add it to the same file as the command itself.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 13 +++++++------ bisect_iv.c | 3 ++- gw_mode.c | 3 ++- interface.c | 3 ++- log.c | 3 ++- loglevel.c | 3 ++- main.c | 31 +++++++++++++++---------------- main.h | 8 +++++--- ping.c | 3 ++- routing_algo.c | 3 ++- statistics.c | 3 ++- tcpdump.c | 3 ++- throughputmeter.c | 3 ++- traceroute.c | 3 ++- translate.c | 3 ++- 15 files changed, 51 insertions(+), 37 deletions(-)
diff --git a/Makefile b/Makefile index b4777b7..842795b 100755 --- a/Makefile +++ b/Makefile @@ -26,7 +26,13 @@ export CONFIG_BATCTL_BISECT=n
# batctl build BINARY_NAME = batctl + +OBJ_BISECT = bisect_iv.o + OBJ += bat-hosts.o +ifeq ($(CONFIG_BATCTL_BISECT),y) +OBJ += $(OBJ_BISECT) +endif OBJ += debugfs.o OBJ += debug.o OBJ += functions.o @@ -47,7 +53,7 @@ OBJ += tcpdump.o OBJ += throughputmeter.o OBJ += traceroute.o OBJ += translate.o -OBJ_BISECT = bisect_iv.o + MANPAGE = man/batctl.8
# batctl flags and options @@ -95,11 +101,6 @@ CFLAGS += $(LIBNL_GENL_CFLAGS) LDLIBS += $(LIBNL_GENL_LDLIBS)
# standard build tools -ifeq ($(CONFIG_BATCTL_BISECT),y) -OBJ += $(OBJ_BISECT) -CPPFLAGS += -DBATCTL_BISECT -endif - CC ?= gcc RM ?= rm -f INSTALL ?= install diff --git a/bisect_iv.c b/bisect_iv.c index f87f915..6da82b9 100644 --- a/bisect_iv.c +++ b/bisect_iv.c @@ -1595,4 +1595,5 @@ static int bisect_iv(char *mesh_iface __maybe_unused, int argc, char **argv) return ret; }
-COMMAND(bisect_iv, "bisect_iv", 0); +COMMAND(bisect_iv, "bisect_iv", 0, + "<file1> .. <fileN>\tanalyze given batman iv log files for routing stability"); diff --git a/gw_mode.c b/gw_mode.c index f07dc99..da22ff0 100644 --- a/gw_mode.c +++ b/gw_mode.c @@ -167,4 +167,5 @@ static int gw_mode(char *mesh_iface, int argc, char **argv) return res; }
-COMMAND(gw_mode, "gw", COMMAND_FLAG_MESH_IFACE); +COMMAND(gw_mode, "gw", COMMAND_FLAG_MESH_IFACE, + "[mode] \tdisplay or modify the gateway mode"); diff --git a/interface.c b/interface.c index 485ed0a..d2883a9 100644 --- a/interface.c +++ b/interface.c @@ -458,4 +458,5 @@ static int interface(char *mesh_iface, int argc, char **argv) return EXIT_FAILURE; }
-COMMAND(interface, "if", 0); +COMMAND(interface, "if", 0, + "[add|del iface(s)]\tdisplay or modify the interface settings"); diff --git a/log.c b/log.c index 585f1c9..e28466d 100644 --- a/log.c +++ b/log.c @@ -69,4 +69,5 @@ static int log_print(char *mesh_iface, int argc, char **argv) return res; }
-COMMAND_NAMED(log, "l", log_print, COMMAND_FLAG_MESH_IFACE); +COMMAND_NAMED(log, "l", log_print, COMMAND_FLAG_MESH_IFACE, + " \tread the log produced by the kernel module"); diff --git a/loglevel.c b/loglevel.c index 06519e7..3dc1a1c 100644 --- a/loglevel.c +++ b/loglevel.c @@ -143,4 +143,5 @@ static int loglevel(char *mesh_iface, int argc, char **argv) return res; }
-COMMAND(loglevel, "ll", COMMAND_FLAG_MESH_IFACE); +COMMAND(loglevel, "ll", COMMAND_FLAG_MESH_IFACE, + "[level] \tdisplay or modify the log level"); diff --git a/main.c b/main.c index f5df477..b9b19de 100644 --- a/main.c +++ b/main.c @@ -41,7 +41,9 @@ extern const struct command *__stop___command[];
static void print_usage(void) { + const struct command **p; int i, opt_indent; + char buf[32];
fprintf(stderr, "Usage: batctl [options] command|debug table [parameters]\n"); fprintf(stderr, "options:\n"); @@ -51,7 +53,19 @@ static void print_usage(void) fprintf(stderr, "\n");
fprintf(stderr, "commands:\n"); - fprintf(stderr, " \tinterface|if [add|del iface(s)]\tdisplay or modify the interface settings\n"); + + for (p = __start___command; p < __stop___command; p++) { + const struct command *cmd = *p; + + if (strcmp(cmd->name, cmd->abbr) == 0) + snprintf(buf, sizeof(buf), "%s", cmd->name); + else + snprintf(buf, sizeof(buf), "%s|%s", cmd->name, + cmd->abbr); + + fprintf(stderr, " \t%-27s%s\n", buf, cmd->usage); + } + for (i = 0; i < BATCTL_SETTINGS_NUM; i++) { fprintf(stderr, " \t%s|%s", batctl_settings[i].opt_long, batctl_settings[i].opt_short); opt_indent = strlen(batctl_settings[i].opt_long) + strlen(batctl_settings[i].opt_short); @@ -66,26 +80,11 @@ static void print_usage(void) fprintf(stderr, " display or modify %s setting\n", batctl_settings[i].opt_long); } - fprintf(stderr, " \tloglevel|ll [level] \tdisplay or modify the log level\n"); - fprintf(stderr, " \tlog|l \tread the log produced by the kernel module\n"); - fprintf(stderr, " \tgw_mode|gw [mode] \tdisplay or modify the gateway mode\n"); - fprintf(stderr, " \trouting_algo|ra [mode] \tdisplay or modify the routing algorithm\n"); fprintf(stderr, "\n");
fprintf(stderr, "debug tables: \tdisplay the corresponding debug table\n"); for (i = 0; i < BATCTL_TABLE_NUM; i++) fprintf(stderr, " \t%s|%s\n", batctl_debug_tables[i].opt_long, batctl_debug_tables[i].opt_short); - - fprintf(stderr, "\n"); - fprintf(stderr, " \tstatistics|s \tprint mesh statistics\n"); - fprintf(stderr, " \tping|p <destination> \tping another batman adv host via layer 2\n"); - fprintf(stderr, " \ttraceroute|tr <destination> \ttraceroute another batman adv host via layer 2\n"); - fprintf(stderr, " \ttcpdump|td <interface> \ttcpdump layer 2 traffic on the given interface\n"); - printf(" \tthroughputmeter|tp <destination> \tstart a throughput measurement\n"); - fprintf(stderr, " \ttranslate|t <destination> \ttranslate a destination to the originator responsible for it\n"); -#ifdef BATCTL_BISECT - fprintf(stderr, " \tbisect_iv <file1> .. <fileN>\tanalyze given batman iv log files for routing stability\n"); -#endif }
static void version(void) diff --git a/main.h b/main.h index c461d6b..b39e350 100644 --- a/main.h +++ b/main.h @@ -66,19 +66,21 @@ struct command { const char *abbr; int (*handler)(char *mesh_iface, int argc, char **argv); uint32_t flags; + const char *usage; };
-#define COMMAND_NAMED(_name, _abbr, _handler, _flags) \ +#define COMMAND_NAMED(_name, _abbr, _handler, _flags, _usage) \ static const struct command command_ ## _name = { \ .name = (#_name), \ .abbr = _abbr, \ .handler = (_handler), \ .flags = (_flags), \ + .usage = (_usage), \ }; \ static const struct command *__command_ ## _name \ __attribute__((__used__)) __attribute__ ((__section__ ("__command"))) = &command_ ## _name
-#define COMMAND(_handler, _abbr, _flags) \ - COMMAND_NAMED(_handler, _abbr, _handler, _flags) +#define COMMAND(_handler, _abbr, _flags, _usage) \ + COMMAND_NAMED(_handler, _abbr, _handler, _flags, _usage)
#endif diff --git a/ping.c b/ping.c index 2da49d4..efaf011 100644 --- a/ping.c +++ b/ping.c @@ -345,4 +345,5 @@ static int ping(char *mesh_iface, int argc, char **argv) return ret; }
-COMMAND(ping, "p", COMMAND_FLAG_MESH_IFACE); +COMMAND(ping, "p", COMMAND_FLAG_MESH_IFACE, + "<destination> \tping another batman adv host via layer 2"); diff --git a/routing_algo.c b/routing_algo.c index 2026224..8cc4ff1 100644 --- a/routing_algo.c +++ b/routing_algo.c @@ -126,4 +126,5 @@ static int routing_algo(char *mesh_iface __maybe_unused, int argc, char **argv) return res; }
-COMMAND(routing_algo, "ra", 0); +COMMAND(routing_algo, "ra", 0, + "[mode] \tdisplay or modify the routing algorithm"); diff --git a/statistics.c b/statistics.c index cb6c1e8..908bbaf 100644 --- a/statistics.c +++ b/statistics.c @@ -126,4 +126,5 @@ static int statistics(char *mesh_iface, int argc __maybe_unused, return ret; }
-COMMAND(statistics, "s", COMMAND_FLAG_MESH_IFACE); +COMMAND(statistics, "s", COMMAND_FLAG_MESH_IFACE, + " \tprint mesh statistics"); diff --git a/tcpdump.c b/tcpdump.c index fd2b35a..62e4a64 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -1352,4 +1352,5 @@ static int tcpdump(char *mesh_iface __maybe_unused, int argc, char **argv) return ret; }
-COMMAND(tcpdump, "td", 0); +COMMAND(tcpdump, "td", 0, + "<interface> \ttcpdump layer 2 traffic on the given interface"); diff --git a/throughputmeter.c b/throughputmeter.c index e9e318c..ebd35a6 100644 --- a/throughputmeter.c +++ b/throughputmeter.c @@ -543,4 +543,5 @@ static int throughputmeter(char *mesh_iface, int argc, char **argv) return ret; }
-COMMAND(throughputmeter, "tp", COMMAND_FLAG_MESH_IFACE); +COMMAND(throughputmeter, "tp", COMMAND_FLAG_MESH_IFACE, + "<destination> \tstart a throughput measurement"); diff --git a/traceroute.c b/traceroute.c index 1352201..9446bcd 100644 --- a/traceroute.c +++ b/traceroute.c @@ -231,4 +231,5 @@ static int traceroute(char *mesh_iface, int argc, char **argv) return ret; }
-COMMAND(traceroute, "tr", COMMAND_FLAG_MESH_IFACE); +COMMAND(traceroute, "tr", COMMAND_FLAG_MESH_IFACE, + "<destination> \ttraceroute another batman adv host via layer 2"); diff --git a/translate.c b/translate.c index d2d34f5..95de9a2 100644 --- a/translate.c +++ b/translate.c @@ -78,4 +78,5 @@ static int translate(char *mesh_iface, int argc, char **argv) return ret; }
-COMMAND(translate, "t", COMMAND_FLAG_MESH_IFACE); +COMMAND(translate, "t", COMMAND_FLAG_MESH_IFACE, + "<destination> \ttranslate a destination to the originator responsible for it");
The command structure first mapped from one name and abbrevation to a single function of batctl. But there can be commands which share a significant portion of the code. To support these kind of things better, add an additional arg pointer to the command structure. The handler then receive a state struct from the main function instead of the mesh_iface.
The command implementation can then use the state to retrieve both the mesh_iface and the cmd with the arg pointer.
Signed-off-by: Sven Eckelmann sven@narfation.org --- bisect_iv.c | 4 ++-- gw_mode.c | 6 +++--- interface.c | 20 ++++++++++---------- log.c | 6 +++--- loglevel.c | 6 +++--- main.c | 29 +++++++++++++++++++---------- main.h | 15 +++++++++++---- ping.c | 8 ++++---- routing_algo.c | 4 ++-- statistics.c | 6 +++--- tcpdump.c | 4 ++-- throughputmeter.c | 8 ++++---- traceroute.c | 8 ++++---- translate.c | 6 +++--- 14 files changed, 73 insertions(+), 57 deletions(-)
diff --git a/bisect_iv.c b/bisect_iv.c index 6da82b9..c6fc708 100644 --- a/bisect_iv.c +++ b/bisect_iv.c @@ -1441,7 +1441,7 @@ static int get_orig_addr(char *orig_name, char *orig_addr) return 0; }
-static int bisect_iv(char *mesh_iface __maybe_unused, int argc, char **argv) +static int bisect_iv(struct state *state __maybe_unused, int argc, char **argv) { int ret = EXIT_FAILURE, res, optchar, found_args = 1; int read_opt = USE_BAT_HOSTS, num_parsed_files; @@ -1595,5 +1595,5 @@ static int bisect_iv(char *mesh_iface __maybe_unused, int argc, char **argv) return ret; }
-COMMAND(bisect_iv, "bisect_iv", 0, +COMMAND(bisect_iv, "bisect_iv", 0, NULL, "<file1> .. <fileN>\tanalyze given batman iv log files for routing stability"); diff --git a/gw_mode.c b/gw_mode.c index da22ff0..bd530d5 100644 --- a/gw_mode.c +++ b/gw_mode.c @@ -45,7 +45,7 @@ static void gw_mode_usage(void) fprintf(stderr, " \t -h print this help\n"); }
-static int gw_mode(char *mesh_iface, int argc, char **argv) +static int gw_mode(struct state *state, int argc, char **argv) { int optchar, res = EXIT_FAILURE; char *path_buff, gw_mode; @@ -68,7 +68,7 @@ static int gw_mode(char *mesh_iface, int argc, char **argv) return EXIT_FAILURE; }
- 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);
if (argc == 1) { res = read_file(path_buff, SYS_GW_MODE, USE_READ_BUFF, 0, 0, 0); @@ -167,5 +167,5 @@ static int gw_mode(char *mesh_iface, int argc, char **argv) return res; }
-COMMAND(gw_mode, "gw", COMMAND_FLAG_MESH_IFACE, +COMMAND(gw_mode, "gw", COMMAND_FLAG_MESH_IFACE, NULL, "[mode] \tdisplay or modify the gateway mode"); diff --git a/interface.c b/interface.c index d2883a9..5f69cb3 100644 --- a/interface.c +++ b/interface.c @@ -297,7 +297,7 @@ static int set_master_interface(const char *iface, unsigned int ifmaster) return err; }
-static int interface(char *mesh_iface, int argc, char **argv) +static int interface(struct state *state, int argc, char **argv) { int i, optchar; int ret; @@ -327,7 +327,7 @@ static int interface(char *mesh_iface, int argc, char **argv) rest_argv = &argv[optind];
if (rest_argc == 0) - return print_interfaces(mesh_iface); + return print_interfaces(state->mesh_iface);
check_root_or_die("batctl interface");
@@ -370,7 +370,7 @@ static int interface(char *mesh_iface, int argc, char **argv)
switch (rest_argv[0][0]) { case 'c': - ret = create_interface(mesh_iface); + ret = create_interface(state->mesh_iface); if (ret < 0) { fprintf(stderr, "Error - failed to add create batman-adv interface: %s\n", @@ -379,7 +379,7 @@ static int interface(char *mesh_iface, int argc, char **argv) } return EXIT_SUCCESS; case 'D': - ret = destroy_interface(mesh_iface); + ret = destroy_interface(state->mesh_iface); if (ret < 0) { fprintf(stderr, "Error - failed to destroy batman-adv interface: %s\n", @@ -392,9 +392,9 @@ static int interface(char *mesh_iface, int argc, char **argv) }
/* get index of batman-adv interface - or try to create it */ - ifmaster = if_nametoindex(mesh_iface); + ifmaster = if_nametoindex(state->mesh_iface); if (!manual_mode && !ifmaster && rest_argv[0][0] == 'a') { - ret = create_interface(mesh_iface); + ret = create_interface(state->mesh_iface); if (ret < 0) { fprintf(stderr, "Error - failed to create batman-adv interface: %s\n", @@ -402,7 +402,7 @@ static int interface(char *mesh_iface, int argc, char **argv) goto err; }
- ifmaster = if_nametoindex(mesh_iface); + ifmaster = if_nametoindex(state->mesh_iface); }
if (!ifmaster) { @@ -447,9 +447,9 @@ static int interface(char *mesh_iface, int argc, char **argv)
/* check if there is no interface left and then destroy mesh_iface */ if (!manual_mode && rest_argv[0][0] == 'd') { - cnt = count_interfaces(mesh_iface); + cnt = count_interfaces(state->mesh_iface); if (cnt == 0) - destroy_interface(mesh_iface); + destroy_interface(state->mesh_iface); }
return EXIT_SUCCESS; @@ -458,5 +458,5 @@ static int interface(char *mesh_iface, int argc, char **argv) return EXIT_FAILURE; }
-COMMAND(interface, "if", 0, +COMMAND(interface, "if", 0, NULL, "[add|del iface(s)]\tdisplay or modify the interface settings"); diff --git a/log.c b/log.c index e28466d..b4f0b86 100644 --- a/log.c +++ b/log.c @@ -36,7 +36,7 @@ static void log_usage(void) fprintf(stderr, " \t -n don't replace mac addresses with bat-host names\n"); }
-static int log_print(char *mesh_iface, int argc, char **argv) +static int log_print(struct state *state, int argc, char **argv) { int optchar, res, read_opt = USE_BAT_HOSTS | LOG_MODE; char full_path[MAX_PATH+1]; @@ -64,10 +64,10 @@ static int log_print(char *mesh_iface, int argc, char **argv) return EXIT_FAILURE; }
- debugfs_make_path(DEBUG_BATIF_PATH_FMT "/", mesh_iface, full_path, sizeof(full_path)); + debugfs_make_path(DEBUG_BATIF_PATH_FMT "/", state->mesh_iface, full_path, sizeof(full_path)); res = read_file(full_path, DEBUG_LOG, read_opt, 0, 0, 0); return res; }
-COMMAND_NAMED(log, "l", log_print, COMMAND_FLAG_MESH_IFACE, +COMMAND_NAMED(log, "l", log_print, COMMAND_FLAG_MESH_IFACE, NULL, " \tread the log produced by the kernel module"); diff --git a/loglevel.c b/loglevel.c index 3dc1a1c..7a61524 100644 --- a/loglevel.c +++ b/loglevel.c @@ -47,7 +47,7 @@ static void log_level_usage(void) fprintf(stderr, " \t tp Messages related to throughput meter\n"); }
-static int loglevel(char *mesh_iface, int argc, char **argv) +static int loglevel(struct state *state, int argc, char **argv) { int optchar, res = EXIT_FAILURE; int log_level = 0; @@ -72,7 +72,7 @@ static int loglevel(char *mesh_iface, int argc, char **argv) return EXIT_FAILURE; }
- 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);
if (argc != 1) { check_root_or_die("batctl loglevel"); @@ -143,5 +143,5 @@ static int loglevel(char *mesh_iface, int argc, char **argv) return res; }
-COMMAND(loglevel, "ll", COMMAND_FLAG_MESH_IFACE, +COMMAND(loglevel, "ll", COMMAND_FLAG_MESH_IFACE, NULL, "[level] \tdisplay or modify the log level"); diff --git a/main.c b/main.c index b9b19de..e20f914 100644 --- a/main.c +++ b/main.c @@ -127,7 +127,10 @@ int main(int argc, char **argv) { const struct command *cmd; int i, ret = EXIT_FAILURE; - char *mesh_iface = mesh_dfl_iface; + struct state state = { + .mesh_iface = mesh_dfl_iface, + .cmd = NULL, + }; int opt;
while ((opt = getopt(argc, argv, "+hm:v")) != -1) { @@ -137,13 +140,13 @@ int main(int argc, char **argv) exit(EXIT_SUCCESS); break; case 'm': - if (mesh_iface != mesh_dfl_iface) { + if (state.mesh_iface != mesh_dfl_iface) { fprintf(stderr, "Error - multiple mesh interfaces specified\n"); goto err; }
- mesh_iface = argv[2]; + state.mesh_iface = argv[2]; break; case 'v': version(); @@ -163,16 +166,22 @@ int main(int argc, char **argv) optind = 0;
if ((cmd = find_command(argv[0]))) { + state.cmd = cmd; + if (cmd->flags & COMMAND_FLAG_MESH_IFACE && - check_mesh_iface(mesh_iface) < 0) { - fprintf(stderr, "Error - interface %s is not present or not a batman-adv interface\n", mesh_iface); + check_mesh_iface(state.mesh_iface) < 0) { + fprintf(stderr, + "Error - interface %s is not present or not a batman-adv interface\n", + state.mesh_iface); exit(EXIT_FAILURE); }
- ret = cmd->handler(mesh_iface, argc, argv); + ret = cmd->handler(&state, argc, argv); } else { - if (check_mesh_iface(mesh_iface) < 0) { - fprintf(stderr, "Error - interface %s is not present or not a batman-adv interface\n", mesh_iface); + if (check_mesh_iface(state.mesh_iface) < 0) { + fprintf(stderr, + "Error - interface %s is not present or not a batman-adv interface\n", + state.mesh_iface); exit(EXIT_FAILURE); }
@@ -181,7 +190,7 @@ int main(int argc, char **argv) (strcmp(argv[0], batctl_settings[i].opt_short) != 0)) continue;
- ret = handle_sys_setting(mesh_iface, i, argc, argv); + ret = handle_sys_setting(state.mesh_iface, i, argc, argv); goto out; }
@@ -190,7 +199,7 @@ int main(int argc, char **argv) (strcmp(argv[0], batctl_debug_tables[i].opt_short) != 0)) continue;
- ret = handle_debug_table(mesh_iface, i, argc, argv); + ret = handle_debug_table(state.mesh_iface, i, argc, argv); goto out; }
diff --git a/main.h b/main.h index b39e350..77eb432 100644 --- a/main.h +++ b/main.h @@ -61,26 +61,33 @@ enum command_flags { COMMAND_FLAG_MESH_IFACE = BIT(0), };
+struct state { + char *mesh_iface; + const struct command *cmd; +}; + struct command { const char *name; const char *abbr; - int (*handler)(char *mesh_iface, int argc, char **argv); + int (*handler)(struct state *state, int argc, char **argv); uint32_t flags; + void *arg; const char *usage; };
-#define COMMAND_NAMED(_name, _abbr, _handler, _flags, _usage) \ +#define COMMAND_NAMED(_name, _abbr, _handler, _flags, _arg, _usage) \ static const struct command command_ ## _name = { \ .name = (#_name), \ .abbr = _abbr, \ .handler = (_handler), \ .flags = (_flags), \ + .arg = (_arg), \ .usage = (_usage), \ }; \ static const struct command *__command_ ## _name \ __attribute__((__used__)) __attribute__ ((__section__ ("__command"))) = &command_ ## _name
-#define COMMAND(_handler, _abbr, _flags, _usage) \ - COMMAND_NAMED(_handler, _abbr, _handler, _flags, _usage) +#define COMMAND(_handler, _abbr, _flags, _arg, _usage) \ + COMMAND_NAMED(_handler, _abbr, _handler, _flags, _arg, _usage)
#endif diff --git a/ping.c b/ping.c index efaf011..24af0e8 100644 --- a/ping.c +++ b/ping.c @@ -72,7 +72,7 @@ static void sig_handler(int sig) } }
-static int ping(char *mesh_iface, int argc, char **argv) +static int ping(struct state *state, int argc, char **argv) { struct batadv_icmp_packet_rr icmp_packet_out, icmp_packet_in; struct timeval tv; @@ -152,7 +152,7 @@ static int ping(char *mesh_iface, int argc, char **argv) }
if (!disable_translate_mac) - dst_mac = translate_mac(mesh_iface, dst_mac); + dst_mac = translate_mac(state->mesh_iface, dst_mac);
mac_string = ether_ntoa_long(dst_mac); signal(SIGINT, sig_handler); @@ -199,7 +199,7 @@ static int ping(char *mesh_iface, int argc, char **argv)
icmp_packet_out.seqno = htons(++seq_counter);
- res = icmp_interface_write(mesh_iface, + res = icmp_interface_write(state->mesh_iface, (struct batadv_icmp_header *)&icmp_packet_out, packet_len); if (res < 0) { @@ -345,5 +345,5 @@ static int ping(char *mesh_iface, int argc, char **argv) return ret; }
-COMMAND(ping, "p", COMMAND_FLAG_MESH_IFACE, +COMMAND(ping, "p", COMMAND_FLAG_MESH_IFACE, NULL, "<destination> \tping another batman adv host via layer 2"); diff --git a/routing_algo.c b/routing_algo.c index 8cc4ff1..30e588b 100644 --- a/routing_algo.c +++ b/routing_algo.c @@ -41,7 +41,7 @@ static void ra_mode_usage(void) fprintf(stderr, " \t -h print this help\n"); }
-static int routing_algo(char *mesh_iface __maybe_unused, int argc, char **argv) +static int routing_algo(struct state *state __maybe_unused, int argc, char **argv) { DIR *iface_base_dir; struct dirent *iface_dir; @@ -126,5 +126,5 @@ static int routing_algo(char *mesh_iface __maybe_unused, int argc, char **argv) return res; }
-COMMAND(routing_algo, "ra", 0, +COMMAND(routing_algo, "ra", 0, NULL, "[mode] \tdisplay or modify the routing algorithm"); diff --git a/statistics.c b/statistics.c index 908bbaf..26ffe44 100644 --- a/statistics.c +++ b/statistics.c @@ -102,14 +102,14 @@ static int statistics_custom_get(int fd, struct ifreq *ifr) return ret; }
-static int statistics(char *mesh_iface, int argc __maybe_unused, +static int statistics(struct state *state, int argc __maybe_unused, char **argv __maybe_unused) { struct ifreq ifr; int fd = -1, ret = EXIT_FAILURE;
memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, mesh_iface, sizeof(ifr.ifr_name)); + strncpy(ifr.ifr_name, state->mesh_iface, sizeof(ifr.ifr_name)); ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
fd = socket(AF_INET, SOCK_DGRAM, 0); @@ -126,5 +126,5 @@ static int statistics(char *mesh_iface, int argc __maybe_unused, return ret; }
-COMMAND(statistics, "s", COMMAND_FLAG_MESH_IFACE, +COMMAND(statistics, "s", COMMAND_FLAG_MESH_IFACE, NULL, " \tprint mesh statistics"); diff --git a/tcpdump.c b/tcpdump.c index 62e4a64..5c93842 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -1210,7 +1210,7 @@ static void sig_handler(int sig) } }
-static int tcpdump(char *mesh_iface __maybe_unused, int argc, char **argv) +static int tcpdump(struct state *state __maybe_unused, int argc, char **argv) { struct timeval tv; struct dump_if *dump_if, *dump_if_tmp; @@ -1352,5 +1352,5 @@ static int tcpdump(char *mesh_iface __maybe_unused, int argc, char **argv) return ret; }
-COMMAND(tcpdump, "td", 0, +COMMAND(tcpdump, "td", 0, NULL, "<interface> \ttcpdump layer 2 traffic on the given interface"); diff --git a/throughputmeter.c b/throughputmeter.c index ebd35a6..0c5e38a 100644 --- a/throughputmeter.c +++ b/throughputmeter.c @@ -388,7 +388,7 @@ static void tp_meter_usage(void) fprintf(stderr, "\t -n don't convert addresses to bat-host names\n"); }
-static int throughputmeter(char *mesh_iface, int argc, char **argv) +static int throughputmeter(struct state *state, int argc, char **argv) { struct bat_host *bat_host; uint64_t throughput; @@ -458,7 +458,7 @@ static int throughputmeter(char *mesh_iface, int argc, char **argv) dst_string = ether_ntoa_long(dst_mac);
/* for sighandler */ - tp_mesh_iface = mesh_iface; + tp_mesh_iface = state->mesh_iface; signal(SIGINT, tp_sig_handler); signal(SIGTERM, tp_sig_handler);
@@ -466,7 +466,7 @@ static int throughputmeter(char *mesh_iface, int argc, char **argv) if (!listen_sock) goto out;
- ret = tp_meter_start(mesh_iface, dst_mac, time, &cookie); + ret = tp_meter_start(state->mesh_iface, dst_mac, time, &cookie); if (ret < 0) { printf("Failed to send tp_meter request to kernel: %d\n", ret); goto out; @@ -543,5 +543,5 @@ static int throughputmeter(char *mesh_iface, int argc, char **argv) return ret; }
-COMMAND(throughputmeter, "tp", COMMAND_FLAG_MESH_IFACE, +COMMAND(throughputmeter, "tp", COMMAND_FLAG_MESH_IFACE, NULL, "<destination> \tstart a throughput measurement"); diff --git a/traceroute.c b/traceroute.c index 9446bcd..77c3188 100644 --- a/traceroute.c +++ b/traceroute.c @@ -55,7 +55,7 @@ static void traceroute_usage(void) fprintf(stderr, " \t -T don't try to translate mac to originator address\n"); }
-static int traceroute(char *mesh_iface, int argc, char **argv) +static int traceroute(struct state *state, int argc, char **argv) { struct batadv_icmp_packet icmp_packet_out, icmp_packet_in; struct bat_host *bat_host; @@ -113,7 +113,7 @@ static int traceroute(char *mesh_iface, int argc, char **argv) }
if (!disable_translate_mac) - dst_mac = translate_mac(mesh_iface, dst_mac); + dst_mac = translate_mac(state->mesh_iface, dst_mac);
mac_string = ether_ntoa_long(dst_mac);
@@ -146,7 +146,7 @@ static int traceroute(char *mesh_iface, int argc, char **argv) icmp_packet_out.seqno = htons(++seq_counter); time_delta[i] = 0.0;
- res = icmp_interface_write(mesh_iface, + res = icmp_interface_write(state->mesh_iface, (struct batadv_icmp_header *)&icmp_packet_out, sizeof(icmp_packet_out)); if (res < 0) { @@ -231,5 +231,5 @@ static int traceroute(char *mesh_iface, int argc, char **argv) return ret; }
-COMMAND(traceroute, "tr", COMMAND_FLAG_MESH_IFACE, +COMMAND(traceroute, "tr", COMMAND_FLAG_MESH_IFACE, NULL, "<destination> \ttraceroute another batman adv host via layer 2"); diff --git a/translate.c b/translate.c index 95de9a2..38f26df 100644 --- a/translate.c +++ b/translate.c @@ -33,7 +33,7 @@ static void translate_usage(void) fprintf(stderr, "Usage: batctl [options] translate mac|bat-host|host_name|IPv4_address\n"); }
-static int translate(char *mesh_iface, int argc, char **argv) +static int translate(struct state *state, int argc, char **argv) { struct ether_addr *dst_mac = NULL; struct bat_host *bat_host; @@ -64,7 +64,7 @@ static int translate(char *mesh_iface, int argc, char **argv) } }
- dst_mac = translate_mac(mesh_iface, dst_mac); + dst_mac = translate_mac(state->mesh_iface, dst_mac); if (dst_mac) { mac_string = ether_ntoa_long(dst_mac); printf("%s\n", mac_string); @@ -78,5 +78,5 @@ static int translate(char *mesh_iface, int argc, char **argv) return ret; }
-COMMAND(translate, "t", COMMAND_FLAG_MESH_IFACE, +COMMAND(translate, "t", COMMAND_FLAG_MESH_IFACE, NULL, "<destination> \ttranslate a destination to the originator responsible for it");
The usage output of batctl is structured in different sections. This should be preserved when the remaining subcommands are converted to the command infrastructure.
Signed-off-by: Sven Eckelmann sven@narfation.org --- bisect_iv.c | 2 +- gw_mode.c | 2 +- interface.c | 2 +- log.c | 2 +- loglevel.c | 2 +- main.c | 68 +++++++++++++++++++++++++++++++++++-------------------- main.h | 12 +++++++--- ping.c | 2 +- routing_algo.c | 2 +- statistics.c | 2 +- tcpdump.c | 2 +- throughputmeter.c | 2 +- traceroute.c | 2 +- translate.c | 2 +- 14 files changed, 64 insertions(+), 40 deletions(-)
diff --git a/bisect_iv.c b/bisect_iv.c index c6fc708..420317e 100644 --- a/bisect_iv.c +++ b/bisect_iv.c @@ -1595,5 +1595,5 @@ static int bisect_iv(struct state *state __maybe_unused, int argc, char **argv) return ret; }
-COMMAND(bisect_iv, "bisect_iv", 0, NULL, +COMMAND(SUBCOMMAND, bisect_iv, "bisect_iv", 0, NULL, "<file1> .. <fileN>\tanalyze given batman iv log files for routing stability"); diff --git a/gw_mode.c b/gw_mode.c index bd530d5..4093f89 100644 --- a/gw_mode.c +++ b/gw_mode.c @@ -167,5 +167,5 @@ static int gw_mode(struct state *state, int argc, char **argv) return res; }
-COMMAND(gw_mode, "gw", COMMAND_FLAG_MESH_IFACE, NULL, +COMMAND(SUBCOMMAND, gw_mode, "gw", COMMAND_FLAG_MESH_IFACE, NULL, "[mode] \tdisplay or modify the gateway mode"); diff --git a/interface.c b/interface.c index 5f69cb3..3c176a8 100644 --- a/interface.c +++ b/interface.c @@ -458,5 +458,5 @@ static int interface(struct state *state, int argc, char **argv) return EXIT_FAILURE; }
-COMMAND(interface, "if", 0, NULL, +COMMAND(SUBCOMMAND, interface, "if", 0, NULL, "[add|del iface(s)]\tdisplay or modify the interface settings"); diff --git a/log.c b/log.c index b4f0b86..cd69676 100644 --- a/log.c +++ b/log.c @@ -69,5 +69,5 @@ static int log_print(struct state *state, int argc, char **argv) return res; }
-COMMAND_NAMED(log, "l", log_print, COMMAND_FLAG_MESH_IFACE, NULL, +COMMAND_NAMED(SUBCOMMAND, log, "l", log_print, COMMAND_FLAG_MESH_IFACE, NULL, " \tread the log produced by the kernel module"); diff --git a/loglevel.c b/loglevel.c index 7a61524..fed70c8 100644 --- a/loglevel.c +++ b/loglevel.c @@ -143,5 +143,5 @@ static int loglevel(struct state *state, int argc, char **argv) return res; }
-COMMAND(loglevel, "ll", COMMAND_FLAG_MESH_IFACE, NULL, +COMMAND(SUBCOMMAND, loglevel, "ll", COMMAND_FLAG_MESH_IFACE, NULL, "[level] \tdisplay or modify the log level"); diff --git a/main.c b/main.c index e20f914..251d753 100644 --- a/main.c +++ b/main.c @@ -41,45 +41,63 @@ extern const struct command *__stop___command[];
static void print_usage(void) { + enum command_type type[] = { + SUBCOMMAND, + }; const struct command **p; - int i, opt_indent; + int opt_indent; char buf[32]; + size_t i; + size_t j;
fprintf(stderr, "Usage: batctl [options] command|debug table [parameters]\n"); fprintf(stderr, "options:\n"); fprintf(stderr, " \t-m mesh interface or VLAN created on top of a mesh interface (default 'bat0')\n"); fprintf(stderr, " \t-h print this help (or 'batctl <command|debug table> -h' for the parameter help)\n"); fprintf(stderr, " \t-v print version\n"); - fprintf(stderr, "\n");
- fprintf(stderr, "commands:\n"); + for (i = 0; i < sizeof(type) / sizeof(*type); i++) { + fprintf(stderr, "\n");
- for (p = __start___command; p < __stop___command; p++) { - const struct command *cmd = *p; + switch (type[i]) { + case SUBCOMMAND: + fprintf(stderr, "commands:\n"); + break; + }
- if (strcmp(cmd->name, cmd->abbr) == 0) - snprintf(buf, sizeof(buf), "%s", cmd->name); - else - snprintf(buf, sizeof(buf), "%s|%s", cmd->name, - cmd->abbr); + for (p = __start___command; p < __stop___command; p++) { + const struct command *cmd = *p;
- fprintf(stderr, " \t%-27s%s\n", buf, cmd->usage); - } + if (cmd->type != type[i]) + continue; + + if (strcmp(cmd->name, cmd->abbr) == 0) + snprintf(buf, sizeof(buf), "%s", cmd->name); + else + snprintf(buf, sizeof(buf), "%s|%s", cmd->name, + cmd->abbr); + + fprintf(stderr, " \t%-27s%s\n", buf, cmd->usage); + }
- for (i = 0; i < BATCTL_SETTINGS_NUM; i++) { - fprintf(stderr, " \t%s|%s", batctl_settings[i].opt_long, batctl_settings[i].opt_short); - opt_indent = strlen(batctl_settings[i].opt_long) + strlen(batctl_settings[i].opt_short); - - if (batctl_settings[i].params == sysfs_param_enable) - fprintf(stderr, "%*s display or modify %s setting\n", - 31 - opt_indent, "[0|1]", batctl_settings[i].opt_long); - else if (batctl_settings[i].params == sysfs_param_server) - fprintf(stderr, "%*s display or modify %s setting\n", - 41 - opt_indent, "[client|server]", batctl_settings[i].opt_long); - else - fprintf(stderr, " display or modify %s setting\n", - batctl_settings[i].opt_long); + if (type[i] == SUBCOMMAND) { + for (j = 0; j < BATCTL_SETTINGS_NUM; j++) { + fprintf(stderr, " \t%s|%s", batctl_settings[j].opt_long, batctl_settings[j].opt_short); + opt_indent = strlen(batctl_settings[j].opt_long) + strlen(batctl_settings[j].opt_short); + + if (batctl_settings[j].params == sysfs_param_enable) + fprintf(stderr, "%*s display or modify %s setting\n", + 31 - opt_indent, "[0|1]", batctl_settings[j].opt_long); + else if (batctl_settings[j].params == sysfs_param_server) + fprintf(stderr, "%*s display or modify %s setting\n", + 41 - opt_indent, "[client|server]", batctl_settings[j].opt_long); + else + fprintf(stderr, " display or modify %s setting\n", + batctl_settings[j].opt_long); + } + } } + fprintf(stderr, "\n");
fprintf(stderr, "debug tables: \tdisplay the corresponding debug table\n"); diff --git a/main.h b/main.h index 77eb432..052304c 100644 --- a/main.h +++ b/main.h @@ -61,12 +61,17 @@ enum command_flags { COMMAND_FLAG_MESH_IFACE = BIT(0), };
+enum command_type { + SUBCOMMAND, +}; + struct state { char *mesh_iface; const struct command *cmd; };
struct command { + enum command_type type; const char *name; const char *abbr; int (*handler)(struct state *state, int argc, char **argv); @@ -75,8 +80,9 @@ struct command { const char *usage; };
-#define COMMAND_NAMED(_name, _abbr, _handler, _flags, _arg, _usage) \ +#define COMMAND_NAMED(_type, _name, _abbr, _handler, _flags, _arg, _usage) \ static const struct command command_ ## _name = { \ + .type = (_type), \ .name = (#_name), \ .abbr = _abbr, \ .handler = (_handler), \ @@ -87,7 +93,7 @@ struct command { static const struct command *__command_ ## _name \ __attribute__((__used__)) __attribute__ ((__section__ ("__command"))) = &command_ ## _name
-#define COMMAND(_handler, _abbr, _flags, _arg, _usage) \ - COMMAND_NAMED(_handler, _abbr, _handler, _flags, _arg, _usage) +#define COMMAND(_type, _handler, _abbr, _flags, _arg, _usage) \ + COMMAND_NAMED(_type, _handler, _abbr, _handler, _flags, _arg, _usage)
#endif diff --git a/ping.c b/ping.c index 24af0e8..5c13d81 100644 --- a/ping.c +++ b/ping.c @@ -345,5 +345,5 @@ static int ping(struct state *state, int argc, char **argv) return ret; }
-COMMAND(ping, "p", COMMAND_FLAG_MESH_IFACE, NULL, +COMMAND(SUBCOMMAND, ping, "p", COMMAND_FLAG_MESH_IFACE, NULL, "<destination> \tping another batman adv host via layer 2"); diff --git a/routing_algo.c b/routing_algo.c index 30e588b..ded9284 100644 --- a/routing_algo.c +++ b/routing_algo.c @@ -126,5 +126,5 @@ static int routing_algo(struct state *state __maybe_unused, int argc, char **arg return res; }
-COMMAND(routing_algo, "ra", 0, NULL, +COMMAND(SUBCOMMAND, routing_algo, "ra", 0, NULL, "[mode] \tdisplay or modify the routing algorithm"); diff --git a/statistics.c b/statistics.c index 26ffe44..d684fa5 100644 --- a/statistics.c +++ b/statistics.c @@ -126,5 +126,5 @@ static int statistics(struct state *state, int argc __maybe_unused, return ret; }
-COMMAND(statistics, "s", COMMAND_FLAG_MESH_IFACE, NULL, +COMMAND(SUBCOMMAND, statistics, "s", COMMAND_FLAG_MESH_IFACE, NULL, " \tprint mesh statistics"); diff --git a/tcpdump.c b/tcpdump.c index 5c93842..42713d3 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -1352,5 +1352,5 @@ static int tcpdump(struct state *state __maybe_unused, int argc, char **argv) return ret; }
-COMMAND(tcpdump, "td", 0, NULL, +COMMAND(SUBCOMMAND, tcpdump, "td", 0, NULL, "<interface> \ttcpdump layer 2 traffic on the given interface"); diff --git a/throughputmeter.c b/throughputmeter.c index 0c5e38a..de20b66 100644 --- a/throughputmeter.c +++ b/throughputmeter.c @@ -543,5 +543,5 @@ static int throughputmeter(struct state *state, int argc, char **argv) return ret; }
-COMMAND(throughputmeter, "tp", COMMAND_FLAG_MESH_IFACE, NULL, +COMMAND(SUBCOMMAND, throughputmeter, "tp", COMMAND_FLAG_MESH_IFACE, NULL, "<destination> \tstart a throughput measurement"); diff --git a/traceroute.c b/traceroute.c index 77c3188..6e325c4 100644 --- a/traceroute.c +++ b/traceroute.c @@ -231,5 +231,5 @@ static int traceroute(struct state *state, int argc, char **argv) return ret; }
-COMMAND(traceroute, "tr", COMMAND_FLAG_MESH_IFACE, NULL, +COMMAND(SUBCOMMAND, traceroute, "tr", COMMAND_FLAG_MESH_IFACE, NULL, "<destination> \ttraceroute another batman adv host via layer 2"); diff --git a/translate.c b/translate.c index 38f26df..ad51ddf 100644 --- a/translate.c +++ b/translate.c @@ -78,5 +78,5 @@ static int translate(struct state *state, int argc, char **argv) return ret; }
-COMMAND(translate, "t", COMMAND_FLAG_MESH_IFACE, NULL, +COMMAND(SUBCOMMAND, translate, "t", COMMAND_FLAG_MESH_IFACE, NULL, "<destination> \ttranslate a destination to the originator responsible for it");
Most of the commands were already converted to the new command infrastructure. To use the new state and pre-initialization steps, the debugfs tables also have to be converted.
Signed-off-by: Sven Eckelmann sven@narfation.org --- debug.c | 228 +++++++++++++++++++++++++++++++++--------------------------- debug.h | 35 ++++------ functions.c | 10 +-- main.c | 19 ++--- main.h | 2 +- 5 files changed, 150 insertions(+), 144 deletions(-)
diff --git a/debug.c b/debug.c index 9bc4d0c..016b148 100644 --- a/debug.c +++ b/debug.c @@ -32,101 +32,34 @@ #include "netlink.h" #include "sys.h"
-const struct debug_table_data batctl_debug_tables[BATCTL_TABLE_NUM] = { - { - .opt_long = "neighbors", - .opt_short = "n", - .debugfs_name = "neighbors", - .header_lines = 2, - .netlink_fn = netlink_print_neighbors, - }, - { - .opt_long = "originators", - .opt_short = "o", - .debugfs_name = "originators", - .header_lines = 2, - .netlink_fn = netlink_print_originators, - }, - { - .opt_long = "gateways", - .opt_short = "gwl", - .debugfs_name = "gateways", - .header_lines = 1, - .netlink_fn = netlink_print_gateways, - }, - { - .opt_long = "translocal", - .opt_short = "tl", - .debugfs_name = "transtable_local", - .header_lines = 2, - .netlink_fn = netlink_print_translocal, - }, - { - .opt_long = "transglobal", - .opt_short = "tg", - .debugfs_name = "transtable_global", - .header_lines = 2, - .netlink_fn = netlink_print_transglobal, - }, - { - .opt_long = "claimtable", - .opt_short = "cl", - .debugfs_name = "bla_claim_table", - .header_lines = 2, - .netlink_fn = netlink_print_bla_claim, - }, - { - .opt_long = "backbonetable", - .opt_short = "bbt", - .debugfs_name = "bla_backbone_table", - .header_lines = 2, - .netlink_fn = netlink_print_bla_backbone, - }, - { - .opt_long = "dat_cache", - .opt_short = "dc", - .debugfs_name = "dat_cache", - .header_lines = 2, - .netlink_fn = netlink_print_dat_cache, - }, - { - .opt_long = "nc_nodes", - .opt_short = "nn", - .debugfs_name = "nc_nodes", - .header_lines = 0, - }, - { - .opt_long = "mcast_flags", - .opt_short = "mf", - .debugfs_name = "mcast_flags", - .header_lines = 6, - .netlink_fn = netlink_print_mcast_flags, - }, -}; - -static void debug_table_usage(int debug_table) +static void debug_table_usage(struct state *state) { + struct debug_table_data *debug_table = state->cmd->arg; + fprintf(stderr, "Usage: batctl [options] %s|%s [parameters]\n", - batctl_debug_tables[debug_table].opt_long, batctl_debug_tables[debug_table].opt_short); + state->cmd->name, state->cmd->abbr); fprintf(stderr, "parameters:\n"); fprintf(stderr, " \t -h print this help\n"); fprintf(stderr, " \t -n don't replace mac addresses with bat-host names\n"); fprintf(stderr, " \t -H don't show the header\n"); fprintf(stderr, " \t -w [interval] watch mode - refresh the table continuously\n");
- if (debug_table == BATCTL_TABLE_ORIGINATORS) { + if (debug_table->option_watch_interval) fprintf(stderr, " \t -t timeout interval - don't print originators not seen for x.y seconds \n"); + + if (debug_table->option_orig_iface) fprintf(stderr, " \t -i [interface] - show multiif originator table for a specific interface\n"); - }
- if (debug_table == BATCTL_TABLE_TRANSLOCAL || - debug_table == BATCTL_TABLE_TRANSGLOBAL) { - fprintf(stderr, " \t -u|-m print unicast or multicast mac addresses only\n"); - } + if (debug_table->option_unicast_only) + fprintf(stderr, " \t -u print unicast mac addresses only\n"); + + if (debug_table->option_multicast_only) + fprintf(stderr, " \t -m print multicast mac addresses only\n"); }
-int handle_debug_table(char *mesh_iface, int debug_table, int argc, char **argv) +int handle_debug_table(struct state *state, int argc, char **argv) { + struct debug_table_data *debug_table = state->cmd->arg; int optchar, read_opt = USE_BAT_HOSTS; char full_path[MAX_PATH+1]; char *debugfs_mnt; @@ -138,7 +71,7 @@ int handle_debug_table(char *mesh_iface, int debug_table, int argc, char **argv) while ((optchar = getopt(argc, argv, "hnw:t:Humi:")) != -1) { switch (optchar) { case 'h': - debug_table_usage(debug_table); + debug_table_usage(state); return EXIT_SUCCESS; case 'n': read_opt &= ~USE_BAT_HOSTS; @@ -156,9 +89,9 @@ int handle_debug_table(char *mesh_iface, int debug_table, int argc, char **argv) } break; case 't': - if (debug_table != BATCTL_TABLE_ORIGINATORS) { + if (debug_table->option_watch_interval) { fprintf(stderr, "Error - unrecognised option '-%c'\n", optchar); - debug_table_usage(debug_table); + debug_table_usage(state); return EXIT_FAILURE; }
@@ -172,33 +105,31 @@ int handle_debug_table(char *mesh_iface, int debug_table, int argc, char **argv) read_opt |= SKIP_HEADER; break; case 'u': - if (debug_table != BATCTL_TABLE_TRANSLOCAL && - debug_table != BATCTL_TABLE_TRANSGLOBAL) { + if (debug_table->option_unicast_only) { fprintf(stderr, "Error - unrecognised option '-%c'\n", optchar); - debug_table_usage(debug_table); + debug_table_usage(state); return EXIT_FAILURE; }
read_opt |= UNICAST_ONLY; break; case 'm': - if (debug_table != BATCTL_TABLE_TRANSLOCAL && - debug_table != BATCTL_TABLE_TRANSGLOBAL) { + if (debug_table->option_multicast_only) { fprintf(stderr, "Error - unrecognised option '-%c'\n", optchar); - debug_table_usage(debug_table); + debug_table_usage(state); return EXIT_FAILURE; }
read_opt |= MULTICAST_ONLY; break; case 'i': - if (debug_table != BATCTL_TABLE_ORIGINATORS) { + if (debug_table->option_orig_iface) { fprintf(stderr, "Error - unrecognised option '-%c'\n", optchar); - debug_table_usage(debug_table); + debug_table_usage(state); return EXIT_FAILURE; }
- if (check_mesh_iface_ownership(mesh_iface, optarg) != EXIT_SUCCESS) + if (check_mesh_iface_ownership(state->mesh_iface, optarg) != EXIT_SUCCESS) return EXIT_FAILURE;
orig_iface = optarg; @@ -217,7 +148,7 @@ int handle_debug_table(char *mesh_iface, int debug_table, int argc, char **argv)
return EXIT_FAILURE; default: - debug_table_usage(debug_table); + debug_table_usage(state); return EXIT_FAILURE; } } @@ -226,7 +157,7 @@ int handle_debug_table(char *mesh_iface, int debug_table, int argc, char **argv)
if (read_opt & UNICAST_ONLY && read_opt & MULTICAST_ONLY) { fprintf(stderr, "Error - '-u' and '-m' are exclusive options\n"); - debug_table_usage(debug_table); + debug_table_usage(state); return EXIT_FAILURE; }
@@ -236,9 +167,9 @@ int handle_debug_table(char *mesh_iface, int debug_table, int argc, char **argv) return EXIT_FAILURE; }
- if (batctl_debug_tables[debug_table].netlink_fn) { - err = batctl_debug_tables[debug_table].netlink_fn( - mesh_iface, orig_iface, read_opt, orig_timeout, + if (debug_table->netlink_fn) { + err = debug_table->netlink_fn( + state->mesh_iface, orig_iface, read_opt, orig_timeout, watch_interval); if (err != -EOPNOTSUPP) return err; @@ -247,11 +178,11 @@ int handle_debug_table(char *mesh_iface, int debug_table, int argc, char **argv) if (orig_iface) debugfs_make_path(DEBUG_BATIF_PATH_FMT "/", orig_iface, full_path, sizeof(full_path)); else - debugfs_make_path(DEBUG_BATIF_PATH_FMT "/", mesh_iface, full_path, sizeof(full_path)); + debugfs_make_path(DEBUG_BATIF_PATH_FMT "/", state->mesh_iface, full_path, sizeof(full_path));
- return read_file(full_path, (char *)batctl_debug_tables[debug_table].debugfs_name, + return read_file(full_path, debug_table->debugfs_name, read_opt, orig_timeout, watch_interval, - batctl_debug_tables[debug_table].header_lines); + debug_table->header_lines); }
int debug_print_routing_algos(void) @@ -268,3 +199,98 @@ int debug_print_routing_algos(void) debugfs_make_path(DEBUG_BATIF_PATH_FMT, "", full_path, sizeof(full_path)); return read_file(full_path, DEBUG_ROUTING_ALGOS, 0, 0, 0, 0); } + +static struct debug_table_data batctl_debug_table_neighbors = { + .debugfs_name = "neighbors", + .header_lines = 2, + .netlink_fn = netlink_print_neighbors, +}; + +COMMAND_NAMED(DEBUGTABLE, neighbors, "n", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_neighbors, ""); + +static struct debug_table_data batctl_debug_table_originators = { + .debugfs_name = "originators", + .header_lines = 2, + .netlink_fn = netlink_print_originators, + .option_watch_interval = 1, + .option_orig_iface = 1, +}; + +COMMAND_NAMED(DEBUGTABLE, originators, "o", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_originators, ""); + +static struct debug_table_data batctl_debug_table_gateways = { + .debugfs_name = "gateways", + .header_lines = 1, + .netlink_fn = netlink_print_gateways, +}; + +COMMAND_NAMED(DEBUGTABLE, gateways, "gwl", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_gateways, ""); + +static struct debug_table_data batctl_debug_table_translocal = { + .debugfs_name = "transtable_local", + .header_lines = 2, + .netlink_fn = netlink_print_translocal, + .option_unicast_only = 1, + .option_multicast_only = 1, +}; + +COMMAND_NAMED(DEBUGTABLE, translocal, "tl", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_translocal, ""); + +static struct debug_table_data batctl_debug_table_transglobal = { + .debugfs_name = "transtable_global", + .header_lines = 2, + .netlink_fn = netlink_print_transglobal, + .option_unicast_only = 1, + .option_multicast_only = 1, +}; + +COMMAND_NAMED(DEBUGTABLE, transglobal, "tg", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_transglobal, ""); + +static struct debug_table_data batctl_debug_table_claimtable = { + .debugfs_name = DEBUG_CLAIMTABLE, + .header_lines = 2, + .netlink_fn = netlink_print_bla_claim, +}; + +COMMAND_NAMED(DEBUGTABLE, claimtable, "cl", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_claimtable, ""); + +static struct debug_table_data batctl_debug_table_backbonetable = { + .debugfs_name = DEBUG_BACKBONETABLE, + .header_lines = 2, + .netlink_fn = netlink_print_bla_backbone, +}; + +COMMAND_NAMED(DEBUGTABLE, backbonetable, "bbt", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_backbonetable, ""); + +static struct debug_table_data batctl_debug_table_dat_cache = { + .debugfs_name = DEBUG_DAT_CACHE, + .header_lines = 2, + .netlink_fn = netlink_print_dat_cache, +}; + +COMMAND_NAMED(DEBUGTABLE, dat_cache, "dc", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_dat_cache, ""); + +static struct debug_table_data batctl_debug_table_nc_nodes = { + .debugfs_name = DEBUG_NC_NODES, + .header_lines = 0, +}; + +COMMAND_NAMED(DEBUGTABLE, nc_nodes, "nn", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_nc_nodes, ""); + +static struct debug_table_data batctl_debug_table_mcast_flags = { + .debugfs_name = DEBUG_MCAST_FLAGS, + .header_lines = 6, + .netlink_fn = netlink_print_mcast_flags, +}; + +COMMAND_NAMED(DEBUGTABLE, mcast_flags, "mf", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_mcast_flags, ""); diff --git a/debug.h b/debug.h index d9a2e3a..79c489a 100644 --- a/debug.h +++ b/debug.h @@ -28,35 +28,26 @@
#define DEBUG_BATIF_PATH_FMT "%s/batman_adv/%s" #define DEBUG_TRANSTABLE_GLOBAL "transtable_global" +#define DEBUG_BACKBONETABLE "bla_backbone_table" +#define DEBUG_CLAIMTABLE "bla_claim_table" +#define DEBUG_DAT_CACHE "dat_cache" +#define DEBUG_NC_NODES "nc_nodes" +#define DEBUG_MCAST_FLAGS "mcast_flags" #define DEBUG_LOG "log" #define DEBUG_ROUTING_ALGOS "routing_algos"
-enum batctl_debug_tables { - BATCTL_TABLE_NEIGHBORS, - BATCTL_TABLE_ORIGINATORS, - BATCTL_TABLE_GATEWAYS, - BATCTL_TABLE_TRANSLOCAL, - BATCTL_TABLE_TRANSGLOBAL, - BATCTL_TABLE_BLA_CLAIMS, - BATCTL_TABLE_BLA_BACKBONES, - BATCTL_TABLE_DAT, - BATCTL_TABLE_NETWORK_CODING_NODES, - BATCTL_TABLE_MCAST_FLAGS, - BATCTL_TABLE_NUM, -}; - struct debug_table_data { - const char opt_long[OPT_LONG_MAX_LEN]; - const char opt_short[OPT_SHORT_MAX_LEN]; - const char debugfs_name[DEBUG_TABLE_PATH_MAX_LEN]; - size_t header_lines; - int (*netlink_fn)(char *mesh_iface, char *hard_iface, int read_opt, + const char *debugfs_name; + size_t header_lines; + int (*netlink_fn)(char *mesh_iface, char *hard_iface, int read_opt, float orig_timeout, float watch_interval); + unsigned int option_unicast_only:1; + unsigned int option_multicast_only:1; + unsigned int option_watch_interval:1; + unsigned int option_orig_iface:1; };
-extern const struct debug_table_data batctl_debug_tables[BATCTL_TABLE_NUM]; - -int handle_debug_table(char *mesh_iface, int debug_table, int argc, char **argv); +int handle_debug_table(struct state *state, int argc, char **argv); int debug_print_routing_algos(void);
#endif diff --git a/functions.c b/functions.c index e0e9978..faa9478 100644 --- a/functions.c +++ b/functions.c @@ -73,11 +73,11 @@ const char *fs_compile_out_param[] = { batctl_settings[BATCTL_SETTINGS_DAT].sysfs_name, batctl_settings[BATCTL_SETTINGS_NETWORK_CODING].sysfs_name, batctl_settings[BATCTL_SETTINGS_MULTICAST_MODE].sysfs_name, - batctl_debug_tables[BATCTL_TABLE_BLA_CLAIMS].debugfs_name, - batctl_debug_tables[BATCTL_TABLE_BLA_BACKBONES].debugfs_name, - batctl_debug_tables[BATCTL_TABLE_DAT].debugfs_name, - batctl_debug_tables[BATCTL_TABLE_NETWORK_CODING_NODES].debugfs_name, - batctl_debug_tables[BATCTL_TABLE_MCAST_FLAGS].debugfs_name, + DEBUG_DAT_CACHE, + DEBUG_BACKBONETABLE, + DEBUG_DAT_CACHE, + DEBUG_NC_NODES, + DEBUG_MCAST_FLAGS, NULL, };
diff --git a/main.c b/main.c index 251d753..f5920a4 100644 --- a/main.c +++ b/main.c @@ -43,6 +43,7 @@ static void print_usage(void) { enum command_type type[] = { SUBCOMMAND, + DEBUGTABLE, }; const struct command **p; int opt_indent; @@ -63,6 +64,9 @@ static void print_usage(void) case SUBCOMMAND: fprintf(stderr, "commands:\n"); break; + case DEBUGTABLE: + fprintf(stderr, "debug tables: \tdisplay the corresponding debug table\n"); + break; }
for (p = __start___command; p < __stop___command; p++) { @@ -97,12 +101,6 @@ static void print_usage(void) } } } - - fprintf(stderr, "\n"); - - fprintf(stderr, "debug tables: \tdisplay the corresponding debug table\n"); - for (i = 0; i < BATCTL_TABLE_NUM; i++) - fprintf(stderr, " \t%s|%s\n", batctl_debug_tables[i].opt_long, batctl_debug_tables[i].opt_short); }
static void version(void) @@ -212,15 +210,6 @@ int main(int argc, char **argv) goto out; }
- for (i = 0; i < BATCTL_TABLE_NUM; i++) { - if ((strcmp(argv[0], batctl_debug_tables[i].opt_long) != 0) && - (strcmp(argv[0], batctl_debug_tables[i].opt_short) != 0)) - continue; - - ret = handle_debug_table(state.mesh_iface, i, argc, argv); - goto out; - } - fprintf(stderr, "Error - no valid command or debug table specified: %s\n", argv[0]); diff --git a/main.h b/main.h index 052304c..5fa248c 100644 --- a/main.h +++ b/main.h @@ -34,7 +34,6 @@ #define OPT_LONG_MAX_LEN 25 #define OPT_SHORT_MAX_LEN 5
-#define DEBUG_TABLE_PATH_MAX_LEN 20 #define SETTINGS_PATH_MAX_LEN 25
#if BYTE_ORDER == BIG_ENDIAN @@ -63,6 +62,7 @@ enum command_flags {
enum command_type { SUBCOMMAND, + DEBUGTABLE, };
struct state {
Most of the commands were already converted to the new command infrastructure. To use the new state and pre-initialization steps, the sysfs settings also have to be converted.
Signed-off-by: Sven Eckelmann sven@narfation.org --- functions.c | 8 +-- main.c | 67 ++++++---------------- main.h | 5 -- sys.c | 187 +++++++++++++++++++++++++++++++++--------------------------- sys.h | 25 ++------ 5 files changed, 130 insertions(+), 162 deletions(-)
diff --git a/functions.c b/functions.c index faa9478..0a7b587 100644 --- a/functions.c +++ b/functions.c @@ -69,10 +69,10 @@ char *line_ptr = NULL; const char *fs_compile_out_param[] = { SYS_LOG, SYS_LOG_LEVEL, - batctl_settings[BATCTL_SETTINGS_BLA].sysfs_name, - batctl_settings[BATCTL_SETTINGS_DAT].sysfs_name, - batctl_settings[BATCTL_SETTINGS_NETWORK_CODING].sysfs_name, - batctl_settings[BATCTL_SETTINGS_MULTICAST_MODE].sysfs_name, + SYS_BLA, + SYS_DAT, + SYS_NETWORK_CODING, + SYS_MULTICAST_MODE, DEBUG_DAT_CACHE, DEBUG_BACKBONETABLE, DEBUG_DAT_CACHE, diff --git a/main.c b/main.c index f5920a4..9fc6bfb 100644 --- a/main.c +++ b/main.c @@ -46,10 +46,8 @@ static void print_usage(void) DEBUGTABLE, }; const struct command **p; - int opt_indent; char buf[32]; size_t i; - size_t j;
fprintf(stderr, "Usage: batctl [options] command|debug table [parameters]\n"); fprintf(stderr, "options:\n"); @@ -83,23 +81,6 @@ static void print_usage(void)
fprintf(stderr, " \t%-27s%s\n", buf, cmd->usage); } - - if (type[i] == SUBCOMMAND) { - for (j = 0; j < BATCTL_SETTINGS_NUM; j++) { - fprintf(stderr, " \t%s|%s", batctl_settings[j].opt_long, batctl_settings[j].opt_short); - opt_indent = strlen(batctl_settings[j].opt_long) + strlen(batctl_settings[j].opt_short); - - if (batctl_settings[j].params == sysfs_param_enable) - fprintf(stderr, "%*s display or modify %s setting\n", - 31 - opt_indent, "[0|1]", batctl_settings[j].opt_long); - else if (batctl_settings[j].params == sysfs_param_server) - fprintf(stderr, "%*s display or modify %s setting\n", - 41 - opt_indent, "[client|server]", batctl_settings[j].opt_long); - else - fprintf(stderr, " display or modify %s setting\n", - batctl_settings[j].opt_long); - } - } } }
@@ -142,12 +123,12 @@ static const struct command *find_command(const char *name) int main(int argc, char **argv) { const struct command *cmd; - int i, ret = EXIT_FAILURE; struct state state = { .mesh_iface = mesh_dfl_iface, .cmd = NULL, }; int opt; + int ret;
while ((opt = getopt(argc, argv, "+hm:v")) != -1) { switch (opt) { @@ -181,42 +162,26 @@ int main(int argc, char **argv) argc -= optind; optind = 0;
- if ((cmd = find_command(argv[0]))) { - state.cmd = cmd; - - if (cmd->flags & COMMAND_FLAG_MESH_IFACE && - check_mesh_iface(state.mesh_iface) < 0) { - fprintf(stderr, - "Error - interface %s is not present or not a batman-adv interface\n", - state.mesh_iface); - exit(EXIT_FAILURE); - } - - ret = cmd->handler(&state, argc, argv); - } else { - if (check_mesh_iface(state.mesh_iface) < 0) { - fprintf(stderr, - "Error - interface %s is not present or not a batman-adv interface\n", - state.mesh_iface); - exit(EXIT_FAILURE); - } - - for (i = 0; i < BATCTL_SETTINGS_NUM; i++) { - if ((strcmp(argv[0], batctl_settings[i].opt_long) != 0) && - (strcmp(argv[0], batctl_settings[i].opt_short) != 0)) - continue; - - ret = handle_sys_setting(state.mesh_iface, i, argc, argv); - goto out; - } - + cmd = find_command(argv[0]); + if (!cmd) { fprintf(stderr, "Error - no valid command or debug table specified: %s\n", argv[0]); - print_usage(); + goto err; }
-out: + state.cmd = cmd; + + if (cmd->flags & COMMAND_FLAG_MESH_IFACE && + check_mesh_iface(state.mesh_iface) < 0) { + fprintf(stderr, + "Error - interface %s is not present or not a batman-adv interface\n", + state.mesh_iface); + exit(EXIT_FAILURE); + } + + ret = cmd->handler(&state, argc, argv); + return ret;
err: diff --git a/main.h b/main.h index 5fa248c..8d91480 100644 --- a/main.h +++ b/main.h @@ -31,11 +31,6 @@
#define EXIT_NOSUCCESS 2
-#define OPT_LONG_MAX_LEN 25 -#define OPT_SHORT_MAX_LEN 5 - -#define SETTINGS_PATH_MAX_LEN 25 - #if BYTE_ORDER == BIG_ENDIAN #define __BIG_ENDIAN_BITFIELD #elif BYTE_ORDER == LITTLE_ENDIAN diff --git a/sys.c b/sys.c index 2cb288e..08b389e 100644 --- a/sys.c +++ b/sys.c @@ -54,87 +54,18 @@ const char *sysfs_param_server[] = { NULL, };
-const struct settings_data batctl_settings[BATCTL_SETTINGS_NUM] = { - { - .opt_long = "orig_interval", - .opt_short = "it", - .sysfs_name = "orig_interval", - .params = NULL, - }, - { - .opt_long = "ap_isolation", - .opt_short = "ap", - .sysfs_name = "ap_isolation", - .params = sysfs_param_enable, - }, - { - .opt_long = "bridge_loop_avoidance", - .opt_short = "bl", - .sysfs_name = "bridge_loop_avoidance", - .params = sysfs_param_enable, - }, - { - .opt_long = "distributed_arp_table", - .opt_short = "dat", - .sysfs_name = "distributed_arp_table", - .params = sysfs_param_enable, - }, - { - .opt_long = "aggregation", - .opt_short = "ag", - .sysfs_name = "aggregated_ogms", - .params = sysfs_param_enable, - }, - { - .opt_long = "bonding", - .opt_short = "b", - .sysfs_name = "bonding", - .params = sysfs_param_enable, - }, - { - .opt_long = "fragmentation", - .opt_short = "f", - .sysfs_name = "fragmentation", - .params = sysfs_param_enable, - }, - { - .opt_long = "network_coding", - .opt_short = "nc", - .sysfs_name = "network_coding", - .params = sysfs_param_enable, - }, - { - .opt_long = "isolation_mark", - .opt_short = "mark", - .sysfs_name = "isolation_mark", - .params = NULL, - }, - { - .opt_long = "multicast_mode", - .opt_short = "mm", - .sysfs_name = "multicast_mode", - .params = sysfs_param_enable, - }, -}; - -static void settings_usage(int setting) +static void settings_usage(struct state *state) { - fprintf(stderr, "Usage: batctl [options] %s|%s [parameters]", - (char *)batctl_settings[setting].opt_long, (char *)batctl_settings[setting].opt_short); - - if (batctl_settings[setting].params == sysfs_param_enable) - fprintf(stderr, " [0|1]\n"); - else if (batctl_settings[setting].params == sysfs_param_server) - fprintf(stderr, " [client|server]\n"); - else - fprintf(stderr, "\n"); + fprintf(stderr, "Usage: batctl [options] %s|%s [parameters] %s\n", + state->cmd->name, state->cmd->abbr, state->cmd->usage);
fprintf(stderr, "parameters:\n"); fprintf(stderr, " \t -h print this help\n"); }
-int handle_sys_setting(char *mesh_iface, int setting, int argc, char **argv) +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; const char **ptr; @@ -142,10 +73,10 @@ int handle_sys_setting(char *mesh_iface, int setting, int argc, char **argv) while ((optchar = getopt(argc, argv, "h")) != -1) { switch (optchar) { case 'h': - settings_usage(setting); + settings_usage(state); return EXIT_SUCCESS; default: - settings_usage(setting); + settings_usage(state); return EXIT_FAILURE; } } @@ -157,27 +88,27 @@ int handle_sys_setting(char *mesh_iface, int setting, int argc, char **argv) return EXIT_FAILURE; }
- 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);
/* 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(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);
if (argc == 1) { - res = read_file(path_buff, (char *)batctl_settings[setting].sysfs_name, + res = read_file(path_buff, settings->sysfs_name, NO_FLAGS, 0, 0, 0); goto out; }
check_root_or_die("batctl");
- if (!batctl_settings[setting].params) + if (!settings->params) goto write_file;
- ptr = batctl_settings[setting].params; + ptr = settings->params; while (*ptr) { if (strcmp(*ptr, argv[1]) == 0) goto write_file; @@ -188,7 +119,7 @@ int handle_sys_setting(char *mesh_iface, int setting, int argc, char **argv) fprintf(stderr, "Error - the supplied argument is invalid: %s\n", argv[1]); fprintf(stderr, "The following values are allowed:\n");
- ptr = batctl_settings[setting].params; + ptr = settings->params; while (*ptr) { fprintf(stderr, " * %s\n", *ptr); ptr++; @@ -197,7 +128,7 @@ int handle_sys_setting(char *mesh_iface, int setting, int argc, char **argv) goto out;
write_file: - res = write_file(path_buff, (char *)batctl_settings[setting].sysfs_name, + res = write_file(path_buff, settings->sysfs_name, argv[1], argc > 2 ? argv[2] : NULL);
out: @@ -205,3 +136,93 @@ int handle_sys_setting(char *mesh_iface, int setting, int argc, char **argv) free(base_dev); return res; } + +static struct settings_data batctl_settings_orig_interval = { + .sysfs_name = "orig_interval", + .params = NULL, +}; + +COMMAND_NAMED(SUBCOMMAND, orig_interval, "it", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_orig_interval, + "[interval] \tdisplay or modify orig_interval setting"); + +static struct settings_data batctl_settings_ap_isolation = { + .sysfs_name = "ap_isolation", + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, ap_isolation, "ap", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_ap_isolation, + "[0|1] \tdisplay or modify ap_isolation setting"); + +static struct settings_data batctl_settings_bridge_loop_avoidance = { + .sysfs_name = SYS_BLA, + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, bridge_loop_avoidance, "bl", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_bridge_loop_avoidance, + "[0|1] \tdisplay or modify bridge_loop_avoidance setting"); + +static struct settings_data batctl_settings_distributed_arp_table = { + .sysfs_name = SYS_DAT, + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, distributed_arp_table, "dat", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_distributed_arp_table, + "[0|1] \tdisplay or modify distributed_arp_table setting"); + +static struct settings_data batctl_settings_aggregation = { + .sysfs_name = "aggregated_ogms", + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, aggregation, "ag", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_aggregation, + "[0|1] \tdisplay or modify aggregation setting"); + +static struct settings_data batctl_settings_bonding = { + .sysfs_name = "bonding", + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, bonding, "b", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_bonding, + "[0|1] \tdisplay or modify bonding setting"); + +static struct settings_data batctl_settings_fragmentation = { + .sysfs_name = "fragmentation", + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, fragmentation, "f", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_fragmentation, + "[0|1] \tdisplay or modify fragmentation setting"); + +static struct settings_data batctl_settings_network_coding = { + .sysfs_name = SYS_NETWORK_CODING, + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, network_coding, "nc", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_network_coding, + "[0|1] \tdisplay or modify network_coding setting"); + +static struct settings_data batctl_settings_isolation_mark = { + .sysfs_name = "isolation_mark", + .params = NULL, +}; + +COMMAND_NAMED(SUBCOMMAND, isolation_mark, "mark", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_isolation_mark, + "[mark] \tdisplay or modify isolation_mark setting"); + +static struct settings_data batctl_settings_multicast_mode = { + .sysfs_name = SYS_MULTICAST_MODE, + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, multicast_mode, "mm", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_multicast_mode, + "[0|1] \tdisplay or modify multicast_mode setting"); diff --git a/sys.h b/sys.h index 5f0280f..20e1934 100644 --- a/sys.h +++ b/sys.h @@ -28,6 +28,10 @@ #define SYS_BATIF_PATH_FMT "/sys/class/net/%s/mesh/" #define SYS_LOG_LEVEL "log_level" #define SYS_LOG "log" +#define SYS_BLA "bridge_loop_avoidance" +#define SYS_DAT "distributed_arp_table" +#define SYS_NETWORK_CODING "network_coding" +#define SYS_MULTICAST_MODE "multicast_mode" #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" @@ -35,31 +39,14 @@ #define SYS_VLAN_PATH SYS_IFACE_PATH"/%s/mesh/vlan%d/" #define VLAN_ID_MAX_LEN 4
-enum batctl_settings_list { - BATCTL_SETTINGS_ORIG_INTERVAL, - BATCTL_SETTINGS_AP_ISOLATION, - BATCTL_SETTINGS_BLA, - BATCTL_SETTINGS_DAT, - BATCTL_SETTINGS_AGGREGATION, - BATCTL_SETTINGS_BONDING, - BATCTL_SETTINGS_FRAGMENTATION, - BATCTL_SETTINGS_NETWORK_CODING, - BATCTL_SETTINGS_ISOLATION_MARK, - BATCTL_SETTINGS_MULTICAST_MODE, - BATCTL_SETTINGS_NUM, -}; - struct settings_data { - const char opt_long[OPT_LONG_MAX_LEN]; - const char opt_short[OPT_SHORT_MAX_LEN]; - const char sysfs_name[SETTINGS_PATH_MAX_LEN]; + const char *sysfs_name; const char **params; };
extern const char *sysfs_param_enable[]; extern const char *sysfs_param_server[]; -extern const struct settings_data batctl_settings[BATCTL_SETTINGS_NUM];
-int handle_sys_setting(char *mesh_iface, int setting, int argc, char **argv); +int handle_sys_setting(struct state *state, int argc, char **argv);
#endif
The netlink.c file contains to many different functions and mixes helper functions with actual command implementations. The debug table commands should be placed in separate files to better group the command specific code sections together.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + backbonetable.c | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ debug.c | 9 ---- main.h | 8 ++++ netlink.c | 108 +++--------------------------------------------- netlink.h | 19 ++++++++- 6 files changed, 157 insertions(+), 113 deletions(-) create mode 100644 backbonetable.c
diff --git a/Makefile b/Makefile index 842795b..704a0d8 100755 --- a/Makefile +++ b/Makefile @@ -30,6 +30,7 @@ BINARY_NAME = batctl OBJ_BISECT = bisect_iv.o
OBJ += bat-hosts.o +OBJ += backbonetable.o ifeq ($(CONFIG_BATCTL_BISECT),y) OBJ += $(OBJ_BISECT) endif diff --git a/backbonetable.c b/backbonetable.c new file mode 100644 index 0000000..d2e58d1 --- /dev/null +++ b/backbonetable.c @@ -0,0 +1,125 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Simon Wunderlich sw@simonwunderlich.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <netinet/if_ether.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +#include "batadv_packet.h" +#include "batman_adv.h" +#include "bat-hosts.h" +#include "debug.h" +#include "functions.h" +#include "main.h" +#include "netlink.h" + +static const int bla_backbone_mandatory[] = { + BATADV_ATTR_BLA_VID, + BATADV_ATTR_BLA_BACKBONE, + BATADV_ATTR_BLA_CRC, + BATADV_ATTR_LAST_SEEN_MSECS, +}; + +static int bla_backbone_callback(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + int last_seen_msecs, last_seen_secs; + struct print_opts *opts = arg; + struct bat_host *bat_host; + struct genlmsghdr *ghdr; + uint16_t backbone_crc; + uint8_t *backbone; + uint16_t vid; + + if (!genlmsg_valid_hdr(nlh, 0)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_BLA_BACKBONE) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + if (missing_mandatory_attrs(attrs, bla_backbone_mandatory, + ARRAY_SIZE(bla_backbone_mandatory))) { + fputs("Missing attributes from kernel\n", stderr); + exit(1); + } + + /* don't show own backbones */ + if (attrs[BATADV_ATTR_BLA_OWN]) + return NL_OK; + + vid = nla_get_u16(attrs[BATADV_ATTR_BLA_VID]); + backbone = nla_data(attrs[BATADV_ATTR_BLA_BACKBONE]); + backbone_crc = nla_get_u16(attrs[BATADV_ATTR_BLA_CRC]); + + last_seen_msecs = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]); + last_seen_secs = last_seen_msecs / 1000; + last_seen_msecs = last_seen_msecs % 1000; + + bat_host = bat_hosts_find_by_mac((char *)backbone); + if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) + printf("%02x:%02x:%02x:%02x:%02x:%02x ", + backbone[0], backbone[1], backbone[2], + backbone[3], backbone[4], backbone[5]); + else + printf("%17s ", bat_host->name); + + printf("on %5d %4i.%03is (0x%04x)\n", + BATADV_PRINT_VID(vid), last_seen_secs, last_seen_msecs, + backbone_crc); + + return NL_OK; +} + +static int netlink_print_bla_backbone(char *mesh_iface, char *orig_iface, + int read_opts, float orig_timeout, + float watch_interval) +{ + return netlink_print_common(mesh_iface, orig_iface, read_opts, + orig_timeout, watch_interval, + "Originator VID last seen (CRC )\n", + BATADV_CMD_GET_BLA_BACKBONE, + bla_backbone_callback); +} + +static struct debug_table_data batctl_debug_table_backbonetable = { + .debugfs_name = DEBUG_BACKBONETABLE, + .header_lines = 2, + .netlink_fn = netlink_print_bla_backbone, +}; + +COMMAND_NAMED(DEBUGTABLE, backbonetable, "bbt", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_backbonetable, ""); diff --git a/debug.c b/debug.c index 016b148..6eba9d8 100644 --- a/debug.c +++ b/debug.c @@ -260,15 +260,6 @@ static struct debug_table_data batctl_debug_table_claimtable = { COMMAND_NAMED(DEBUGTABLE, claimtable, "cl", handle_debug_table, COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_claimtable, "");
-static struct debug_table_data batctl_debug_table_backbonetable = { - .debugfs_name = DEBUG_BACKBONETABLE, - .header_lines = 2, - .netlink_fn = netlink_print_bla_backbone, -}; - -COMMAND_NAMED(DEBUGTABLE, backbonetable, "bbt", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_backbonetable, ""); - static struct debug_table_data batctl_debug_table_dat_cache = { .debugfs_name = DEBUG_DAT_CACHE, .header_lines = 2, diff --git a/main.h b/main.h index 8d91480..2656dcf 100644 --- a/main.h +++ b/main.h @@ -51,6 +51,14 @@ extern char module_ver_path[]; #define BATADV_PRINT_VID(vid) (vid & BATADV_VLAN_HAS_TAG ? \ (int)(vid & VLAN_VID_MASK) : -1)
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) + +#ifndef container_of +#define container_of(ptr, type, member) __extension__ ({ \ + const __typeof__(((type *)0)->member) *__pmember = (ptr); \ + (type *)((char *)__pmember - offsetof(type, member)); }) +#endif + enum command_flags { COMMAND_FLAG_MESH_IFACE = BIT(0), }; diff --git a/netlink.c b/netlink.c index f0fd1d9..cf7ff65 100644 --- a/netlink.c +++ b/netlink.c @@ -43,24 +43,6 @@ #include "functions.h" #include "main.h"
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) - -#ifndef container_of -#define container_of(ptr, type, member) __extension__ ({ \ - const __typeof__(((type *)0)->member) *__pmember = (ptr); \ - (type *)((char *)__pmember - offsetof(type, member)); }) -#endif - -struct print_opts { - int read_opt; - float orig_timeout; - float watch_interval; - nl_recvmsg_msg_cb_t callback; - char *remaining_header; - const char *static_header; - uint8_t nl_cmd; -}; - struct nlquery_opts { int err; }; @@ -132,8 +114,8 @@ static char algo_name_buf[256] = ""; static int64_t mcast_flags = -EOPNOTSUPP; static int64_t mcast_flags_priv = -EOPNOTSUPP;
-static int missing_mandatory_attrs(struct nlattr *attrs[], - const int mandatory[], int num) +int missing_mandatory_attrs(struct nlattr *attrs[], const int mandatory[], + int num) { int i;
@@ -1055,74 +1037,6 @@ static int bla_claim_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static const int bla_backbone_mandatory[] = { - BATADV_ATTR_BLA_VID, - BATADV_ATTR_BLA_BACKBONE, - BATADV_ATTR_BLA_CRC, - BATADV_ATTR_LAST_SEEN_MSECS, -}; - -static int bla_backbone_callback(struct nl_msg *msg, void *arg) -{ - struct nlattr *attrs[BATADV_ATTR_MAX+1]; - struct nlmsghdr *nlh = nlmsg_hdr(msg); - int last_seen_msecs, last_seen_secs; - struct print_opts *opts = arg; - struct bat_host *bat_host; - struct genlmsghdr *ghdr; - uint16_t backbone_crc; - uint8_t *backbone; - uint16_t vid; - - if (!genlmsg_valid_hdr(nlh, 0)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - ghdr = nlmsg_data(nlh); - - if (ghdr->cmd != BATADV_CMD_GET_BLA_BACKBONE) - return NL_OK; - - if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), - genlmsg_len(ghdr), batadv_netlink_policy)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - if (missing_mandatory_attrs(attrs, bla_backbone_mandatory, - ARRAY_SIZE(bla_backbone_mandatory))) { - fputs("Missing attributes from kernel\n", stderr); - exit(1); - } - - /* don't show own backbones */ - if (attrs[BATADV_ATTR_BLA_OWN]) - return NL_OK; - - vid = nla_get_u16(attrs[BATADV_ATTR_BLA_VID]); - backbone = nla_data(attrs[BATADV_ATTR_BLA_BACKBONE]); - backbone_crc = nla_get_u16(attrs[BATADV_ATTR_BLA_CRC]); - - last_seen_msecs = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]); - last_seen_secs = last_seen_msecs / 1000; - last_seen_msecs = last_seen_msecs % 1000; - - bat_host = bat_hosts_find_by_mac((char *)backbone); - if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) - printf("%02x:%02x:%02x:%02x:%02x:%02x ", - backbone[0], backbone[1], backbone[2], - backbone[3], backbone[4], backbone[5]); - else - printf("%17s ", bat_host->name); - - printf("on %5d %4i.%03is (0x%04x)\n", - BATADV_PRINT_VID(vid), last_seen_secs, last_seen_msecs, - backbone_crc); - - return NL_OK; -} - static const int dat_cache_mandatory[] = { BATADV_ATTR_DAT_CACHE_IP4ADDRESS, BATADV_ATTR_DAT_CACHE_HWADDRESS, @@ -1263,10 +1177,10 @@ static int mcast_flags_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static int netlink_print_common(char *mesh_iface, char *orig_iface, - int read_opt, float orig_timeout, - float watch_interval, const char *header, - uint8_t nl_cmd, nl_recvmsg_msg_cb_t callback) +int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt, + float orig_timeout, float watch_interval, + const char *header, uint8_t nl_cmd, + nl_recvmsg_msg_cb_t callback) { struct print_opts opts = { .read_opt = read_opt, @@ -1485,16 +1399,6 @@ int netlink_print_bla_claim(char *mesh_iface, char *orig_iface, int read_opts, bla_claim_callback); }
-int netlink_print_bla_backbone(char *mesh_iface, char *orig_iface, int read_opts, - float orig_timeout, float watch_interval) -{ - return netlink_print_common(mesh_iface, orig_iface, read_opts, - orig_timeout, watch_interval, - "Originator VID last seen (CRC )\n", - BATADV_CMD_GET_BLA_BACKBONE, - bla_backbone_callback); -} - int netlink_print_dat_cache(char *mesh_iface, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) { diff --git a/netlink.h b/netlink.h index 089e25e..7bda0d3 100644 --- a/netlink.h +++ b/netlink.h @@ -26,6 +26,16 @@ #include <netlink/genl/genl.h> #include <netlink/genl/ctrl.h>
+struct print_opts { + int read_opt; + float orig_timeout; + float watch_interval; + nl_recvmsg_msg_cb_t callback; + char *remaining_header; + const char *static_header; + uint8_t nl_cmd; +}; + struct ether_addr;
int netlink_print_routing_algos(void); @@ -43,8 +53,6 @@ int netlink_print_gateways(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); int netlink_print_bla_claim(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); -int netlink_print_bla_backbone(char *mesh_iface, char *orig_iface, int read_opt, - float orig_timeout, float watch_interval); int netlink_print_dat_cache(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); int netlink_print_mcast_flags(char *mesh_iface, char *orig_iface, int read_opt, @@ -58,4 +66,11 @@ int get_primarymac_netlink(const char *mesh_iface, uint8_t *primarymac);
extern struct nla_policy batadv_netlink_policy[];
+int missing_mandatory_attrs(struct nlattr *attrs[], const int mandatory[], + int num); +int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt, + float orig_timeout, float watch_interval, + const char *header, uint8_t nl_cmd, + nl_recvmsg_msg_cb_t callback); + #endif /* _BATCTL_NETLINK_H */
The netlink.c file contains to many different functions and mixes helper functions with actual command implementations. The debug table commands should be placed in separate files to better group the command specific code sections together.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + claimtable.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ debug.c | 9 ---- netlink.c | 84 ------------------------------------- netlink.h | 2 - 5 files changed, 133 insertions(+), 95 deletions(-) create mode 100644 claimtable.c
diff --git a/Makefile b/Makefile index 704a0d8..cdc5948 100755 --- a/Makefile +++ b/Makefile @@ -34,6 +34,7 @@ OBJ += backbonetable.o ifeq ($(CONFIG_BATCTL_BISECT),y) OBJ += $(OBJ_BISECT) endif +OBJ += claimtable.o OBJ += debugfs.o OBJ += debug.o OBJ += functions.o diff --git a/claimtable.c b/claimtable.c new file mode 100644 index 0000000..06473d0 --- /dev/null +++ b/claimtable.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Andrew Lunn andrew@lunn.ch + * Simon Wunderlich sw@simonwunderlich.de + * Sven Eckelmann sven@narfation.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <netinet/if_ether.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +#include "batadv_packet.h" +#include "batman_adv.h" +#include "bat-hosts.h" +#include "debug.h" +#include "functions.h" +#include "main.h" +#include "netlink.h" + +static const int bla_claim_mandatory[] = { + BATADV_ATTR_BLA_ADDRESS, + BATADV_ATTR_BLA_VID, + BATADV_ATTR_BLA_BACKBONE, + BATADV_ATTR_BLA_CRC, +}; + +static int bla_claim_callback(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct print_opts *opts = arg; + struct bat_host *bat_host; + struct genlmsghdr *ghdr; + uint16_t backbone_crc; + uint8_t *backbone; + uint8_t *client; + uint16_t vid; + char c = ' '; + + if (!genlmsg_valid_hdr(nlh, 0)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_BLA_CLAIM) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + if (missing_mandatory_attrs(attrs, bla_claim_mandatory, + ARRAY_SIZE(bla_claim_mandatory))) { + fputs("Missing attributes from kernel\n", stderr); + exit(1); + } + + if (attrs[BATADV_ATTR_BLA_OWN]) + c = '*'; + + client = nla_data(attrs[BATADV_ATTR_BLA_ADDRESS]); + vid = nla_get_u16(attrs[BATADV_ATTR_BLA_VID]); + backbone = nla_data(attrs[BATADV_ATTR_BLA_BACKBONE]); + backbone_crc = nla_get_u16(attrs[BATADV_ATTR_BLA_CRC]); + + bat_host = bat_hosts_find_by_mac((char *)client); + if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) + printf("%02x:%02x:%02x:%02x:%02x:%02x ", + client[0], client[1], client[2], + client[3], client[4], client[5]); + else + printf("%17s ", bat_host->name); + + printf("on %5d by ", BATADV_PRINT_VID(vid)); + + bat_host = bat_hosts_find_by_mac((char *)backbone); + if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) + printf("%02x:%02x:%02x:%02x:%02x:%02x ", + backbone[0], backbone[1], backbone[2], + backbone[3], backbone[4], backbone[5]); + else + printf("%17s ", bat_host->name); + + printf("[%c] (0x%04x)\n", c, backbone_crc); + + return NL_OK; +} + +static int netlink_print_bla_claim(char *mesh_iface, char *orig_iface, + int read_opts, float orig_timeout, + float watch_interval) +{ + return netlink_print_common(mesh_iface, orig_iface, read_opts, + orig_timeout, watch_interval, + "Client VID Originator [o] (CRC )\n", + BATADV_CMD_GET_BLA_CLAIM, + bla_claim_callback); +} + +static struct debug_table_data batctl_debug_table_claimtable = { + .debugfs_name = DEBUG_CLAIMTABLE, + .header_lines = 2, + .netlink_fn = netlink_print_bla_claim, +}; + +COMMAND_NAMED(DEBUGTABLE, claimtable, "cl", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_claimtable, ""); diff --git a/debug.c b/debug.c index 6eba9d8..c8a2845 100644 --- a/debug.c +++ b/debug.c @@ -251,15 +251,6 @@ static struct debug_table_data batctl_debug_table_transglobal = { COMMAND_NAMED(DEBUGTABLE, transglobal, "tg", handle_debug_table, COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_transglobal, "");
-static struct debug_table_data batctl_debug_table_claimtable = { - .debugfs_name = DEBUG_CLAIMTABLE, - .header_lines = 2, - .netlink_fn = netlink_print_bla_claim, -}; - -COMMAND_NAMED(DEBUGTABLE, claimtable, "cl", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_claimtable, ""); - static struct debug_table_data batctl_debug_table_dat_cache = { .debugfs_name = DEBUG_DAT_CACHE, .header_lines = 2, diff --git a/netlink.c b/netlink.c index cf7ff65..4d3c6f8 100644 --- a/netlink.c +++ b/netlink.c @@ -964,79 +964,6 @@ static int gateways_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static const int bla_claim_mandatory[] = { - BATADV_ATTR_BLA_ADDRESS, - BATADV_ATTR_BLA_VID, - BATADV_ATTR_BLA_BACKBONE, - BATADV_ATTR_BLA_CRC, -}; - -static int bla_claim_callback(struct nl_msg *msg, void *arg) -{ - struct nlattr *attrs[BATADV_ATTR_MAX+1]; - struct nlmsghdr *nlh = nlmsg_hdr(msg); - struct print_opts *opts = arg; - struct bat_host *bat_host; - struct genlmsghdr *ghdr; - uint16_t backbone_crc; - uint8_t *backbone; - uint8_t *client; - uint16_t vid; - char c = ' '; - - if (!genlmsg_valid_hdr(nlh, 0)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - ghdr = nlmsg_data(nlh); - - if (ghdr->cmd != BATADV_CMD_GET_BLA_CLAIM) - return NL_OK; - - if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), - genlmsg_len(ghdr), batadv_netlink_policy)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - if (missing_mandatory_attrs(attrs, bla_claim_mandatory, - ARRAY_SIZE(bla_claim_mandatory))) { - fputs("Missing attributes from kernel\n", stderr); - exit(1); - } - - if (attrs[BATADV_ATTR_BLA_OWN]) - c = '*'; - - client = nla_data(attrs[BATADV_ATTR_BLA_ADDRESS]); - vid = nla_get_u16(attrs[BATADV_ATTR_BLA_VID]); - backbone = nla_data(attrs[BATADV_ATTR_BLA_BACKBONE]); - backbone_crc = nla_get_u16(attrs[BATADV_ATTR_BLA_CRC]); - - bat_host = bat_hosts_find_by_mac((char *)client); - if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) - printf("%02x:%02x:%02x:%02x:%02x:%02x ", - client[0], client[1], client[2], - client[3], client[4], client[5]); - else - printf("%17s ", bat_host->name); - - printf("on %5d by ", BATADV_PRINT_VID(vid)); - - bat_host = bat_hosts_find_by_mac((char *)backbone); - if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) - printf("%02x:%02x:%02x:%02x:%02x:%02x ", - backbone[0], backbone[1], backbone[2], - backbone[3], backbone[4], backbone[5]); - else - printf("%17s ", bat_host->name); - - printf("[%c] (0x%04x)\n", c, backbone_crc); - - return NL_OK; -} - static const int dat_cache_mandatory[] = { BATADV_ATTR_DAT_CACHE_IP4ADDRESS, BATADV_ATTR_DAT_CACHE_HWADDRESS, @@ -1388,17 +1315,6 @@ int netlink_print_gateways(char *mesh_iface, char *orig_iface, int read_opts, gateways_callback); }
-int netlink_print_bla_claim(char *mesh_iface, char *orig_iface, int read_opts, - float orig_timeout, - float watch_interval) -{ - return netlink_print_common(mesh_iface, orig_iface, read_opts, - orig_timeout, watch_interval, - "Client VID Originator [o] (CRC )\n", - BATADV_CMD_GET_BLA_CLAIM, - bla_claim_callback); -} - int netlink_print_dat_cache(char *mesh_iface, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) { diff --git a/netlink.h b/netlink.h index 7bda0d3..514dfa3 100644 --- a/netlink.h +++ b/netlink.h @@ -51,8 +51,6 @@ int netlink_print_translocal(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); int netlink_print_gateways(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); -int netlink_print_bla_claim(char *mesh_iface, char *orig_iface, int read_opt, - float orig_timeout, float watch_interval); int netlink_print_dat_cache(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); int netlink_print_mcast_flags(char *mesh_iface, char *orig_iface, int read_opt,
The netlink.c file contains to many different functions and mixes helper functions with actual command implementations. The debug table commands should be placed in separate files to better group the command specific code sections together.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + claimtable.c | 4 +- dat_cache.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ debug.c | 9 ---- netlink.c | 96 --------------------------------------- netlink.h | 2 - 6 files changed, 148 insertions(+), 110 deletions(-) create mode 100644 dat_cache.c
diff --git a/Makefile b/Makefile index cdc5948..648c7bc 100755 --- a/Makefile +++ b/Makefile @@ -35,6 +35,7 @@ ifeq ($(CONFIG_BATCTL_BISECT),y) OBJ += $(OBJ_BISECT) endif OBJ += claimtable.o +OBJ += dat_cache.o OBJ += debugfs.o OBJ += debug.o OBJ += functions.o diff --git a/claimtable.c b/claimtable.c index 06473d0..06f42dc 100644 --- a/claimtable.c +++ b/claimtable.c @@ -1,9 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: * - * Andrew Lunn andrew@lunn.ch - * Simon Wunderlich sw@simonwunderlich.de - * Sven Eckelmann sven@narfation.org + * Linus Lüssing linus.luessing@c0d3.blue * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/dat_cache.c b/dat_cache.c new file mode 100644 index 0000000..a56fb11 --- /dev/null +++ b/dat_cache.c @@ -0,0 +1,146 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <arpa/inet.h> +#include <netinet/if_ether.h> +#include <netinet/in.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <sys/socket.h> + +#include "batadv_packet.h" +#include "batman_adv.h" +#include "bat-hosts.h" +#include "debug.h" +#include "functions.h" +#include "main.h" +#include "netlink.h" + +static const int dat_cache_mandatory[] = { + BATADV_ATTR_DAT_CACHE_IP4ADDRESS, + BATADV_ATTR_DAT_CACHE_HWADDRESS, + BATADV_ATTR_DAT_CACHE_VID, + BATADV_ATTR_LAST_SEEN_MSECS, +}; + +static int dat_cache_callback(struct nl_msg *msg, void *arg) +{ + int last_seen_msecs, last_seen_secs, last_seen_mins; + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct print_opts *opts = arg; + struct bat_host *bat_host; + struct genlmsghdr *ghdr; + struct in_addr in_addr; + uint8_t *hwaddr; + int16_t vid; + char *addr; + + if (!genlmsg_valid_hdr(nlh, 0)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_DAT_CACHE) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + if (missing_mandatory_attrs(attrs, dat_cache_mandatory, + ARRAY_SIZE(dat_cache_mandatory))) { + fputs("Missing attributes from kernel\n", stderr); + exit(1); + } + + in_addr.s_addr = nla_get_u32(attrs[BATADV_ATTR_DAT_CACHE_IP4ADDRESS]); + addr = inet_ntoa(in_addr); + hwaddr = nla_data(attrs[BATADV_ATTR_DAT_CACHE_HWADDRESS]); + vid = nla_get_u16(attrs[BATADV_ATTR_DAT_CACHE_VID]); + + last_seen_msecs = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]); + last_seen_mins = last_seen_msecs / 60000; + last_seen_msecs = last_seen_msecs % 60000; + last_seen_secs = last_seen_msecs / 1000; + + if (opts->read_opt & MULTICAST_ONLY && !(addr[0] & 0x01)) + return NL_OK; + + if (opts->read_opt & UNICAST_ONLY && (addr[0] & 0x01)) + return NL_OK; + + printf(" * %15s ", addr); + + bat_host = bat_hosts_find_by_mac((char *)hwaddr); + if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) + printf("%02x:%02x:%02x:%02x:%02x:%02x ", + hwaddr[0], hwaddr[1], hwaddr[2], + hwaddr[3], hwaddr[4], hwaddr[5]); + else + printf("%17s ", bat_host->name); + + printf("%4i %6i:%02i\n", + BATADV_PRINT_VID(vid), last_seen_mins, last_seen_secs); + + return NL_OK; +} + +static int netlink_print_dat_cache(char *mesh_iface, char *orig_iface, + int read_opts, float orig_timeout, + float watch_interval) +{ + char *header; + int ret; + + ret = asprintf(&header, "Distributed ARP Table (%s):\n%s\n", + mesh_iface, + " IPv4 MAC VID last-seen"); + + if (ret < 0) + return ret; + + ret = netlink_print_common(mesh_iface, orig_iface, read_opts, + orig_timeout, watch_interval, header, + BATADV_CMD_GET_DAT_CACHE, + dat_cache_callback); + + free(header); + return ret; +} + +static struct debug_table_data batctl_debug_table_dat_cache = { + .debugfs_name = DEBUG_DAT_CACHE, + .header_lines = 2, + .netlink_fn = netlink_print_dat_cache, +}; + +COMMAND_NAMED(DEBUGTABLE, dat_cache, "dc", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_dat_cache, ""); diff --git a/debug.c b/debug.c index c8a2845..29c8252 100644 --- a/debug.c +++ b/debug.c @@ -251,15 +251,6 @@ static struct debug_table_data batctl_debug_table_transglobal = { COMMAND_NAMED(DEBUGTABLE, transglobal, "tg", handle_debug_table, COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_transglobal, "");
-static struct debug_table_data batctl_debug_table_dat_cache = { - .debugfs_name = DEBUG_DAT_CACHE, - .header_lines = 2, - .netlink_fn = netlink_print_dat_cache, -}; - -COMMAND_NAMED(DEBUGTABLE, dat_cache, "dc", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_dat_cache, ""); - static struct debug_table_data batctl_debug_table_nc_nodes = { .debugfs_name = DEBUG_NC_NODES, .header_lines = 0, diff --git a/netlink.c b/netlink.c index 4d3c6f8..42fe4a0 100644 --- a/netlink.c +++ b/netlink.c @@ -964,80 +964,6 @@ static int gateways_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static const int dat_cache_mandatory[] = { - BATADV_ATTR_DAT_CACHE_IP4ADDRESS, - BATADV_ATTR_DAT_CACHE_HWADDRESS, - BATADV_ATTR_DAT_CACHE_VID, - BATADV_ATTR_LAST_SEEN_MSECS, -}; - -static int dat_cache_callback(struct nl_msg *msg, void *arg) -{ - int last_seen_msecs, last_seen_secs, last_seen_mins; - struct nlattr *attrs[BATADV_ATTR_MAX+1]; - struct nlmsghdr *nlh = nlmsg_hdr(msg); - struct print_opts *opts = arg; - struct bat_host *bat_host; - struct genlmsghdr *ghdr; - struct in_addr in_addr; - uint8_t *hwaddr; - int16_t vid; - char *addr; - - if (!genlmsg_valid_hdr(nlh, 0)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - ghdr = nlmsg_data(nlh); - - if (ghdr->cmd != BATADV_CMD_GET_DAT_CACHE) - return NL_OK; - - if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), - genlmsg_len(ghdr), batadv_netlink_policy)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - if (missing_mandatory_attrs(attrs, dat_cache_mandatory, - ARRAY_SIZE(dat_cache_mandatory))) { - fputs("Missing attributes from kernel\n", stderr); - exit(1); - } - - in_addr.s_addr = nla_get_u32(attrs[BATADV_ATTR_DAT_CACHE_IP4ADDRESS]); - addr = inet_ntoa(in_addr); - hwaddr = nla_data(attrs[BATADV_ATTR_DAT_CACHE_HWADDRESS]); - vid = nla_get_u16(attrs[BATADV_ATTR_DAT_CACHE_VID]); - - last_seen_msecs = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]); - last_seen_mins = last_seen_msecs / 60000; - last_seen_msecs = last_seen_msecs % 60000; - last_seen_secs = last_seen_msecs / 1000; - - if (opts->read_opt & MULTICAST_ONLY && !(addr[0] & 0x01)) - return NL_OK; - - if (opts->read_opt & UNICAST_ONLY && (addr[0] & 0x01)) - return NL_OK; - - printf(" * %15s ", addr); - - bat_host = bat_hosts_find_by_mac((char *)hwaddr); - if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) - printf("%02x:%02x:%02x:%02x:%02x:%02x ", - hwaddr[0], hwaddr[1], hwaddr[2], - hwaddr[3], hwaddr[4], hwaddr[5]); - else - printf("%17s ", bat_host->name); - - printf("%4i %6i:%02i\n", - BATADV_PRINT_VID(vid), last_seen_mins, last_seen_secs); - - return NL_OK; -} - static const int mcast_flags_mandatory[] = { BATADV_ATTR_ORIG_ADDRESS, }; @@ -1315,28 +1241,6 @@ int netlink_print_gateways(char *mesh_iface, char *orig_iface, int read_opts, gateways_callback); }
-int netlink_print_dat_cache(char *mesh_iface, char *orig_iface, int read_opts, - float orig_timeout, float watch_interval) -{ - char *header; - int ret; - - ret = asprintf(&header, "Distributed ARP Table (%s):\n%s\n", - mesh_iface, - " IPv4 MAC VID last-seen"); - - if (ret < 0) - return ret; - - ret = netlink_print_common(mesh_iface, orig_iface, read_opts, - orig_timeout, watch_interval, header, - BATADV_CMD_GET_DAT_CACHE, - dat_cache_callback); - - free(header); - return ret; -} - int netlink_print_mcast_flags(char *mesh_iface, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) { diff --git a/netlink.h b/netlink.h index 514dfa3..7549838 100644 --- a/netlink.h +++ b/netlink.h @@ -51,8 +51,6 @@ int netlink_print_translocal(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); int netlink_print_gateways(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); -int netlink_print_dat_cache(char *mesh_iface, char *orig_iface, int read_opt, - float orig_timeout, float watch_interval); int netlink_print_mcast_flags(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval);
The netlink.c file contains to many different functions and mixes helper functions with actual command implementations. The debug table commands should be placed in separate files to better group the command specific code sections together.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + debug.c | 9 ---- gateways.c | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ netlink.c | 130 ++------------------------------------------- netlink.h | 8 +-- 5 files changed, 183 insertions(+), 140 deletions(-) create mode 100644 gateways.c
diff --git a/Makefile b/Makefile index 648c7bc..3a8e785 100755 --- a/Makefile +++ b/Makefile @@ -39,6 +39,7 @@ OBJ += dat_cache.o OBJ += debugfs.o OBJ += debug.o OBJ += functions.o +OBJ += gateways.o OBJ += genl.o OBJ += gw_mode.o OBJ += hash.o diff --git a/debug.c b/debug.c index 29c8252..7bf8bff 100644 --- a/debug.c +++ b/debug.c @@ -220,15 +220,6 @@ static struct debug_table_data batctl_debug_table_originators = { COMMAND_NAMED(DEBUGTABLE, originators, "o", handle_debug_table, COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_originators, "");
-static struct debug_table_data batctl_debug_table_gateways = { - .debugfs_name = "gateways", - .header_lines = 1, - .netlink_fn = netlink_print_gateways, -}; - -COMMAND_NAMED(DEBUGTABLE, gateways, "gwl", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_gateways, ""); - static struct debug_table_data batctl_debug_table_translocal = { .debugfs_name = "transtable_local", .header_lines = 2, diff --git a/gateways.c b/gateways.c new file mode 100644 index 0000000..f81bf20 --- /dev/null +++ b/gateways.c @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Andrew Lunn andrew@lunn.ch + * Sven Eckelmann sven@narfation.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <errno.h> +#include <net/if.h> +#include <netinet/if_ether.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "batadv_packet.h" +#include "batman_adv.h" +#include "bat-hosts.h" +#include "debug.h" +#include "functions.h" +#include "main.h" +#include "netlink.h" + +static const int gateways_mandatory[] = { + BATADV_ATTR_ORIG_ADDRESS, + BATADV_ATTR_ROUTER, + BATADV_ATTR_HARD_IFNAME, + BATADV_ATTR_BANDWIDTH_DOWN, + BATADV_ATTR_BANDWIDTH_UP, +}; + +static int gateways_callback(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct print_opts *opts = arg; + struct bat_host *bat_host; + struct genlmsghdr *ghdr; + const char *primary_if; + uint32_t bandwidth_down; + uint32_t bandwidth_up; + uint32_t throughput; + uint8_t *router; + uint8_t *orig; + char c = ' '; + uint8_t tq; + + if (!genlmsg_valid_hdr(nlh, 0)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_GATEWAYS) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + if (missing_mandatory_attrs(attrs, gateways_mandatory, + ARRAY_SIZE(gateways_mandatory))) { + fputs("Missing attributes from kernel\n", stderr); + exit(1); + } + + if (attrs[BATADV_ATTR_FLAG_BEST]) + c = '*'; + + orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]); + router = nla_data(attrs[BATADV_ATTR_ROUTER]); + primary_if = nla_get_string(attrs[BATADV_ATTR_HARD_IFNAME]); + bandwidth_down = nla_get_u32(attrs[BATADV_ATTR_BANDWIDTH_DOWN]); + bandwidth_up = nla_get_u32(attrs[BATADV_ATTR_BANDWIDTH_UP]); + + printf("%c ", c); + + bat_host = bat_hosts_find_by_mac((char *)orig); + if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) + printf("%02x:%02x:%02x:%02x:%02x:%02x ", + orig[0], orig[1], orig[2], + orig[3], orig[4], orig[5]); + else + printf("%17s ", bat_host->name); + + if (attrs[BATADV_ATTR_THROUGHPUT]) { + throughput = nla_get_u32(attrs[BATADV_ATTR_THROUGHPUT]); + printf("(%9u.%1u) ", throughput / 10, throughput % 10); + } else if (attrs[BATADV_ATTR_TQ]) { + tq = nla_get_u8(attrs[BATADV_ATTR_TQ]); + printf("(%3i) ", tq); + } + + bat_host = bat_hosts_find_by_mac((char *)router); + if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) + printf("%02x:%02x:%02x:%02x:%02x:%02x ", + router[0], router[1], router[2], + router[3], router[4], router[5]); + else + printf("%17s ", bat_host->name); + + printf("[%10s]: %u.%u/%u.%u MBit\n", + primary_if, bandwidth_down / 10, bandwidth_down % 10, + bandwidth_up / 10, bandwidth_up % 10); + + return NL_OK; +} + +static int netlink_print_gateways(char *mesh_iface, char *orig_iface, + int read_opts, float orig_timeout, + float watch_interval) +{ + char *header = NULL; + char *info_header; + int ifindex; + + ifindex = if_nametoindex(mesh_iface); + if (!ifindex) { + fprintf(stderr, "Interface %s is unknown\n", mesh_iface); + return -ENODEV; + } + + /* only parse routing algorithm name */ + last_err = -EINVAL; + info_header = netlink_get_info(ifindex, BATADV_CMD_GET_ORIGINATORS, NULL); + free(info_header); + + if (strlen(algo_name_buf) == 0) + return last_err; + + if (!strcmp("BATMAN_IV", algo_name_buf)) + header = " Router ( TQ) Next Hop [outgoingIf] Bandwidth\n"; + if (!strcmp("BATMAN_V", algo_name_buf)) + header = " Router ( throughput) Next Hop [outgoingIf] Bandwidth\n"; + + if (!header) + return -EINVAL; + + return netlink_print_common(mesh_iface, orig_iface, read_opts, + orig_timeout, watch_interval, + header, + BATADV_CMD_GET_GATEWAYS, + gateways_callback); +} + +static struct debug_table_data batctl_debug_table_gateways = { + .debugfs_name = "gateways", + .header_lines = 1, + .netlink_fn = netlink_print_gateways, +}; + +COMMAND_NAMED(DEBUGTABLE, gateways, "gwl", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_gateways, ""); diff --git a/netlink.c b/netlink.c index 42fe4a0..c3b2bad 100644 --- a/netlink.c +++ b/netlink.c @@ -109,8 +109,8 @@ struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = { [BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NLA_U32 }, };
-static int last_err; -static char algo_name_buf[256] = ""; +int last_err; +char algo_name_buf[256] = ""; static int64_t mcast_flags = -EOPNOTSUPP; static int64_t mcast_flags_priv = -EOPNOTSUPP;
@@ -283,7 +283,7 @@ static int info_callback(struct nl_msg *msg, void *arg) return NL_STOP; }
-static char *netlink_get_info(int ifindex, uint8_t nl_cmd, const char *header) +char *netlink_get_info(int ifindex, uint8_t nl_cmd, const char *header) { struct nl_sock *sock; struct nl_msg *msg; @@ -876,94 +876,6 @@ static int translocal_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static const int gateways_mandatory[] = { - BATADV_ATTR_ORIG_ADDRESS, - BATADV_ATTR_ROUTER, - BATADV_ATTR_HARD_IFNAME, - BATADV_ATTR_BANDWIDTH_DOWN, - BATADV_ATTR_BANDWIDTH_UP, -}; - -static int gateways_callback(struct nl_msg *msg, void *arg) -{ - struct nlattr *attrs[BATADV_ATTR_MAX+1]; - struct nlmsghdr *nlh = nlmsg_hdr(msg); - struct print_opts *opts = arg; - struct bat_host *bat_host; - struct genlmsghdr *ghdr; - const char *primary_if; - uint32_t bandwidth_down; - uint32_t bandwidth_up; - uint32_t throughput; - uint8_t *router; - uint8_t *orig; - char c = ' '; - uint8_t tq; - - if (!genlmsg_valid_hdr(nlh, 0)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - ghdr = nlmsg_data(nlh); - - if (ghdr->cmd != BATADV_CMD_GET_GATEWAYS) - return NL_OK; - - if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), - genlmsg_len(ghdr), batadv_netlink_policy)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - if (missing_mandatory_attrs(attrs, gateways_mandatory, - ARRAY_SIZE(gateways_mandatory))) { - fputs("Missing attributes from kernel\n", stderr); - exit(1); - } - - if (attrs[BATADV_ATTR_FLAG_BEST]) - c = '*'; - - orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]); - router = nla_data(attrs[BATADV_ATTR_ROUTER]); - primary_if = nla_get_string(attrs[BATADV_ATTR_HARD_IFNAME]); - bandwidth_down = nla_get_u32(attrs[BATADV_ATTR_BANDWIDTH_DOWN]); - bandwidth_up = nla_get_u32(attrs[BATADV_ATTR_BANDWIDTH_UP]); - - printf("%c ", c); - - bat_host = bat_hosts_find_by_mac((char *)orig); - if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) - printf("%02x:%02x:%02x:%02x:%02x:%02x ", - orig[0], orig[1], orig[2], - orig[3], orig[4], orig[5]); - else - printf("%17s ", bat_host->name); - - if (attrs[BATADV_ATTR_THROUGHPUT]) { - throughput = nla_get_u32(attrs[BATADV_ATTR_THROUGHPUT]); - printf("(%9u.%1u) ", throughput / 10, throughput % 10); - } else if (attrs[BATADV_ATTR_TQ]) { - tq = nla_get_u8(attrs[BATADV_ATTR_TQ]); - printf("(%3i) ", tq); - } - - bat_host = bat_hosts_find_by_mac((char *)router); - if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) - printf("%02x:%02x:%02x:%02x:%02x:%02x ", - router[0], router[1], router[2], - router[3], router[4], router[5]); - else - printf("%17s ", bat_host->name); - - printf("[%10s]: %u.%u/%u.%u MBit\n", - primary_if, bandwidth_down / 10, bandwidth_down % 10, - bandwidth_up / 10, bandwidth_up % 10); - - return NL_OK; -} - static const int mcast_flags_mandatory[] = { BATADV_ATTR_ORIG_ADDRESS, }; @@ -1205,42 +1117,6 @@ int netlink_print_translocal(char *mesh_iface, char *orig_iface, int read_opts, translocal_callback); }
-int netlink_print_gateways(char *mesh_iface, char *orig_iface, int read_opts, - float orig_timeout, - float watch_interval) -{ char *header = NULL; - char *info_header; - int ifindex; - - ifindex = if_nametoindex(mesh_iface); - if (!ifindex) { - fprintf(stderr, "Interface %s is unknown\n", mesh_iface); - return -ENODEV; - } - - /* only parse routing algorithm name */ - last_err = -EINVAL; - info_header = netlink_get_info(ifindex, BATADV_CMD_GET_ORIGINATORS, NULL); - free(info_header); - - if (strlen(algo_name_buf) == 0) - return last_err; - - if (!strcmp("BATMAN_IV", algo_name_buf)) - header = " Router ( TQ) Next Hop [outgoingIf] Bandwidth\n"; - if (!strcmp("BATMAN_V", algo_name_buf)) - header = " Router ( throughput) Next Hop [outgoingIf] Bandwidth\n"; - - if (!header) - return -EINVAL; - - return netlink_print_common(mesh_iface, orig_iface, read_opts, - orig_timeout, watch_interval, - header, - BATADV_CMD_GET_GATEWAYS, - gateways_callback); -} - int netlink_print_mcast_flags(char *mesh_iface, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) { diff --git a/netlink.h b/netlink.h index 7549838..ecf4b01 100644 --- a/netlink.h +++ b/netlink.h @@ -43,17 +43,14 @@ int netlink_print_originators(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); int netlink_print_neighbors(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); -int netlink_print_gateways(char *mesh_iface, char *orig_iface, int read_opt, - float orig_timeout, float watch_interval); int netlink_print_transglobal(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); int netlink_print_translocal(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); -int netlink_print_gateways(char *mesh_iface, char *orig_iface, int read_opt, - float orig_timeout, float watch_interval); int netlink_print_mcast_flags(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval);
+char *netlink_get_info(int ifindex, uint8_t nl_cmd, const char *header); int translate_mac_netlink(const char *mesh_iface, const struct ether_addr *mac, struct ether_addr *mac_out); int get_nexthop_netlink(const char *mesh_iface, const struct ether_addr *mac, @@ -69,4 +66,7 @@ int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt, const char *header, uint8_t nl_cmd, nl_recvmsg_msg_cb_t callback);
+extern char algo_name_buf[256]; +extern int last_err; + #endif /* _BATCTL_NETLINK_H */
The netlink.c file contains to many different functions and mixes helper functions with actual command implementations. The debug table commands should be placed in separate files to better group the command specific code sections together.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + debug.c | 9 --- gateways.c | 3 +- mcast_flags.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ netlink.c | 133 +------------------------------------------ netlink.h | 5 +- 6 files changed, 186 insertions(+), 144 deletions(-) create mode 100644 mcast_flags.c
diff --git a/Makefile b/Makefile index 3a8e785..a725986 100755 --- a/Makefile +++ b/Makefile @@ -48,6 +48,7 @@ OBJ += interface.o OBJ += loglevel.o OBJ += log.o OBJ += main.o +OBJ += mcast_flags.o OBJ += netlink.o OBJ += ping.o OBJ += routing_algo.o diff --git a/debug.c b/debug.c index 7bf8bff..4b480a3 100644 --- a/debug.c +++ b/debug.c @@ -249,12 +249,3 @@ static struct debug_table_data batctl_debug_table_nc_nodes = {
COMMAND_NAMED(DEBUGTABLE, nc_nodes, "nn", handle_debug_table, COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_nc_nodes, ""); - -static struct debug_table_data batctl_debug_table_mcast_flags = { - .debugfs_name = DEBUG_MCAST_FLAGS, - .header_lines = 6, - .netlink_fn = netlink_print_mcast_flags, -}; - -COMMAND_NAMED(DEBUGTABLE, mcast_flags, "mf", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_mcast_flags, ""); diff --git a/gateways.c b/gateways.c index f81bf20..ca5d6ec 100644 --- a/gateways.c +++ b/gateways.c @@ -1,8 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: * - * Andrew Lunn andrew@lunn.ch - * Sven Eckelmann sven@narfation.org + * Linus Lüssing linus.luessing@c0d3.blue * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public diff --git a/mcast_flags.c b/mcast_flags.c new file mode 100644 index 0000000..e35cce3 --- /dev/null +++ b/mcast_flags.c @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <errno.h> +#include <net/if.h> +#include <netinet/if_ether.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +#include "batadv_packet.h" +#include "batman_adv.h" +#include "bat-hosts.h" +#include "debug.h" +#include "functions.h" +#include "main.h" +#include "netlink.h" + +static const int mcast_flags_mandatory[] = { + BATADV_ATTR_ORIG_ADDRESS, +}; + +static int mcast_flags_callback(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct print_opts *opts = arg; + struct bat_host *bat_host; + struct genlmsghdr *ghdr; + uint32_t flags; + uint8_t *addr; + + if (!genlmsg_valid_hdr(nlh, 0)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_MCAST_FLAGS) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + if (missing_mandatory_attrs(attrs, mcast_flags_mandatory, + ARRAY_SIZE(mcast_flags_mandatory))) { + fputs("Missing attributes from kernel\n", stderr); + exit(1); + } + + addr = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]); + + if (opts->read_opt & MULTICAST_ONLY && !(addr[0] & 0x01)) + return NL_OK; + + if (opts->read_opt & UNICAST_ONLY && (addr[0] & 0x01)) + return NL_OK; + + bat_host = bat_hosts_find_by_mac((char *)addr); + if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) + printf("%02x:%02x:%02x:%02x:%02x:%02x ", + addr[0], addr[1], addr[2], + addr[3], addr[4], addr[5]); + else + printf("%17s ", bat_host->name); + + if (attrs[BATADV_ATTR_MCAST_FLAGS]) { + flags = nla_get_u32(attrs[BATADV_ATTR_MCAST_FLAGS]); + + printf("[%c%c%c]\n", + flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES ? 'U' : '.', + flags & BATADV_MCAST_WANT_ALL_IPV4 ? '4' : '.', + flags & BATADV_MCAST_WANT_ALL_IPV6 ? '6' : '.'); + } else { + printf("-\n"); + } + + return NL_OK; +} + +static int netlink_print_mcast_flags(char *mesh_iface, char *orig_iface, + int read_opts, float orig_timeout, + float watch_interval) +{ + char querier4, querier6, shadowing4, shadowing6; + char *info_header; + char *header; + bool bridged; + int ifindex; + int ret; + + ifindex = if_nametoindex(mesh_iface); + if (!ifindex) { + fprintf(stderr, "Interface %s is unknown\n", mesh_iface); + return -ENODEV; + } + + /* only parse own multicast flags */ + info_header = netlink_get_info(ifindex, BATADV_CMD_GET_MCAST_FLAGS, NULL); + free(info_header); + + if (mcast_flags == -EOPNOTSUPP || mcast_flags_priv == -EOPNOTSUPP) + return -EOPNOTSUPP; + + bridged = mcast_flags_priv & BATADV_MCAST_FLAGS_BRIDGED; + + if (bridged) { + querier4 = (mcast_flags_priv & BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS) ? '.' : '4'; + querier6 = (mcast_flags_priv & BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS) ? '.' : '6'; + shadowing4 = (mcast_flags_priv & BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING) ? '4' : '.'; + shadowing6 = (mcast_flags_priv & BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING) ? '6' : '.'; + } else { + querier4 = '?'; + querier6 = '?'; + shadowing4 = '?'; + shadowing6 = '?'; + } + + ret = asprintf(&header, + "Multicast flags (own flags: [%c%c%c])\n" + "* Bridged [U]\t\t\t\t%c\n" + "* No IGMP/MLD Querier [4/6]:\t\t%c/%c\n" + "* Shadowing IGMP/MLD Querier [4/6]:\t%c/%c\n" + "-------------------------------------------\n" + " %-10s %s\n", + (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.', + (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.', + (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.', + bridged ? 'U' : '.', + querier4, querier6, shadowing4, shadowing6, + "Originator", "Flags"); + + if (ret < 0) + return ret; + + ret = netlink_print_common(mesh_iface, orig_iface, read_opts, + orig_timeout, watch_interval, header, + BATADV_CMD_GET_MCAST_FLAGS, + mcast_flags_callback); + + free(header); + return ret; +} + +static struct debug_table_data batctl_debug_table_mcast_flags = { + .debugfs_name = DEBUG_MCAST_FLAGS, + .header_lines = 6, + .netlink_fn = netlink_print_mcast_flags, +}; + +COMMAND_NAMED(DEBUGTABLE, mcast_flags, "mf", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_mcast_flags, ""); diff --git a/netlink.c b/netlink.c index c3b2bad..4f2199e 100644 --- a/netlink.c +++ b/netlink.c @@ -111,8 +111,8 @@ struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = {
int last_err; char algo_name_buf[256] = ""; -static int64_t mcast_flags = -EOPNOTSUPP; -static int64_t mcast_flags_priv = -EOPNOTSUPP; +int64_t mcast_flags = -EOPNOTSUPP; +int64_t mcast_flags_priv = -EOPNOTSUPP;
int missing_mandatory_attrs(struct nlattr *attrs[], const int mandatory[], int num) @@ -876,72 +876,6 @@ static int translocal_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static const int mcast_flags_mandatory[] = { - BATADV_ATTR_ORIG_ADDRESS, -}; - -static int mcast_flags_callback(struct nl_msg *msg, void *arg) -{ - struct nlattr *attrs[BATADV_ATTR_MAX+1]; - struct nlmsghdr *nlh = nlmsg_hdr(msg); - struct print_opts *opts = arg; - struct bat_host *bat_host; - struct genlmsghdr *ghdr; - uint32_t flags; - uint8_t *addr; - - if (!genlmsg_valid_hdr(nlh, 0)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - ghdr = nlmsg_data(nlh); - - if (ghdr->cmd != BATADV_CMD_GET_MCAST_FLAGS) - return NL_OK; - - if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), - genlmsg_len(ghdr), batadv_netlink_policy)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - if (missing_mandatory_attrs(attrs, mcast_flags_mandatory, - ARRAY_SIZE(mcast_flags_mandatory))) { - fputs("Missing attributes from kernel\n", stderr); - exit(1); - } - - addr = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]); - - if (opts->read_opt & MULTICAST_ONLY && !(addr[0] & 0x01)) - return NL_OK; - - if (opts->read_opt & UNICAST_ONLY && (addr[0] & 0x01)) - return NL_OK; - - bat_host = bat_hosts_find_by_mac((char *)addr); - if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) - printf("%02x:%02x:%02x:%02x:%02x:%02x ", - addr[0], addr[1], addr[2], - addr[3], addr[4], addr[5]); - else - printf("%17s ", bat_host->name); - - if (attrs[BATADV_ATTR_MCAST_FLAGS]) { - flags = nla_get_u32(attrs[BATADV_ATTR_MCAST_FLAGS]); - - printf("[%c%c%c]\n", - flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES ? 'U' : '.', - flags & BATADV_MCAST_WANT_ALL_IPV4 ? '4' : '.', - flags & BATADV_MCAST_WANT_ALL_IPV6 ? '6' : '.'); - } else { - printf("-\n"); - } - - return NL_OK; -} - int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval, const char *header, uint8_t nl_cmd, @@ -1117,69 +1051,6 @@ int netlink_print_translocal(char *mesh_iface, char *orig_iface, int read_opts, translocal_callback); }
-int netlink_print_mcast_flags(char *mesh_iface, char *orig_iface, int read_opts, - float orig_timeout, float watch_interval) -{ - char querier4, querier6, shadowing4, shadowing6; - char *info_header; - char *header; - bool bridged; - int ifindex; - int ret; - - ifindex = if_nametoindex(mesh_iface); - if (!ifindex) { - fprintf(stderr, "Interface %s is unknown\n", mesh_iface); - return -ENODEV; - } - - /* only parse own multicast flags */ - info_header = netlink_get_info(ifindex, BATADV_CMD_GET_MCAST_FLAGS, NULL); - free(info_header); - - if (mcast_flags == -EOPNOTSUPP || mcast_flags_priv == -EOPNOTSUPP) - return -EOPNOTSUPP; - - bridged = mcast_flags_priv & BATADV_MCAST_FLAGS_BRIDGED; - - if (bridged) { - querier4 = (mcast_flags_priv & BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS) ? '.' : '4'; - querier6 = (mcast_flags_priv & BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS) ? '.' : '6'; - shadowing4 = (mcast_flags_priv & BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING) ? '4' : '.'; - shadowing6 = (mcast_flags_priv & BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING) ? '6' : '.'; - } else { - querier4 = '?'; - querier6 = '?'; - shadowing4 = '?'; - shadowing6 = '?'; - } - - ret = asprintf(&header, - "Multicast flags (own flags: [%c%c%c])\n" - "* Bridged [U]\t\t\t\t%c\n" - "* No IGMP/MLD Querier [4/6]:\t\t%c/%c\n" - "* Shadowing IGMP/MLD Querier [4/6]:\t%c/%c\n" - "-------------------------------------------\n" - " %-10s %s\n", - (mcast_flags & BATADV_MCAST_WANT_ALL_UNSNOOPABLES) ? 'U' : '.', - (mcast_flags & BATADV_MCAST_WANT_ALL_IPV4) ? '4' : '.', - (mcast_flags & BATADV_MCAST_WANT_ALL_IPV6) ? '6' : '.', - bridged ? 'U' : '.', - querier4, querier6, shadowing4, shadowing6, - "Originator", "Flags"); - - if (ret < 0) - return ret; - - ret = netlink_print_common(mesh_iface, orig_iface, read_opts, - orig_timeout, watch_interval, header, - BATADV_CMD_GET_MCAST_FLAGS, - mcast_flags_callback); - - free(header); - return ret; -} - static int nlquery_error_cb(struct sockaddr_nl *nla __maybe_unused, struct nlmsgerr *nlerr, void *arg) { diff --git a/netlink.h b/netlink.h index ecf4b01..e0fa466 100644 --- a/netlink.h +++ b/netlink.h @@ -25,6 +25,7 @@
#include <netlink/genl/genl.h> #include <netlink/genl/ctrl.h> +#include <stdint.h>
struct print_opts { int read_opt; @@ -47,8 +48,6 @@ int netlink_print_transglobal(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); int netlink_print_translocal(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); -int netlink_print_mcast_flags(char *mesh_iface, char *orig_iface, int read_opt, - float orig_timeout, float watch_interval);
char *netlink_get_info(int ifindex, uint8_t nl_cmd, const char *header); int translate_mac_netlink(const char *mesh_iface, const struct ether_addr *mac, @@ -68,5 +67,7 @@ int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt,
extern char algo_name_buf[256]; extern int last_err; +extern int64_t mcast_flags; +extern int64_t mcast_flags_priv;
#endif /* _BATCTL_NETLINK_H */
The other commands are stored in separate files and nc_nodes might also receive a netlink implementation. The latter would increase the complexity significantly and thus justify that the command is also added via an extra file.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + debug.c | 8 -------- nc_nodes.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 nc_nodes.c
diff --git a/Makefile b/Makefile index a725986..ac4824b 100755 --- a/Makefile +++ b/Makefile @@ -49,6 +49,7 @@ OBJ += loglevel.o OBJ += log.o OBJ += main.o OBJ += mcast_flags.o +OBJ += nc_nodes.o OBJ += netlink.o OBJ += ping.o OBJ += routing_algo.o diff --git a/debug.c b/debug.c index 4b480a3..531c6aa 100644 --- a/debug.c +++ b/debug.c @@ -241,11 +241,3 @@ static struct debug_table_data batctl_debug_table_transglobal = {
COMMAND_NAMED(DEBUGTABLE, transglobal, "tg", handle_debug_table, COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_transglobal, ""); - -static struct debug_table_data batctl_debug_table_nc_nodes = { - .debugfs_name = DEBUG_NC_NODES, - .header_lines = 0, -}; - -COMMAND_NAMED(DEBUGTABLE, nc_nodes, "nn", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_nc_nodes, ""); diff --git a/nc_nodes.c b/nc_nodes.c new file mode 100644 index 0000000..9cf437d --- /dev/null +++ b/nc_nodes.c @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include "debug.h" +#include "main.h" + +static struct debug_table_data batctl_debug_table_nc_nodes = { + .debugfs_name = DEBUG_NC_NODES, + .header_lines = 0, +}; + +COMMAND_NAMED(DEBUGTABLE, nc_nodes, "nn", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_nc_nodes, "");
The netlink.c file contains to many different functions and mixes helper functions with actual command implementations. The debug table commands should be placed in separate files to better group the command specific code sections together.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + debug.c | 9 ---- neighbors.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ netlink.c | 94 ---------------------------------------- netlink.h | 2 - 5 files changed, 142 insertions(+), 105 deletions(-) create mode 100644 neighbors.c
diff --git a/Makefile b/Makefile index ac4824b..d447663 100755 --- a/Makefile +++ b/Makefile @@ -50,6 +50,7 @@ OBJ += log.o OBJ += main.o OBJ += mcast_flags.o OBJ += nc_nodes.o +OBJ += neighbors.o OBJ += netlink.o OBJ += ping.o OBJ += routing_algo.o diff --git a/debug.c b/debug.c index 531c6aa..a5e7276 100644 --- a/debug.c +++ b/debug.c @@ -200,15 +200,6 @@ int debug_print_routing_algos(void) return read_file(full_path, DEBUG_ROUTING_ALGOS, 0, 0, 0, 0); }
-static struct debug_table_data batctl_debug_table_neighbors = { - .debugfs_name = "neighbors", - .header_lines = 2, - .netlink_fn = netlink_print_neighbors, -}; - -COMMAND_NAMED(DEBUGTABLE, neighbors, "n", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_neighbors, ""); - static struct debug_table_data batctl_debug_table_originators = { .debugfs_name = "originators", .header_lines = 2, diff --git a/neighbors.c b/neighbors.c new file mode 100644 index 0000000..f7ea9ec --- /dev/null +++ b/neighbors.c @@ -0,0 +1,141 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Andrew Lunn andrew@lunn.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <net/if.h> +#include <netinet/if_ether.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +#include "batadv_packet.h" +#include "batman_adv.h" +#include "bat-hosts.h" +#include "debug.h" +#include "functions.h" +#include "main.h" +#include "netlink.h" + +static const int neighbors_mandatory[] = { + BATADV_ATTR_NEIGH_ADDRESS, + BATADV_ATTR_HARD_IFINDEX, + BATADV_ATTR_LAST_SEEN_MSECS, +}; + +static int neighbors_callback(struct nl_msg *msg, void *arg) +{ + unsigned throughput_mbits, throughput_kbits; + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + int last_seen_msecs, last_seen_secs; + struct print_opts *opts = arg; + struct bat_host *bat_host; + char ifname[IF_NAMESIZE]; + struct genlmsghdr *ghdr; + uint8_t *neigh; + + if (!genlmsg_valid_hdr(nlh, 0)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_NEIGHBORS) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + if (missing_mandatory_attrs(attrs, neighbors_mandatory, + ARRAY_SIZE(neighbors_mandatory))) { + fputs("Missing attributes from kernel\n", stderr); + exit(1); + } + + neigh = nla_data(attrs[BATADV_ATTR_NEIGH_ADDRESS]); + bat_host = bat_hosts_find_by_mac((char *)neigh); + + if (!if_indextoname(nla_get_u32(attrs[BATADV_ATTR_HARD_IFINDEX]), + ifname)) + ifname[0] = '\0'; + + last_seen_msecs = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]); + last_seen_secs = last_seen_msecs / 1000; + last_seen_msecs = last_seen_msecs % 1000; + + if (attrs[BATADV_ATTR_THROUGHPUT]) { + throughput_kbits = nla_get_u32(attrs[BATADV_ATTR_THROUGHPUT]); + throughput_mbits = throughput_kbits / 1000; + throughput_kbits = throughput_kbits % 1000; + + if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) + printf("%02x:%02x:%02x:%02x:%02x:%02x ", + neigh[0], neigh[1], neigh[2], + neigh[3], neigh[4], neigh[5]); + else + printf("%17s ", bat_host->name); + + printf("%4i.%03is (%9u.%1u) [%10s]\n", + last_seen_secs, last_seen_msecs, + throughput_mbits, throughput_kbits / 100, + ifname); + } else { + printf(" %10s ", ifname); + + if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) + printf("%02x:%02x:%02x:%02x:%02x:%02x ", + neigh[0], neigh[1], neigh[2], + neigh[3], neigh[4], neigh[5]); + else + printf("%17s ", bat_host->name); + + printf("%4i.%03is\n", last_seen_secs, last_seen_msecs); + } + + return NL_OK; +} + +static int netlink_print_neighbors(char *mesh_iface, char *orig_iface, + int read_opts, float orig_timeout, + float watch_interval) +{ + return netlink_print_common(mesh_iface, orig_iface, read_opts, + orig_timeout, watch_interval, + "IF Neighbor last-seen\n", + BATADV_CMD_GET_NEIGHBORS, + neighbors_callback); +} + +static struct debug_table_data batctl_debug_table_neighbors = { + .debugfs_name = "neighbors", + .header_lines = 2, + .netlink_fn = netlink_print_neighbors, +}; + +COMMAND_NAMED(DEBUGTABLE, neighbors, "n", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_neighbors, ""); diff --git a/netlink.c b/netlink.c index 4f2199e..7735cb6 100644 --- a/netlink.c +++ b/netlink.c @@ -595,89 +595,6 @@ static int originators_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static const int neighbors_mandatory[] = { - BATADV_ATTR_NEIGH_ADDRESS, - BATADV_ATTR_HARD_IFINDEX, - BATADV_ATTR_LAST_SEEN_MSECS, -}; - -static int neighbors_callback(struct nl_msg *msg, void *arg) -{ - unsigned throughput_mbits, throughput_kbits; - struct nlattr *attrs[BATADV_ATTR_MAX+1]; - struct nlmsghdr *nlh = nlmsg_hdr(msg); - int last_seen_msecs, last_seen_secs; - struct print_opts *opts = arg; - struct bat_host *bat_host; - char ifname[IF_NAMESIZE]; - struct genlmsghdr *ghdr; - uint8_t *neigh; - - if (!genlmsg_valid_hdr(nlh, 0)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - ghdr = nlmsg_data(nlh); - - if (ghdr->cmd != BATADV_CMD_GET_NEIGHBORS) - return NL_OK; - - if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), - genlmsg_len(ghdr), batadv_netlink_policy)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - if (missing_mandatory_attrs(attrs, neighbors_mandatory, - ARRAY_SIZE(neighbors_mandatory))) { - fputs("Missing attributes from kernel\n", stderr); - exit(1); - } - - neigh = nla_data(attrs[BATADV_ATTR_NEIGH_ADDRESS]); - bat_host = bat_hosts_find_by_mac((char *)neigh); - - if (!if_indextoname(nla_get_u32(attrs[BATADV_ATTR_HARD_IFINDEX]), - ifname)) - ifname[0] = '\0'; - - last_seen_msecs = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]); - last_seen_secs = last_seen_msecs / 1000; - last_seen_msecs = last_seen_msecs % 1000; - - if (attrs[BATADV_ATTR_THROUGHPUT]) { - throughput_kbits = nla_get_u32(attrs[BATADV_ATTR_THROUGHPUT]); - throughput_mbits = throughput_kbits / 1000; - throughput_kbits = throughput_kbits % 1000; - - if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) - printf("%02x:%02x:%02x:%02x:%02x:%02x ", - neigh[0], neigh[1], neigh[2], - neigh[3], neigh[4], neigh[5]); - else - printf("%17s ", bat_host->name); - - printf("%4i.%03is (%9u.%1u) [%10s]\n", - last_seen_secs, last_seen_msecs, - throughput_mbits, throughput_kbits / 100, - ifname); - } else { - printf(" %10s ", ifname); - - if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) - printf("%02x:%02x:%02x:%02x:%02x:%02x ", - neigh[0], neigh[1], neigh[2], - neigh[3], neigh[4], neigh[5]); - else - printf("%17s ", bat_host->name); - - printf("%4i.%03is\n", last_seen_secs, last_seen_msecs); - } - - return NL_OK; -} - static const int transglobal_mandatory[] = { BATADV_ATTR_TT_ADDRESS, BATADV_ATTR_ORIG_ADDRESS, @@ -1018,17 +935,6 @@ int netlink_print_originators(char *mesh_iface, char *orig_iface, originators_callback); }
-int netlink_print_neighbors(char *mesh_iface, char *orig_iface, int read_opts, - float orig_timeout, - float watch_interval) -{ - return netlink_print_common(mesh_iface, orig_iface, read_opts, - orig_timeout, watch_interval, - "IF Neighbor last-seen\n", - BATADV_CMD_GET_NEIGHBORS, - neighbors_callback); -} - int netlink_print_transglobal(char *mesh_iface, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) diff --git a/netlink.h b/netlink.h index e0fa466..bfac3a5 100644 --- a/netlink.h +++ b/netlink.h @@ -42,8 +42,6 @@ struct ether_addr; int netlink_print_routing_algos(void); int netlink_print_originators(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); -int netlink_print_neighbors(char *mesh_iface, char *orig_iface, int read_opt, - float orig_timeout, float watch_interval); int netlink_print_transglobal(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); int netlink_print_translocal(char *mesh_iface, char *orig_iface, int read_opt,
The netlink.c file contains to many different functions and mixes helper functions with actual command implementations. The debug table commands should be placed in separate files to better group the command specific code sections together.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + debug.c | 11 --- netlink.c | 175 -------------------------------------------- netlink.h | 2 - originators.c | 227 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 228 insertions(+), 188 deletions(-) create mode 100644 originators.c
diff --git a/Makefile b/Makefile index d447663..059c602 100755 --- a/Makefile +++ b/Makefile @@ -53,6 +53,7 @@ OBJ += nc_nodes.o OBJ += neighbors.o OBJ += netlink.o OBJ += ping.o +OBJ += originators.o OBJ += routing_algo.o OBJ += statistics.o OBJ += sys.o diff --git a/debug.c b/debug.c index a5e7276..f4cc2ea 100644 --- a/debug.c +++ b/debug.c @@ -200,17 +200,6 @@ int debug_print_routing_algos(void) return read_file(full_path, DEBUG_ROUTING_ALGOS, 0, 0, 0, 0); }
-static struct debug_table_data batctl_debug_table_originators = { - .debugfs_name = "originators", - .header_lines = 2, - .netlink_fn = netlink_print_originators, - .option_watch_interval = 1, - .option_orig_iface = 1, -}; - -COMMAND_NAMED(DEBUGTABLE, originators, "o", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_originators, ""); - static struct debug_table_data batctl_debug_table_translocal = { .debugfs_name = "transtable_local", .header_lines = 2, diff --git a/netlink.c b/netlink.c index 7735cb6..cbb73ac 100644 --- a/netlink.c +++ b/netlink.c @@ -456,145 +456,6 @@ int netlink_print_routing_algos(void) return last_err; }
-static const int originators_mandatory[] = { - BATADV_ATTR_ORIG_ADDRESS, - BATADV_ATTR_NEIGH_ADDRESS, - BATADV_ATTR_HARD_IFINDEX, - BATADV_ATTR_LAST_SEEN_MSECS, -}; - -static int originators_callback(struct nl_msg *msg, void *arg) -{ - unsigned throughput_mbits, throughput_kbits; - struct nlattr *attrs[BATADV_ATTR_MAX+1]; - struct nlmsghdr *nlh = nlmsg_hdr(msg); - int last_seen_msecs, last_seen_secs; - struct print_opts *opts = arg; - struct bat_host *bat_host; - struct genlmsghdr *ghdr; - char ifname[IF_NAMESIZE]; - float last_seen; - uint8_t *neigh; - uint8_t *orig; - char c = ' '; - uint8_t tq; - - if (!genlmsg_valid_hdr(nlh, 0)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - ghdr = nlmsg_data(nlh); - - if (ghdr->cmd != BATADV_CMD_GET_ORIGINATORS) - return NL_OK; - - if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), - genlmsg_len(ghdr), batadv_netlink_policy)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - if (missing_mandatory_attrs(attrs, originators_mandatory, - ARRAY_SIZE(originators_mandatory))) { - fputs("Missing attributes from kernel\n", stderr); - exit(1); - } - - orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]); - neigh = nla_data(attrs[BATADV_ATTR_NEIGH_ADDRESS]); - - if (!if_indextoname(nla_get_u32(attrs[BATADV_ATTR_HARD_IFINDEX]), - ifname)) - ifname[0] = '\0'; - - if (attrs[BATADV_ATTR_FLAG_BEST]) - c = '*'; - - last_seen_msecs = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]); - last_seen = (float)last_seen_msecs / 1000.0; - last_seen_secs = last_seen_msecs / 1000; - last_seen_msecs = last_seen_msecs % 1000; - - /* skip timed out originators */ - if (opts->read_opt & NO_OLD_ORIGS) - if (last_seen > opts->orig_timeout) - return NL_OK; - - if (attrs[BATADV_ATTR_THROUGHPUT]) { - throughput_kbits = nla_get_u32(attrs[BATADV_ATTR_THROUGHPUT]); - throughput_mbits = throughput_kbits / 1000; - throughput_kbits = throughput_kbits % 1000; - - if (!(opts->read_opt & USE_BAT_HOSTS)) { - printf(" %c %02x:%02x:%02x:%02x:%02x:%02x %4i.%03is (%9u.%1u) %02x:%02x:%02x:%02x:%02x:%02x [%10s]\n", - c, - orig[0], orig[1], orig[2], - orig[3], orig[4], orig[5], - last_seen_secs, last_seen_msecs, - throughput_mbits, throughput_kbits / 100, - neigh[0], neigh[1], neigh[2], - neigh[3], neigh[4], neigh[5], - ifname); - } else { - bat_host = bat_hosts_find_by_mac((char *)orig); - if (bat_host) - printf(" %c %17s ", c, bat_host->name); - else - printf(" %c %02x:%02x:%02x:%02x:%02x:%02x ", - c, - orig[0], orig[1], orig[2], - orig[3], orig[4], orig[5]); - printf("%4i.%03is (%9u.%1u) ", - last_seen_secs, last_seen_msecs, - throughput_mbits, throughput_kbits / 100); - bat_host = bat_hosts_find_by_mac((char *)neigh); - if (bat_host) - printf(" %c %17s ", c, bat_host->name); - else - printf(" %02x:%02x:%02x:%02x:%02x:%02x ", - neigh[0], neigh[1], neigh[2], - neigh[3], neigh[4], neigh[5]); - printf("[%10s]\n", ifname); - } - } - if (attrs[BATADV_ATTR_TQ]) { - tq = nla_get_u8(attrs[BATADV_ATTR_TQ]); - - if (!(opts->read_opt & USE_BAT_HOSTS)) { - printf(" %c %02x:%02x:%02x:%02x:%02x:%02x %4i.%03is (%3i) %02x:%02x:%02x:%02x:%02x:%02x [%10s]\n", - c, - orig[0], orig[1], orig[2], - orig[3], orig[4], orig[5], - last_seen_secs, last_seen_msecs, tq, - neigh[0], neigh[1], neigh[2], - neigh[3], neigh[4], neigh[5], - ifname); - } else { - bat_host = bat_hosts_find_by_mac((char *)orig); - if (bat_host) - printf(" %c %17s ", c, bat_host->name); - else - printf(" %c %02x:%02x:%02x:%02x:%02x:%02x ", - c, - orig[0], orig[1], orig[2], - orig[3], orig[4], orig[5]); - printf("%4i.%03is (%3i) ", - last_seen_secs, last_seen_msecs, tq); - bat_host = bat_hosts_find_by_mac((char *)neigh); - if (bat_host) - printf("%17s ", bat_host->name); - else - printf("%02x:%02x:%02x:%02x:%02x:%02x ", - neigh[0], neigh[1], neigh[2], - neigh[3], neigh[4], neigh[5]); - printf("[%10s]\n", ifname); - } - } - - return NL_OK; -} - static const int transglobal_mandatory[] = { BATADV_ATTR_TT_ADDRESS, BATADV_ATTR_ORIG_ADDRESS, @@ -899,42 +760,6 @@ int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt, return last_err; }
-int netlink_print_originators(char *mesh_iface, char *orig_iface, - int read_opts, float orig_timeout, - float watch_interval) -{ - char *header = NULL; - char *info_header; - int ifindex; - - ifindex = if_nametoindex(mesh_iface); - if (!ifindex) { - fprintf(stderr, "Interface %s is unknown\n", mesh_iface); - return -ENODEV; - } - - /* only parse routing algorithm name */ - last_err = -EINVAL; - info_header = netlink_get_info(ifindex, BATADV_CMD_GET_ORIGINATORS, NULL); - free(info_header); - - if (strlen(algo_name_buf) == 0) - return last_err; - - if (!strcmp("BATMAN_IV", algo_name_buf)) - header = " Originator last-seen (#/255) Nexthop [outgoingIF]\n"; - if (!strcmp("BATMAN_V", algo_name_buf)) - header = " Originator last-seen ( throughput) Nexthop [outgoingIF]\n"; - - if (!header) - return -EINVAL; - - return netlink_print_common(mesh_iface, orig_iface, read_opts, - orig_timeout, watch_interval, header, - BATADV_CMD_GET_ORIGINATORS, - originators_callback); -} - int netlink_print_transglobal(char *mesh_iface, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) diff --git a/netlink.h b/netlink.h index bfac3a5..a099482 100644 --- a/netlink.h +++ b/netlink.h @@ -40,8 +40,6 @@ struct print_opts { struct ether_addr;
int netlink_print_routing_algos(void); -int netlink_print_originators(char *mesh_iface, char *orig_iface, int read_opt, - float orig_timeout, float watch_interval); int netlink_print_transglobal(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval); int netlink_print_translocal(char *mesh_iface, char *orig_iface, int read_opt, diff --git a/originators.c b/originators.c new file mode 100644 index 0000000..54526e3 --- /dev/null +++ b/originators.c @@ -0,0 +1,227 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Andrew Lunn andrew@lunn.ch + * Sven Eckelmann sven@narfation.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <errno.h> +#include <net/if.h> +#include <netinet/if_ether.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> + +#include "batadv_packet.h" +#include "batman_adv.h" +#include "bat-hosts.h" +#include "debug.h" +#include "functions.h" +#include "main.h" +#include "netlink.h" + +static const int originators_mandatory[] = { + BATADV_ATTR_ORIG_ADDRESS, + BATADV_ATTR_NEIGH_ADDRESS, + BATADV_ATTR_HARD_IFINDEX, + BATADV_ATTR_LAST_SEEN_MSECS, +}; + +static int originators_callback(struct nl_msg *msg, void *arg) +{ + unsigned throughput_mbits, throughput_kbits; + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + int last_seen_msecs, last_seen_secs; + struct print_opts *opts = arg; + struct bat_host *bat_host; + struct genlmsghdr *ghdr; + char ifname[IF_NAMESIZE]; + float last_seen; + uint8_t *neigh; + uint8_t *orig; + char c = ' '; + uint8_t tq; + + if (!genlmsg_valid_hdr(nlh, 0)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_ORIGINATORS) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + if (missing_mandatory_attrs(attrs, originators_mandatory, + ARRAY_SIZE(originators_mandatory))) { + fputs("Missing attributes from kernel\n", stderr); + exit(1); + } + + orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]); + neigh = nla_data(attrs[BATADV_ATTR_NEIGH_ADDRESS]); + + if (!if_indextoname(nla_get_u32(attrs[BATADV_ATTR_HARD_IFINDEX]), + ifname)) + ifname[0] = '\0'; + + if (attrs[BATADV_ATTR_FLAG_BEST]) + c = '*'; + + last_seen_msecs = nla_get_u32(attrs[BATADV_ATTR_LAST_SEEN_MSECS]); + last_seen = (float)last_seen_msecs / 1000.0; + last_seen_secs = last_seen_msecs / 1000; + last_seen_msecs = last_seen_msecs % 1000; + + /* skip timed out originators */ + if (opts->read_opt & NO_OLD_ORIGS) + if (last_seen > opts->orig_timeout) + return NL_OK; + + if (attrs[BATADV_ATTR_THROUGHPUT]) { + throughput_kbits = nla_get_u32(attrs[BATADV_ATTR_THROUGHPUT]); + throughput_mbits = throughput_kbits / 1000; + throughput_kbits = throughput_kbits % 1000; + + if (!(opts->read_opt & USE_BAT_HOSTS)) { + printf(" %c %02x:%02x:%02x:%02x:%02x:%02x %4i.%03is (%9u.%1u) %02x:%02x:%02x:%02x:%02x:%02x [%10s]\n", + c, + orig[0], orig[1], orig[2], + orig[3], orig[4], orig[5], + last_seen_secs, last_seen_msecs, + throughput_mbits, throughput_kbits / 100, + neigh[0], neigh[1], neigh[2], + neigh[3], neigh[4], neigh[5], + ifname); + } else { + bat_host = bat_hosts_find_by_mac((char *)orig); + if (bat_host) + printf(" %c %17s ", c, bat_host->name); + else + printf(" %c %02x:%02x:%02x:%02x:%02x:%02x ", + c, + orig[0], orig[1], orig[2], + orig[3], orig[4], orig[5]); + printf("%4i.%03is (%9u.%1u) ", + last_seen_secs, last_seen_msecs, + throughput_mbits, throughput_kbits / 100); + bat_host = bat_hosts_find_by_mac((char *)neigh); + if (bat_host) + printf(" %c %17s ", c, bat_host->name); + else + printf(" %02x:%02x:%02x:%02x:%02x:%02x ", + neigh[0], neigh[1], neigh[2], + neigh[3], neigh[4], neigh[5]); + printf("[%10s]\n", ifname); + } + } + if (attrs[BATADV_ATTR_TQ]) { + tq = nla_get_u8(attrs[BATADV_ATTR_TQ]); + + if (!(opts->read_opt & USE_BAT_HOSTS)) { + printf(" %c %02x:%02x:%02x:%02x:%02x:%02x %4i.%03is (%3i) %02x:%02x:%02x:%02x:%02x:%02x [%10s]\n", + c, + orig[0], orig[1], orig[2], + orig[3], orig[4], orig[5], + last_seen_secs, last_seen_msecs, tq, + neigh[0], neigh[1], neigh[2], + neigh[3], neigh[4], neigh[5], + ifname); + } else { + bat_host = bat_hosts_find_by_mac((char *)orig); + if (bat_host) + printf(" %c %17s ", c, bat_host->name); + else + printf(" %c %02x:%02x:%02x:%02x:%02x:%02x ", + c, + orig[0], orig[1], orig[2], + orig[3], orig[4], orig[5]); + printf("%4i.%03is (%3i) ", + last_seen_secs, last_seen_msecs, tq); + bat_host = bat_hosts_find_by_mac((char *)neigh); + if (bat_host) + printf("%17s ", bat_host->name); + else + printf("%02x:%02x:%02x:%02x:%02x:%02x ", + neigh[0], neigh[1], neigh[2], + neigh[3], neigh[4], neigh[5]); + printf("[%10s]\n", ifname); + } + } + + return NL_OK; +} + +static int netlink_print_originators(char *mesh_iface, char *orig_iface, + int read_opts, float orig_timeout, + float watch_interval) +{ + char *header = NULL; + char *info_header; + int ifindex; + + ifindex = if_nametoindex(mesh_iface); + if (!ifindex) { + fprintf(stderr, "Interface %s is unknown\n", mesh_iface); + return -ENODEV; + } + + /* only parse routing algorithm name */ + last_err = -EINVAL; + info_header = netlink_get_info(ifindex, BATADV_CMD_GET_ORIGINATORS, NULL); + free(info_header); + + if (strlen(algo_name_buf) == 0) + return last_err; + + if (!strcmp("BATMAN_IV", algo_name_buf)) + header = " Originator last-seen (#/255) Nexthop [outgoingIF]\n"; + if (!strcmp("BATMAN_V", algo_name_buf)) + header = " Originator last-seen ( throughput) Nexthop [outgoingIF]\n"; + + if (!header) + return -EINVAL; + + return netlink_print_common(mesh_iface, orig_iface, read_opts, + orig_timeout, watch_interval, header, + BATADV_CMD_GET_ORIGINATORS, + originators_callback); +} + +static struct debug_table_data batctl_debug_table_originators = { + .debugfs_name = "originators", + .header_lines = 2, + .netlink_fn = netlink_print_originators, + .option_watch_interval = 1, + .option_orig_iface = 1, +}; + +COMMAND_NAMED(DEBUGTABLE, originators, "o", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_originators, "");
The netlink.c file contains to many different functions and mixes helper functions with actual command implementations. The debug table commands should be placed in separate files to better group the command specific code sections together.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + debug.c | 11 ---- netlink.c | 112 ---------------------------------------- netlink.h | 2 - transglobal.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 162 insertions(+), 125 deletions(-) create mode 100644 transglobal.c
diff --git a/Makefile b/Makefile index 059c602..ef0c28b 100755 --- a/Makefile +++ b/Makefile @@ -60,6 +60,7 @@ OBJ += sys.o OBJ += tcpdump.o OBJ += throughputmeter.o OBJ += traceroute.o +OBJ += transglobal.o OBJ += translate.o
MANPAGE = man/batctl.8 diff --git a/debug.c b/debug.c index f4cc2ea..5f2ad04 100644 --- a/debug.c +++ b/debug.c @@ -210,14 +210,3 @@ static struct debug_table_data batctl_debug_table_translocal = {
COMMAND_NAMED(DEBUGTABLE, translocal, "tl", handle_debug_table, COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_translocal, ""); - -static struct debug_table_data batctl_debug_table_transglobal = { - .debugfs_name = "transtable_global", - .header_lines = 2, - .netlink_fn = netlink_print_transglobal, - .option_unicast_only = 1, - .option_multicast_only = 1, -}; - -COMMAND_NAMED(DEBUGTABLE, transglobal, "tg", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_transglobal, ""); diff --git a/netlink.c b/netlink.c index cbb73ac..6583696 100644 --- a/netlink.c +++ b/netlink.c @@ -456,107 +456,6 @@ int netlink_print_routing_algos(void) return last_err; }
-static const int transglobal_mandatory[] = { - BATADV_ATTR_TT_ADDRESS, - BATADV_ATTR_ORIG_ADDRESS, - BATADV_ATTR_TT_VID, - BATADV_ATTR_TT_TTVN, - BATADV_ATTR_TT_LAST_TTVN, - BATADV_ATTR_TT_CRC32, - BATADV_ATTR_TT_FLAGS, -}; - -static int transglobal_callback(struct nl_msg *msg, void *arg) -{ - struct nlattr *attrs[BATADV_ATTR_MAX+1]; - struct nlmsghdr *nlh = nlmsg_hdr(msg); - struct print_opts *opts = arg; - struct bat_host *bat_host; - struct genlmsghdr *ghdr; - char c, r, w, i, t; - uint8_t last_ttvn; - uint32_t crc32; - uint32_t flags; - uint8_t *addr; - uint8_t *orig; - uint8_t ttvn; - int16_t vid; - - if (!genlmsg_valid_hdr(nlh, 0)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - ghdr = nlmsg_data(nlh); - - if (ghdr->cmd != BATADV_CMD_GET_TRANSTABLE_GLOBAL) - return NL_OK; - - if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), - genlmsg_len(ghdr), batadv_netlink_policy)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - if (missing_mandatory_attrs(attrs, transglobal_mandatory, - ARRAY_SIZE(transglobal_mandatory))) { - fputs("Missing attributes from kernel\n", stderr); - exit(1); - } - - addr = nla_data(attrs[BATADV_ATTR_TT_ADDRESS]); - orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]); - vid = nla_get_u16(attrs[BATADV_ATTR_TT_VID]); - ttvn = nla_get_u8(attrs[BATADV_ATTR_TT_TTVN]); - last_ttvn = nla_get_u8(attrs[BATADV_ATTR_TT_LAST_TTVN]); - crc32 = nla_get_u32(attrs[BATADV_ATTR_TT_CRC32]); - flags = nla_get_u32(attrs[BATADV_ATTR_TT_FLAGS]); - - if (opts->read_opt & MULTICAST_ONLY && !(addr[0] & 0x01)) - return NL_OK; - - if (opts->read_opt & UNICAST_ONLY && (addr[0] & 0x01)) - return NL_OK; - - c = ' ', r = '.', w = '.', i = '.', t = '.'; - if (attrs[BATADV_ATTR_FLAG_BEST]) - c = '*'; - if (flags & BATADV_TT_CLIENT_ROAM) - r = 'R'; - if (flags & BATADV_TT_CLIENT_WIFI) - w = 'W'; - if (flags & BATADV_TT_CLIENT_ISOLA) - i = 'I'; - if (flags & BATADV_TT_CLIENT_TEMP) - t = 'T'; - - printf(" %c ", c); - - bat_host = bat_hosts_find_by_mac((char *)addr); - if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) - printf("%02x:%02x:%02x:%02x:%02x:%02x ", - addr[0], addr[1], addr[2], - addr[3], addr[4], addr[5]); - else - printf("%17s ", bat_host->name); - - printf("%4i [%c%c%c%c] (%3u) ", - BATADV_PRINT_VID(vid), r, w, i, t, ttvn); - - bat_host = bat_hosts_find_by_mac((char *)orig); - if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) - printf("%02x:%02x:%02x:%02x:%02x:%02x ", - orig[0], orig[1], orig[2], - orig[3], orig[4], orig[5]); - else - printf("%17s ", bat_host->name); - - printf("(%3u) (0x%.8x)\n", - last_ttvn, crc32); - - return NL_OK; -} - static const int translocal_mandatory[] = { BATADV_ATTR_TT_ADDRESS, BATADV_ATTR_TT_VID, @@ -760,17 +659,6 @@ int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt, return last_err; }
-int netlink_print_transglobal(char *mesh_iface, char *orig_iface, - int read_opts, float orig_timeout, - float watch_interval) -{ - return netlink_print_common(mesh_iface, orig_iface, read_opts, - orig_timeout, watch_interval, - " Client VID Flags Last ttvn Via ttvn (CRC )\n", - BATADV_CMD_GET_TRANSTABLE_GLOBAL, - transglobal_callback); -} - int netlink_print_translocal(char *mesh_iface, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) diff --git a/netlink.h b/netlink.h index a099482..1cec0f7 100644 --- a/netlink.h +++ b/netlink.h @@ -40,8 +40,6 @@ struct print_opts { struct ether_addr;
int netlink_print_routing_algos(void); -int netlink_print_transglobal(char *mesh_iface, char *orig_iface, int read_opt, - float orig_timeout, float watch_interval); int netlink_print_translocal(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval);
diff --git a/transglobal.c b/transglobal.c new file mode 100644 index 0000000..f61aa9f --- /dev/null +++ b/transglobal.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Andrew Lunn andrew@lunn.ch + * Sven Eckelmann sven@narfation.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <netinet/if_ether.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +#include "batadv_packet.h" +#include "batman_adv.h" +#include "bat-hosts.h" +#include "debug.h" +#include "functions.h" +#include "main.h" +#include "netlink.h" + +static const int transglobal_mandatory[] = { + BATADV_ATTR_TT_ADDRESS, + BATADV_ATTR_ORIG_ADDRESS, + BATADV_ATTR_TT_VID, + BATADV_ATTR_TT_TTVN, + BATADV_ATTR_TT_LAST_TTVN, + BATADV_ATTR_TT_CRC32, + BATADV_ATTR_TT_FLAGS, +}; + +static int transglobal_callback(struct nl_msg *msg, void *arg) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct print_opts *opts = arg; + struct bat_host *bat_host; + struct genlmsghdr *ghdr; + char c, r, w, i, t; + uint8_t last_ttvn; + uint32_t crc32; + uint32_t flags; + uint8_t *addr; + uint8_t *orig; + uint8_t ttvn; + int16_t vid; + + if (!genlmsg_valid_hdr(nlh, 0)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_TRANSTABLE_GLOBAL) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + if (missing_mandatory_attrs(attrs, transglobal_mandatory, + ARRAY_SIZE(transglobal_mandatory))) { + fputs("Missing attributes from kernel\n", stderr); + exit(1); + } + + addr = nla_data(attrs[BATADV_ATTR_TT_ADDRESS]); + orig = nla_data(attrs[BATADV_ATTR_ORIG_ADDRESS]); + vid = nla_get_u16(attrs[BATADV_ATTR_TT_VID]); + ttvn = nla_get_u8(attrs[BATADV_ATTR_TT_TTVN]); + last_ttvn = nla_get_u8(attrs[BATADV_ATTR_TT_LAST_TTVN]); + crc32 = nla_get_u32(attrs[BATADV_ATTR_TT_CRC32]); + flags = nla_get_u32(attrs[BATADV_ATTR_TT_FLAGS]); + + if (opts->read_opt & MULTICAST_ONLY && !(addr[0] & 0x01)) + return NL_OK; + + if (opts->read_opt & UNICAST_ONLY && (addr[0] & 0x01)) + return NL_OK; + + c = ' ', r = '.', w = '.', i = '.', t = '.'; + if (attrs[BATADV_ATTR_FLAG_BEST]) + c = '*'; + if (flags & BATADV_TT_CLIENT_ROAM) + r = 'R'; + if (flags & BATADV_TT_CLIENT_WIFI) + w = 'W'; + if (flags & BATADV_TT_CLIENT_ISOLA) + i = 'I'; + if (flags & BATADV_TT_CLIENT_TEMP) + t = 'T'; + + printf(" %c ", c); + + bat_host = bat_hosts_find_by_mac((char *)addr); + if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) + printf("%02x:%02x:%02x:%02x:%02x:%02x ", + addr[0], addr[1], addr[2], + addr[3], addr[4], addr[5]); + else + printf("%17s ", bat_host->name); + + printf("%4i [%c%c%c%c] (%3u) ", + BATADV_PRINT_VID(vid), r, w, i, t, ttvn); + + bat_host = bat_hosts_find_by_mac((char *)orig); + if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) + printf("%02x:%02x:%02x:%02x:%02x:%02x ", + orig[0], orig[1], orig[2], + orig[3], orig[4], orig[5]); + else + printf("%17s ", bat_host->name); + + printf("(%3u) (0x%.8x)\n", + last_ttvn, crc32); + + return NL_OK; +} + +static int netlink_print_transglobal(char *mesh_iface, char *orig_iface, + int read_opts, float orig_timeout, + float watch_interval) +{ + return netlink_print_common(mesh_iface, orig_iface, read_opts, + orig_timeout, watch_interval, + " Client VID Flags Last ttvn Via ttvn (CRC )\n", + BATADV_CMD_GET_TRANSTABLE_GLOBAL, + transglobal_callback); +} + +static struct debug_table_data batctl_debug_table_transglobal = { + .debugfs_name = "transtable_global", + .header_lines = 2, + .netlink_fn = netlink_print_transglobal, + .option_unicast_only = 1, + .option_multicast_only = 1, +}; + +COMMAND_NAMED(DEBUGTABLE, transglobal, "tg", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_transglobal, "");
The netlink.c file contains to many different functions and mixes helper functions with actual command implementations. The debug table commands should be placed in separate files to better group the command specific code sections together.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + debug.c | 11 ----- netlink.c | 108 ---------------------------------------- netlink.h | 2 - translocal.c | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 158 insertions(+), 121 deletions(-) create mode 100644 translocal.c
diff --git a/Makefile b/Makefile index ef0c28b..93db44a 100755 --- a/Makefile +++ b/Makefile @@ -62,6 +62,7 @@ OBJ += throughputmeter.o OBJ += traceroute.o OBJ += transglobal.o OBJ += translate.o +OBJ += translocal.o
MANPAGE = man/batctl.8
diff --git a/debug.c b/debug.c index 5f2ad04..17dde92 100644 --- a/debug.c +++ b/debug.c @@ -199,14 +199,3 @@ int debug_print_routing_algos(void) debugfs_make_path(DEBUG_BATIF_PATH_FMT, "", full_path, sizeof(full_path)); return read_file(full_path, DEBUG_ROUTING_ALGOS, 0, 0, 0, 0); } - -static struct debug_table_data batctl_debug_table_translocal = { - .debugfs_name = "transtable_local", - .header_lines = 2, - .netlink_fn = netlink_print_translocal, - .option_unicast_only = 1, - .option_multicast_only = 1, -}; - -COMMAND_NAMED(DEBUGTABLE, translocal, "tl", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_translocal, ""); diff --git a/netlink.c b/netlink.c index 6583696..26ae27d 100644 --- a/netlink.c +++ b/netlink.c @@ -456,103 +456,6 @@ int netlink_print_routing_algos(void) return last_err; }
-static const int translocal_mandatory[] = { - BATADV_ATTR_TT_ADDRESS, - BATADV_ATTR_TT_VID, - BATADV_ATTR_TT_CRC32, - BATADV_ATTR_TT_FLAGS, -}; - -static int translocal_callback(struct nl_msg *msg, void *arg) -{ - int last_seen_msecs = 0, last_seen_secs = 0; - struct nlattr *attrs[BATADV_ATTR_MAX+1]; - struct nlmsghdr *nlh = nlmsg_hdr(msg); - struct print_opts *opts = arg; - struct bat_host *bat_host; - struct genlmsghdr *ghdr; - char r, p, n, x, w, i; - uint8_t *addr; - int16_t vid; - uint32_t crc32; - uint32_t flags; - - if (!genlmsg_valid_hdr(nlh, 0)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - ghdr = nlmsg_data(nlh); - - if (ghdr->cmd != BATADV_CMD_GET_TRANSTABLE_LOCAL) - return NL_OK; - - if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), - genlmsg_len(ghdr), batadv_netlink_policy)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - if (missing_mandatory_attrs(attrs, translocal_mandatory, - ARRAY_SIZE(translocal_mandatory))) { - fputs("Missing attributes from kernel\n", stderr); - exit(1); - } - - addr = nla_data(attrs[BATADV_ATTR_TT_ADDRESS]); - vid = nla_get_u16(attrs[BATADV_ATTR_TT_VID]); - crc32 = nla_get_u32(attrs[BATADV_ATTR_TT_CRC32]); - flags = nla_get_u32(attrs[BATADV_ATTR_TT_FLAGS]); - last_seen_msecs = 0, last_seen_secs = 0; - - if (opts->read_opt & MULTICAST_ONLY && !(addr[0] & 0x01)) - return NL_OK; - - if (opts->read_opt & UNICAST_ONLY && (addr[0] & 0x01)) - return NL_OK; - - r = '.', p = '.', n = '.', x = '.', w = '.', i = '.'; - if (flags & BATADV_TT_CLIENT_ROAM) - r = 'R'; - if (flags & BATADV_TT_CLIENT_NEW) - n = 'N'; - if (flags & BATADV_TT_CLIENT_PENDING) - x = 'X'; - if (flags & BATADV_TT_CLIENT_WIFI) - w = 'W'; - if (flags & BATADV_TT_CLIENT_ISOLA) - i = 'I'; - - if (flags & BATADV_TT_CLIENT_NOPURGE) { - p = 'P'; - } else { - if (!attrs[BATADV_ATTR_LAST_SEEN_MSECS]) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - last_seen_msecs = nla_get_u32( - attrs[BATADV_ATTR_LAST_SEEN_MSECS]); - last_seen_secs = last_seen_msecs / 1000; - last_seen_msecs = last_seen_msecs % 1000; - } - - bat_host = bat_hosts_find_by_mac((char *)addr); - if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) - printf("%02x:%02x:%02x:%02x:%02x:%02x ", - addr[0], addr[1], addr[2], - addr[3], addr[4], addr[5]); - else - printf("%17s ", bat_host->name); - - printf("%4i [%c%c%c%c%c%c] %3u.%03u (0x%.8x)\n", - BATADV_PRINT_VID(vid), r, p, n, x, w, i, - last_seen_secs, last_seen_msecs, - crc32); - - return NL_OK; -} - int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt, float orig_timeout, float watch_interval, const char *header, uint8_t nl_cmd, @@ -659,17 +562,6 @@ int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt, return last_err; }
-int netlink_print_translocal(char *mesh_iface, char *orig_iface, int read_opts, - float orig_timeout, - float watch_interval) -{ - return netlink_print_common(mesh_iface, orig_iface, read_opts, - orig_timeout, watch_interval, - "Client VID Flags Last seen (CRC )\n", - BATADV_CMD_GET_TRANSTABLE_LOCAL, - translocal_callback); -} - static int nlquery_error_cb(struct sockaddr_nl *nla __maybe_unused, struct nlmsgerr *nlerr, void *arg) { diff --git a/netlink.h b/netlink.h index 1cec0f7..0b21ac1 100644 --- a/netlink.h +++ b/netlink.h @@ -40,8 +40,6 @@ struct print_opts { struct ether_addr;
int netlink_print_routing_algos(void); -int netlink_print_translocal(char *mesh_iface, char *orig_iface, int read_opt, - float orig_timeout, float watch_interval);
char *netlink_get_info(int ifindex, uint8_t nl_cmd, const char *header); int translate_mac_netlink(const char *mesh_iface, const struct ether_addr *mac, diff --git a/translocal.c b/translocal.c new file mode 100644 index 0000000..815dc1e --- /dev/null +++ b/translocal.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Andrew Lunn andrew@lunn.ch + * Sven Eckelmann sven@narfation.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <netinet/if_ether.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> + +#include "batadv_packet.h" +#include "batman_adv.h" +#include "bat-hosts.h" +#include "debug.h" +#include "functions.h" +#include "main.h" +#include "netlink.h" + +static const int translocal_mandatory[] = { + BATADV_ATTR_TT_ADDRESS, + BATADV_ATTR_TT_VID, + BATADV_ATTR_TT_CRC32, + BATADV_ATTR_TT_FLAGS, +}; + +static int translocal_callback(struct nl_msg *msg, void *arg) +{ + int last_seen_msecs = 0, last_seen_secs = 0; + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct print_opts *opts = arg; + struct bat_host *bat_host; + struct genlmsghdr *ghdr; + char r, p, n, x, w, i; + uint8_t *addr; + int16_t vid; + uint32_t crc32; + uint32_t flags; + + if (!genlmsg_valid_hdr(nlh, 0)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_TRANSTABLE_LOCAL) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + if (missing_mandatory_attrs(attrs, translocal_mandatory, + ARRAY_SIZE(translocal_mandatory))) { + fputs("Missing attributes from kernel\n", stderr); + exit(1); + } + + addr = nla_data(attrs[BATADV_ATTR_TT_ADDRESS]); + vid = nla_get_u16(attrs[BATADV_ATTR_TT_VID]); + crc32 = nla_get_u32(attrs[BATADV_ATTR_TT_CRC32]); + flags = nla_get_u32(attrs[BATADV_ATTR_TT_FLAGS]); + last_seen_msecs = 0, last_seen_secs = 0; + + if (opts->read_opt & MULTICAST_ONLY && !(addr[0] & 0x01)) + return NL_OK; + + if (opts->read_opt & UNICAST_ONLY && (addr[0] & 0x01)) + return NL_OK; + + r = '.', p = '.', n = '.', x = '.', w = '.', i = '.'; + if (flags & BATADV_TT_CLIENT_ROAM) + r = 'R'; + if (flags & BATADV_TT_CLIENT_NEW) + n = 'N'; + if (flags & BATADV_TT_CLIENT_PENDING) + x = 'X'; + if (flags & BATADV_TT_CLIENT_WIFI) + w = 'W'; + if (flags & BATADV_TT_CLIENT_ISOLA) + i = 'I'; + + if (flags & BATADV_TT_CLIENT_NOPURGE) { + p = 'P'; + } else { + if (!attrs[BATADV_ATTR_LAST_SEEN_MSECS]) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + last_seen_msecs = nla_get_u32( + attrs[BATADV_ATTR_LAST_SEEN_MSECS]); + last_seen_secs = last_seen_msecs / 1000; + last_seen_msecs = last_seen_msecs % 1000; + } + + bat_host = bat_hosts_find_by_mac((char *)addr); + if (!(opts->read_opt & USE_BAT_HOSTS) || !bat_host) + printf("%02x:%02x:%02x:%02x:%02x:%02x ", + addr[0], addr[1], addr[2], + addr[3], addr[4], addr[5]); + else + printf("%17s ", bat_host->name); + + printf("%4i [%c%c%c%c%c%c] %3u.%03u (0x%.8x)\n", + BATADV_PRINT_VID(vid), r, p, n, x, w, i, + last_seen_secs, last_seen_msecs, + crc32); + + return NL_OK; +} + +static int netlink_print_translocal(char *mesh_iface, char *orig_iface, + int read_opts, float orig_timeout, + float watch_interval) +{ + return netlink_print_common(mesh_iface, orig_iface, read_opts, + orig_timeout, watch_interval, + "Client VID Flags Last seen (CRC )\n", + BATADV_CMD_GET_TRANSTABLE_LOCAL, + translocal_callback); +} + +static struct debug_table_data batctl_debug_table_translocal = { + .debugfs_name = "transtable_local", + .header_lines = 2, + .netlink_fn = netlink_print_translocal, + .option_unicast_only = 1, + .option_multicast_only = 1, +}; + +COMMAND_NAMED(DEBUGTABLE, translocal, "tl", handle_debug_table, + COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_translocal, "");
The sysfs settings are planned to get also be implemented in netlink. To avoid cluttering up netlink.c again, it should be stored in a separate file. This also allows to order the usage lines using the Makefile.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + aggregation.c | 33 +++++++++++++++++++++++++++++++++ sys.c | 9 --------- 3 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 aggregation.c
diff --git a/Makefile b/Makefile index 93db44a..dfc59af 100755 --- a/Makefile +++ b/Makefile @@ -29,6 +29,7 @@ BINARY_NAME = batctl
OBJ_BISECT = bisect_iv.o
+OBJ += aggregation.o OBJ += bat-hosts.o OBJ += backbonetable.o ifeq ($(CONFIG_BATCTL_BISECT),y) diff --git a/aggregation.c b/aggregation.c new file mode 100644 index 0000000..57c1dbb --- /dev/null +++ b/aggregation.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include "main.h" +#include "sys.h" + +static struct settings_data batctl_settings_aggregation = { + .sysfs_name = "aggregated_ogms", + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, aggregation, "ag", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_aggregation, + "[0|1] \tdisplay or modify aggregation setting"); diff --git a/sys.c b/sys.c index 08b389e..00e452c 100644 --- a/sys.c +++ b/sys.c @@ -173,15 +173,6 @@ COMMAND_NAMED(SUBCOMMAND, distributed_arp_table, "dat", handle_sys_setting, COMMAND_FLAG_MESH_IFACE, &batctl_settings_distributed_arp_table, "[0|1] \tdisplay or modify distributed_arp_table setting");
-static struct settings_data batctl_settings_aggregation = { - .sysfs_name = "aggregated_ogms", - .params = sysfs_param_enable, -}; - -COMMAND_NAMED(SUBCOMMAND, aggregation, "ag", handle_sys_setting, - COMMAND_FLAG_MESH_IFACE, &batctl_settings_aggregation, - "[0|1] \tdisplay or modify aggregation setting"); - static struct settings_data batctl_settings_bonding = { .sysfs_name = "bonding", .params = sysfs_param_enable,
The sysfs settings are planned to get also be implemented in netlink. To avoid cluttering up netlink.c again, it should be stored in a separate file. This also allows to order the usage lines using the Makefile.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + ap_isolation.c | 33 +++++++++++++++++++++++++++++++++ sys.c | 9 --------- 3 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 ap_isolation.c
diff --git a/Makefile b/Makefile index dfc59af..0a72595 100755 --- a/Makefile +++ b/Makefile @@ -30,6 +30,7 @@ BINARY_NAME = batctl OBJ_BISECT = bisect_iv.o
OBJ += aggregation.o +OBJ += ap_isolation.o OBJ += bat-hosts.o OBJ += backbonetable.o ifeq ($(CONFIG_BATCTL_BISECT),y) diff --git a/ap_isolation.c b/ap_isolation.c new file mode 100644 index 0000000..2d16c68 --- /dev/null +++ b/ap_isolation.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Antonio Quartulli a@unstable.cc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include "main.h" +#include "sys.h" + +static struct settings_data batctl_settings_ap_isolation = { + .sysfs_name = "ap_isolation", + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, ap_isolation, "ap", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_ap_isolation, + "[0|1] \tdisplay or modify ap_isolation setting"); diff --git a/sys.c b/sys.c index 00e452c..80d9fa1 100644 --- a/sys.c +++ b/sys.c @@ -146,15 +146,6 @@ COMMAND_NAMED(SUBCOMMAND, orig_interval, "it", handle_sys_setting, COMMAND_FLAG_MESH_IFACE, &batctl_settings_orig_interval, "[interval] \tdisplay or modify orig_interval setting");
-static struct settings_data batctl_settings_ap_isolation = { - .sysfs_name = "ap_isolation", - .params = sysfs_param_enable, -}; - -COMMAND_NAMED(SUBCOMMAND, ap_isolation, "ap", handle_sys_setting, - COMMAND_FLAG_MESH_IFACE, &batctl_settings_ap_isolation, - "[0|1] \tdisplay or modify ap_isolation setting"); - static struct settings_data batctl_settings_bridge_loop_avoidance = { .sysfs_name = SYS_BLA, .params = sysfs_param_enable,
The sysfs settings are planned to get also be implemented in netlink. To avoid cluttering up netlink.c again, it should be stored in a separate file. This also allows to order the usage lines using the Makefile.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + bonding.c | 33 +++++++++++++++++++++++++++++++++ sys.c | 9 --------- 3 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 bonding.c
diff --git a/Makefile b/Makefile index 0a72595..c1b8484 100755 --- a/Makefile +++ b/Makefile @@ -36,6 +36,7 @@ OBJ += backbonetable.o ifeq ($(CONFIG_BATCTL_BISECT),y) OBJ += $(OBJ_BISECT) endif +OBJ += bonding.o OBJ += claimtable.o OBJ += dat_cache.o OBJ += debugfs.o diff --git a/bonding.c b/bonding.c new file mode 100644 index 0000000..f7105c9 --- /dev/null +++ b/bonding.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include "main.h" +#include "sys.h" + +static struct settings_data batctl_settings_bonding = { + .sysfs_name = "bonding", + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, bonding, "b", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_bonding, + "[0|1] \tdisplay or modify bonding setting"); diff --git a/sys.c b/sys.c index 80d9fa1..8ad925e 100644 --- a/sys.c +++ b/sys.c @@ -164,15 +164,6 @@ COMMAND_NAMED(SUBCOMMAND, distributed_arp_table, "dat", handle_sys_setting, COMMAND_FLAG_MESH_IFACE, &batctl_settings_distributed_arp_table, "[0|1] \tdisplay or modify distributed_arp_table setting");
-static struct settings_data batctl_settings_bonding = { - .sysfs_name = "bonding", - .params = sysfs_param_enable, -}; - -COMMAND_NAMED(SUBCOMMAND, bonding, "b", handle_sys_setting, - COMMAND_FLAG_MESH_IFACE, &batctl_settings_bonding, - "[0|1] \tdisplay or modify bonding setting"); - static struct settings_data batctl_settings_fragmentation = { .sysfs_name = "fragmentation", .params = sysfs_param_enable,
The sysfs settings are planned to get also be implemented in netlink. To avoid cluttering up netlink.c again, it should be stored in a separate file. This also allows to order the usage lines using the Makefile.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + bridge_loop_avoidance.c | 33 +++++++++++++++++++++++++++++++++ sys.c | 9 --------- 3 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 bridge_loop_avoidance.c
diff --git a/Makefile b/Makefile index c1b8484..6664aa0 100755 --- a/Makefile +++ b/Makefile @@ -37,6 +37,7 @@ ifeq ($(CONFIG_BATCTL_BISECT),y) OBJ += $(OBJ_BISECT) endif OBJ += bonding.o +OBJ += bridge_loop_avoidance.o OBJ += claimtable.o OBJ += dat_cache.o OBJ += debugfs.o diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c new file mode 100644 index 0000000..0db49f2 --- /dev/null +++ b/bridge_loop_avoidance.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Simon Wunderlich sw@simonwunderlich.de + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include "main.h" +#include "sys.h" + +static struct settings_data batctl_settings_bridge_loop_avoidance = { + .sysfs_name = SYS_BLA, + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, bridge_loop_avoidance, "bl", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_bridge_loop_avoidance, + "[0|1] \tdisplay or modify bridge_loop_avoidance setting"); diff --git a/sys.c b/sys.c index 8ad925e..e08738d 100644 --- a/sys.c +++ b/sys.c @@ -146,15 +146,6 @@ COMMAND_NAMED(SUBCOMMAND, orig_interval, "it", handle_sys_setting, COMMAND_FLAG_MESH_IFACE, &batctl_settings_orig_interval, "[interval] \tdisplay or modify orig_interval setting");
-static struct settings_data batctl_settings_bridge_loop_avoidance = { - .sysfs_name = SYS_BLA, - .params = sysfs_param_enable, -}; - -COMMAND_NAMED(SUBCOMMAND, bridge_loop_avoidance, "bl", handle_sys_setting, - COMMAND_FLAG_MESH_IFACE, &batctl_settings_bridge_loop_avoidance, - "[0|1] \tdisplay or modify bridge_loop_avoidance setting"); - static struct settings_data batctl_settings_distributed_arp_table = { .sysfs_name = SYS_DAT, .params = sysfs_param_enable,
The sysfs settings are planned to get also be implemented in netlink. To avoid cluttering up netlink.c again, it should be stored in a separate file. This also allows to order the usage lines using the Makefile.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + distributed_arp_table.c | 33 +++++++++++++++++++++++++++++++++ sys.c | 9 --------- 3 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 distributed_arp_table.c
diff --git a/Makefile b/Makefile index 6664aa0..9cbef82 100755 --- a/Makefile +++ b/Makefile @@ -42,6 +42,7 @@ OBJ += claimtable.o OBJ += dat_cache.o OBJ += debugfs.o OBJ += debug.o +OBJ += distributed_arp_table.o OBJ += functions.o OBJ += gateways.o OBJ += genl.o diff --git a/distributed_arp_table.c b/distributed_arp_table.c new file mode 100644 index 0000000..ba6e5b7 --- /dev/null +++ b/distributed_arp_table.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Antonio Quartulli a@unstable.cc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include "main.h" +#include "sys.h" + +static struct settings_data batctl_settings_distributed_arp_table = { + .sysfs_name = SYS_DAT, + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, distributed_arp_table, "dat", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_distributed_arp_table, + "[0|1] \tdisplay or modify distributed_arp_table setting"); diff --git a/sys.c b/sys.c index e08738d..9ce7a90 100644 --- a/sys.c +++ b/sys.c @@ -146,15 +146,6 @@ COMMAND_NAMED(SUBCOMMAND, orig_interval, "it", handle_sys_setting, COMMAND_FLAG_MESH_IFACE, &batctl_settings_orig_interval, "[interval] \tdisplay or modify orig_interval setting");
-static struct settings_data batctl_settings_distributed_arp_table = { - .sysfs_name = SYS_DAT, - .params = sysfs_param_enable, -}; - -COMMAND_NAMED(SUBCOMMAND, distributed_arp_table, "dat", handle_sys_setting, - COMMAND_FLAG_MESH_IFACE, &batctl_settings_distributed_arp_table, - "[0|1] \tdisplay or modify distributed_arp_table setting"); - static struct settings_data batctl_settings_fragmentation = { .sysfs_name = "fragmentation", .params = sysfs_param_enable,
The sysfs settings are planned to get also be implemented in netlink. To avoid cluttering up netlink.c again, it should be stored in a separate file. This also allows to order the usage lines using the Makefile.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + fragmentation.c | 33 +++++++++++++++++++++++++++++++++ sys.c | 9 --------- 3 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 fragmentation.c
diff --git a/Makefile b/Makefile index 9cbef82..7f82d44 100755 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ OBJ += dat_cache.o OBJ += debugfs.o OBJ += debug.o OBJ += distributed_arp_table.o +OBJ += fragmentation.o OBJ += functions.o OBJ += gateways.o OBJ += genl.o diff --git a/fragmentation.c b/fragmentation.c new file mode 100644 index 0000000..e159bdd --- /dev/null +++ b/fragmentation.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include "main.h" +#include "sys.h" + +static struct settings_data batctl_settings_fragmentation = { + .sysfs_name = "fragmentation", + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, fragmentation, "f", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_fragmentation, + "[0|1] \tdisplay or modify fragmentation setting"); diff --git a/sys.c b/sys.c index 9ce7a90..f81298b 100644 --- a/sys.c +++ b/sys.c @@ -146,15 +146,6 @@ COMMAND_NAMED(SUBCOMMAND, orig_interval, "it", handle_sys_setting, COMMAND_FLAG_MESH_IFACE, &batctl_settings_orig_interval, "[interval] \tdisplay or modify orig_interval setting");
-static struct settings_data batctl_settings_fragmentation = { - .sysfs_name = "fragmentation", - .params = sysfs_param_enable, -}; - -COMMAND_NAMED(SUBCOMMAND, fragmentation, "f", handle_sys_setting, - COMMAND_FLAG_MESH_IFACE, &batctl_settings_fragmentation, - "[0|1] \tdisplay or modify fragmentation setting"); - static struct settings_data batctl_settings_network_coding = { .sysfs_name = SYS_NETWORK_CODING, .params = sysfs_param_enable,
The sysfs settings are planned to get also be implemented in netlink. To avoid cluttering up netlink.c again, it should be stored in a separate file. This also allows to order the usage lines using the Makefile.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + isolation_mark.c | 35 +++++++++++++++++++++++++++++++++++ sys.c | 9 --------- 3 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 isolation_mark.c
diff --git a/Makefile b/Makefile index 7f82d44..9598065 100755 --- a/Makefile +++ b/Makefile @@ -51,6 +51,7 @@ OBJ += gw_mode.o OBJ += hash.o OBJ += icmp_helper.o OBJ += interface.o +OBJ += isolation_mark.o OBJ += loglevel.o OBJ += log.o OBJ += main.o diff --git a/isolation_mark.c b/isolation_mark.c new file mode 100644 index 0000000..13ba869 --- /dev/null +++ b/isolation_mark.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Antonio Quartulli a@unstable.cc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <stddef.h> + +#include "main.h" +#include "sys.h" + +static struct settings_data batctl_settings_isolation_mark = { + .sysfs_name = "isolation_mark", + .params = NULL, +}; + +COMMAND_NAMED(SUBCOMMAND, isolation_mark, "mark", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_isolation_mark, + "[mark] \tdisplay or modify isolation_mark setting"); diff --git a/sys.c b/sys.c index f81298b..355b801 100644 --- a/sys.c +++ b/sys.c @@ -155,15 +155,6 @@ COMMAND_NAMED(SUBCOMMAND, network_coding, "nc", handle_sys_setting, COMMAND_FLAG_MESH_IFACE, &batctl_settings_network_coding, "[0|1] \tdisplay or modify network_coding setting");
-static struct settings_data batctl_settings_isolation_mark = { - .sysfs_name = "isolation_mark", - .params = NULL, -}; - -COMMAND_NAMED(SUBCOMMAND, isolation_mark, "mark", handle_sys_setting, - COMMAND_FLAG_MESH_IFACE, &batctl_settings_isolation_mark, - "[mark] \tdisplay or modify isolation_mark setting"); - static struct settings_data batctl_settings_multicast_mode = { .sysfs_name = SYS_MULTICAST_MODE, .params = sysfs_param_enable,
The sysfs settings are planned to get also be implemented in netlink. To avoid cluttering up netlink.c again, it should be stored in a separate file. This also allows to order the usage lines using the Makefile.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + multicast_mode.c | 33 +++++++++++++++++++++++++++++++++ sys.c | 9 --------- 3 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 multicast_mode.c
diff --git a/Makefile b/Makefile index 9598065..9e5199d 100755 --- a/Makefile +++ b/Makefile @@ -56,6 +56,7 @@ OBJ += loglevel.o OBJ += log.o OBJ += main.o OBJ += mcast_flags.o +OBJ += multicast_mode.o OBJ += nc_nodes.o OBJ += neighbors.o OBJ += netlink.o diff --git a/multicast_mode.c b/multicast_mode.c new file mode 100644 index 0000000..8542928 --- /dev/null +++ b/multicast_mode.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Linus Lüssing linus.luessing@c0d3.blue + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include "main.h" +#include "sys.h" + +static struct settings_data batctl_settings_multicast_mode = { + .sysfs_name = SYS_MULTICAST_MODE, + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, multicast_mode, "mm", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_multicast_mode, + "[0|1] \tdisplay or modify multicast_mode setting"); diff --git a/sys.c b/sys.c index 355b801..80ef3ab 100644 --- a/sys.c +++ b/sys.c @@ -154,12 +154,3 @@ static struct settings_data batctl_settings_network_coding = { COMMAND_NAMED(SUBCOMMAND, network_coding, "nc", handle_sys_setting, COMMAND_FLAG_MESH_IFACE, &batctl_settings_network_coding, "[0|1] \tdisplay or modify network_coding setting"); - -static struct settings_data batctl_settings_multicast_mode = { - .sysfs_name = SYS_MULTICAST_MODE, - .params = sysfs_param_enable, -}; - -COMMAND_NAMED(SUBCOMMAND, multicast_mode, "mm", handle_sys_setting, - COMMAND_FLAG_MESH_IFACE, &batctl_settings_multicast_mode, - "[0|1] \tdisplay or modify multicast_mode setting");
The sysfs settings are planned to get also be implemented in netlink. To avoid cluttering up netlink.c again, it should be stored in a separate file. This also allows to order the usage lines using the Makefile.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + network_coding.c | 33 +++++++++++++++++++++++++++++++++ sys.c | 9 --------- 3 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 network_coding.c
diff --git a/Makefile b/Makefile index 9e5199d..8582bf6 100755 --- a/Makefile +++ b/Makefile @@ -60,6 +60,7 @@ OBJ += multicast_mode.o OBJ += nc_nodes.o OBJ += neighbors.o OBJ += netlink.o +OBJ += network_coding.o OBJ += ping.o OBJ += originators.o OBJ += routing_algo.o diff --git a/network_coding.c b/network_coding.c new file mode 100644 index 0000000..a4c4296 --- /dev/null +++ b/network_coding.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Martin Hundebøll martin@hundeboll.net + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include "main.h" +#include "sys.h" + +static struct settings_data batctl_settings_network_coding = { + .sysfs_name = SYS_NETWORK_CODING, + .params = sysfs_param_enable, +}; + +COMMAND_NAMED(SUBCOMMAND, network_coding, "nc", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_network_coding, + "[0|1] \tdisplay or modify network_coding setting"); diff --git a/sys.c b/sys.c index 80ef3ab..932a7e8 100644 --- a/sys.c +++ b/sys.c @@ -145,12 +145,3 @@ static struct settings_data batctl_settings_orig_interval = { COMMAND_NAMED(SUBCOMMAND, orig_interval, "it", handle_sys_setting, COMMAND_FLAG_MESH_IFACE, &batctl_settings_orig_interval, "[interval] \tdisplay or modify orig_interval setting"); - -static struct settings_data batctl_settings_network_coding = { - .sysfs_name = SYS_NETWORK_CODING, - .params = sysfs_param_enable, -}; - -COMMAND_NAMED(SUBCOMMAND, network_coding, "nc", handle_sys_setting, - COMMAND_FLAG_MESH_IFACE, &batctl_settings_network_coding, - "[0|1] \tdisplay or modify network_coding setting");
The sysfs settings are planned to get also be implemented in netlink. To avoid cluttering up netlink.c again, it should be stored in a separate file. This also allows to order the usage lines using the Makefile.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + orig_interval.c | 35 +++++++++++++++++++++++++++++++++++ sys.c | 9 --------- 3 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 orig_interval.c
diff --git a/Makefile b/Makefile index 8582bf6..a6971d8 100755 --- a/Makefile +++ b/Makefile @@ -63,6 +63,7 @@ OBJ += netlink.o OBJ += network_coding.o OBJ += ping.o OBJ += originators.o +OBJ += orig_interval.o OBJ += routing_algo.o OBJ += statistics.o OBJ += sys.o diff --git a/orig_interval.c b/orig_interval.c new file mode 100644 index 0000000..d308ea2 --- /dev/null +++ b/orig_interval.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner mareklindner@neomailbox.ch + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <stddef.h> + +#include "main.h" +#include "sys.h" + +static struct settings_data batctl_settings_orig_interval = { + .sysfs_name = "orig_interval", + .params = NULL, +}; + +COMMAND_NAMED(SUBCOMMAND, orig_interval, "it", handle_sys_setting, + COMMAND_FLAG_MESH_IFACE, &batctl_settings_orig_interval, + "[interval] \tdisplay or modify orig_interval setting"); diff --git a/sys.c b/sys.c index 932a7e8..6b98ac4 100644 --- a/sys.c +++ b/sys.c @@ -136,12 +136,3 @@ int handle_sys_setting(struct state *state, int argc, char **argv) free(base_dev); return res; } - -static struct settings_data batctl_settings_orig_interval = { - .sysfs_name = "orig_interval", - .params = NULL, -}; - -COMMAND_NAMED(SUBCOMMAND, orig_interval, "it", handle_sys_setting, - COMMAND_FLAG_MESH_IFACE, &batctl_settings_orig_interval, - "[interval] \tdisplay or modify orig_interval setting");
The netlink socket is used by the debug table functionality to retrieve the tables. The initialization can be centralized and moved to the main function (controlled by a flag) to share it between the other commands.
Since more commands will use netlink in the future, this flag can reduce the implementation effort significantly.
Signed-off-by: Sven Eckelmann sven@narfation.org --- backbonetable.c | 7 ++-- claimtable.c | 7 ++-- dat_cache.c | 9 ++--- debug.c | 5 ++- debug.h | 2 +- gateways.c | 11 ++++--- main.c | 18 +++++++++- main.h | 9 +++++ mcast_flags.c | 11 ++++--- neighbors.c | 7 ++-- netlink.c | 100 +++++++++++++++++++++++++++++++++++++------------------- netlink.h | 7 +++- originators.c | 11 ++++--- transglobal.c | 7 ++-- translocal.c | 7 ++-- 15 files changed, 145 insertions(+), 73 deletions(-)
diff --git a/backbonetable.c b/backbonetable.c index d2e58d1..b82fbe7 100644 --- a/backbonetable.c +++ b/backbonetable.c @@ -104,11 +104,11 @@ static int bla_backbone_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static int netlink_print_bla_backbone(char *mesh_iface, char *orig_iface, +static int netlink_print_bla_backbone(struct state *state, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) { - return netlink_print_common(mesh_iface, orig_iface, read_opts, + return netlink_print_common(state, orig_iface, read_opts, orig_timeout, watch_interval, "Originator VID last seen (CRC )\n", BATADV_CMD_GET_BLA_BACKBONE, @@ -122,4 +122,5 @@ static struct debug_table_data batctl_debug_table_backbonetable = { };
COMMAND_NAMED(DEBUGTABLE, backbonetable, "bbt", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_backbonetable, ""); + COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, + &batctl_debug_table_backbonetable, ""); diff --git a/claimtable.c b/claimtable.c index 06f42dc..5410392 100644 --- a/claimtable.c +++ b/claimtable.c @@ -109,11 +109,11 @@ static int bla_claim_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static int netlink_print_bla_claim(char *mesh_iface, char *orig_iface, +static int netlink_print_bla_claim(struct state *state, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) { - return netlink_print_common(mesh_iface, orig_iface, read_opts, + return netlink_print_common(state, orig_iface, read_opts, orig_timeout, watch_interval, "Client VID Originator [o] (CRC )\n", BATADV_CMD_GET_BLA_CLAIM, @@ -127,4 +127,5 @@ static struct debug_table_data batctl_debug_table_claimtable = { };
COMMAND_NAMED(DEBUGTABLE, claimtable, "cl", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_claimtable, ""); + COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, + &batctl_debug_table_claimtable, ""); diff --git a/dat_cache.c b/dat_cache.c index a56fb11..edf8c72 100644 --- a/dat_cache.c +++ b/dat_cache.c @@ -113,7 +113,7 @@ static int dat_cache_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static int netlink_print_dat_cache(char *mesh_iface, char *orig_iface, +static int netlink_print_dat_cache(struct state *state, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) { @@ -121,13 +121,13 @@ static int netlink_print_dat_cache(char *mesh_iface, char *orig_iface, int ret;
ret = asprintf(&header, "Distributed ARP Table (%s):\n%s\n", - mesh_iface, + state->mesh_iface, " IPv4 MAC VID last-seen");
if (ret < 0) return ret;
- ret = netlink_print_common(mesh_iface, orig_iface, read_opts, + ret = netlink_print_common(state, orig_iface, read_opts, orig_timeout, watch_interval, header, BATADV_CMD_GET_DAT_CACHE, dat_cache_callback); @@ -143,4 +143,5 @@ static struct debug_table_data batctl_debug_table_dat_cache = { };
COMMAND_NAMED(DEBUGTABLE, dat_cache, "dc", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_dat_cache, ""); + COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, + &batctl_debug_table_dat_cache, ""); diff --git a/debug.c b/debug.c index 17dde92..b908e00 100644 --- a/debug.c +++ b/debug.c @@ -168,9 +168,8 @@ int handle_debug_table(struct state *state, int argc, char **argv) }
if (debug_table->netlink_fn) { - err = debug_table->netlink_fn( - state->mesh_iface, orig_iface, read_opt, orig_timeout, - watch_interval); + err = debug_table->netlink_fn(state , orig_iface, read_opt, + orig_timeout, watch_interval); if (err != -EOPNOTSUPP) return err; } diff --git a/debug.h b/debug.h index 79c489a..525a46b 100644 --- a/debug.h +++ b/debug.h @@ -39,7 +39,7 @@ struct debug_table_data { const char *debugfs_name; size_t header_lines; - int (*netlink_fn)(char *mesh_iface, char *hard_iface, int read_opt, + int (*netlink_fn)(struct state *state, char *hard_iface, int read_opt, float orig_timeout, float watch_interval); unsigned int option_unicast_only:1; unsigned int option_multicast_only:1; diff --git a/gateways.c b/gateways.c index ca5d6ec..ff7693f 100644 --- a/gateways.c +++ b/gateways.c @@ -127,7 +127,7 @@ static int gateways_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static int netlink_print_gateways(char *mesh_iface, char *orig_iface, +static int netlink_print_gateways(struct state *state, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) { @@ -135,9 +135,9 @@ static int netlink_print_gateways(char *mesh_iface, char *orig_iface, char *info_header; int ifindex;
- ifindex = if_nametoindex(mesh_iface); + ifindex = if_nametoindex(state->mesh_iface); if (!ifindex) { - fprintf(stderr, "Interface %s is unknown\n", mesh_iface); + fprintf(stderr, "Interface %s is unknown\n", state->mesh_iface); return -ENODEV; }
@@ -157,7 +157,7 @@ static int netlink_print_gateways(char *mesh_iface, char *orig_iface, if (!header) return -EINVAL;
- return netlink_print_common(mesh_iface, orig_iface, read_opts, + return netlink_print_common(state, orig_iface, read_opts, orig_timeout, watch_interval, header, BATADV_CMD_GET_GATEWAYS, @@ -171,4 +171,5 @@ static struct debug_table_data batctl_debug_table_gateways = { };
COMMAND_NAMED(DEBUGTABLE, gateways, "gwl", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_gateways, ""); + COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, + &batctl_debug_table_gateways, ""); diff --git a/main.c b/main.c index 9fc6bfb..ab7da45 100644 --- a/main.c +++ b/main.c @@ -21,7 +21,7 @@ */
- +#include <errno.h> #include <getopt.h> #include <stdio.h> #include <stdlib.h> @@ -32,6 +32,7 @@ #include "sys.h" #include "debug.h" #include "functions.h" +#include "netlink.h"
char mesh_dfl_iface[] = "bat0"; char module_ver_path[] = "/sys/module/batman_adv/version"; @@ -180,8 +181,23 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); }
+ if (cmd->flags & COMMAND_FLAG_NETLINK) { + ret = netlink_create(&state); + if (ret < 0 && ret != -EOPNOTSUPP) { + /* TODO handle -EOPNOTSUPP as error when fallbacks were + * removed + */ + fprintf(stderr, + "Error - failed to connect to batadv\n"); + exit(EXIT_FAILURE); + } + } + ret = cmd->handler(&state, argc, argv);
+ if (cmd->flags & COMMAND_FLAG_NETLINK) + netlink_destroy(&state); + return ret;
err: diff --git a/main.h b/main.h index 2656dcf..4a48f61 100644 --- a/main.h +++ b/main.h @@ -25,6 +25,10 @@
#include <stdint.h>
+#include <netlink/genl/ctrl.h> +#include <netlink/genl/genl.h> +#include <netlink/netlink.h> + #ifndef SOURCE_VERSION #define SOURCE_VERSION "2018.4" #endif @@ -61,6 +65,7 @@ extern char module_ver_path[];
enum command_flags { COMMAND_FLAG_MESH_IFACE = BIT(0), + COMMAND_FLAG_NETLINK = BIT(1), };
enum command_type { @@ -71,6 +76,10 @@ enum command_type { struct state { char *mesh_iface; const struct command *cmd; + + struct nl_sock *sock; + struct nl_cb *cb; + int batadv_family; };
struct command { diff --git a/mcast_flags.c b/mcast_flags.c index e35cce3..0dc4227 100644 --- a/mcast_flags.c +++ b/mcast_flags.c @@ -105,7 +105,7 @@ static int mcast_flags_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static int netlink_print_mcast_flags(char *mesh_iface, char *orig_iface, +static int netlink_print_mcast_flags(struct state *state, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) { @@ -116,9 +116,9 @@ static int netlink_print_mcast_flags(char *mesh_iface, char *orig_iface, int ifindex; int ret;
- ifindex = if_nametoindex(mesh_iface); + ifindex = if_nametoindex(state->mesh_iface); if (!ifindex) { - fprintf(stderr, "Interface %s is unknown\n", mesh_iface); + fprintf(stderr, "Interface %s is unknown\n", state->mesh_iface); return -ENODEV; }
@@ -160,7 +160,7 @@ static int netlink_print_mcast_flags(char *mesh_iface, char *orig_iface, if (ret < 0) return ret;
- ret = netlink_print_common(mesh_iface, orig_iface, read_opts, + ret = netlink_print_common(state, orig_iface, read_opts, orig_timeout, watch_interval, header, BATADV_CMD_GET_MCAST_FLAGS, mcast_flags_callback); @@ -176,4 +176,5 @@ static struct debug_table_data batctl_debug_table_mcast_flags = { };
COMMAND_NAMED(DEBUGTABLE, mcast_flags, "mf", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_mcast_flags, ""); + COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, + &batctl_debug_table_mcast_flags, ""); diff --git a/neighbors.c b/neighbors.c index f7ea9ec..76b45ea 100644 --- a/neighbors.c +++ b/neighbors.c @@ -120,11 +120,11 @@ static int neighbors_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static int netlink_print_neighbors(char *mesh_iface, char *orig_iface, +static int netlink_print_neighbors(struct state *state, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) { - return netlink_print_common(mesh_iface, orig_iface, read_opts, + return netlink_print_common(state, orig_iface, read_opts, orig_timeout, watch_interval, "IF Neighbor last-seen\n", BATADV_CMD_GET_NEIGHBORS, @@ -138,4 +138,5 @@ static struct debug_table_data batctl_debug_table_neighbors = { };
COMMAND_NAMED(DEBUGTABLE, neighbors, "n", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_neighbors, ""); + COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, + &batctl_debug_table_neighbors, ""); diff --git a/netlink.c b/netlink.c index 26ae27d..8268037 100644 --- a/netlink.c +++ b/netlink.c @@ -109,6 +109,59 @@ struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = { [BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NLA_U32 }, };
+int netlink_create(struct state *state) +{ + int ret; + + state->sock = NULL; + state->cb = NULL; + state->batadv_family = 0; + + state->sock = nl_socket_alloc(); + if (!state->sock) + return -ENOMEM; + + ret = genl_connect(state->sock); + if (ret < 0) + goto err_free_sock; + + state->batadv_family = genl_ctrl_resolve(state->sock, BATADV_NL_NAME); + if (state->batadv_family < 0) { + ret = -EOPNOTSUPP; + goto err_free_sock; + } + + state->cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!state->cb) { + ret = -ENOMEM; + goto err_free_family; + } + + return 0; + +err_free_family: + state->batadv_family = 0; + +err_free_sock: + nl_socket_free(state->sock); + state->sock = NULL; + + return ret; +} + +void netlink_destroy(struct state *state) +{ + if (state->cb) { + nl_cb_put(state->cb); + state->cb = NULL; + } + + if (state->sock) { + nl_socket_free(state->sock); + state->sock = NULL; + } +} + int last_err; char algo_name_buf[256] = ""; int64_t mcast_flags = -EOPNOTSUPP; @@ -456,7 +509,7 @@ int netlink_print_routing_algos(void) return last_err; }
-int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt, +int netlink_print_common(struct state *state, char *orig_iface, int read_opt, float orig_timeout, float watch_interval, const char *header, uint8_t nl_cmd, nl_recvmsg_msg_cb_t callback) @@ -469,29 +522,19 @@ int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt, .callback = callback, }; int hardifindex = 0; - struct nl_sock *sock; struct nl_msg *msg; - struct nl_cb *cb; int ifindex; - int family;
- sock = nl_socket_alloc(); - if (!sock) - return -ENOMEM; - - genl_connect(sock); - - family = genl_ctrl_resolve(sock, BATADV_NL_NAME); - if (family < 0) { + if (!state->sock) { last_err = -EOPNOTSUPP; - goto err_free_sock; + return last_err; }
- ifindex = if_nametoindex(mesh_iface); + ifindex = if_nametoindex(state->mesh_iface); if (!ifindex) { - fprintf(stderr, "Interface %s is unknown\n", mesh_iface); + fprintf(stderr, "Interface %s is unknown\n", state->mesh_iface); last_err = -ENODEV; - goto err_free_sock; + return last_err; }
if (orig_iface) { @@ -500,21 +543,15 @@ int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt, fprintf(stderr, "Interface %s is unknown\n", orig_iface); last_err = -ENODEV; - goto err_free_sock; + return last_err; } }
- cb = nl_cb_alloc(NL_CB_DEFAULT); - if (!cb) { - last_err = -ENOMEM; - goto err_free_sock; - } - bat_hosts_init(read_opt);
- nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, netlink_print_common_cb, &opts); - nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, stop_callback, NULL); - nl_cb_err(cb, NL_CB_CUSTOM, print_error, NULL); + nl_cb_set(state->cb, NL_CB_VALID, NL_CB_CUSTOM, netlink_print_common_cb, &opts); + nl_cb_set(state->cb, NL_CB_FINISH, NL_CB_CUSTOM, stop_callback, NULL); + nl_cb_err(state->cb, NL_CB_CUSTOM, print_error, NULL);
do { if (read_opt & CLR_CONT_READ) @@ -530,20 +567,20 @@ int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt, if (!msg) continue;
- genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, - NLM_F_DUMP, nl_cmd, 1); + 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); if (hardifindex) nla_put_u32(msg, BATADV_ATTR_HARD_IFINDEX, hardifindex);
- nl_send_auto_complete(sock, msg); + nl_send_auto_complete(state->sock, msg);
nlmsg_free(msg);
last_err = 0; - nl_recvmsgs(sock, cb); + nl_recvmsgs(state->sock, state->cb);
/* the header should still be printed when no entry was received */ if (!last_err) @@ -556,9 +593,6 @@ int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt,
bat_hosts_free();
-err_free_sock: - nl_socket_free(sock); - return last_err; }
diff --git a/netlink.h b/netlink.h index 0b21ac1..2526b07 100644 --- a/netlink.h +++ b/netlink.h @@ -27,6 +27,8 @@ #include <netlink/genl/ctrl.h> #include <stdint.h>
+struct state; + struct print_opts { int read_opt; float orig_timeout; @@ -39,6 +41,9 @@ struct print_opts {
struct ether_addr;
+int netlink_create(struct state *state); +void netlink_destroy(struct state *state); + int netlink_print_routing_algos(void);
char *netlink_get_info(int ifindex, uint8_t nl_cmd, const char *header); @@ -52,7 +57,7 @@ extern struct nla_policy batadv_netlink_policy[];
int missing_mandatory_attrs(struct nlattr *attrs[], const int mandatory[], int num); -int netlink_print_common(char *mesh_iface, char *orig_iface, int read_opt, +int netlink_print_common(struct state *state, char *orig_iface, int read_opt, float orig_timeout, float watch_interval, const char *header, uint8_t nl_cmd, nl_recvmsg_msg_cb_t callback); diff --git a/originators.c b/originators.c index 54526e3..c29300a 100644 --- a/originators.c +++ b/originators.c @@ -179,7 +179,7 @@ static int originators_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static int netlink_print_originators(char *mesh_iface, char *orig_iface, +static int netlink_print_originators(struct state *state, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) { @@ -187,9 +187,9 @@ static int netlink_print_originators(char *mesh_iface, char *orig_iface, char *info_header; int ifindex;
- ifindex = if_nametoindex(mesh_iface); + ifindex = if_nametoindex(state->mesh_iface); if (!ifindex) { - fprintf(stderr, "Interface %s is unknown\n", mesh_iface); + fprintf(stderr, "Interface %s is unknown\n", state->mesh_iface); return -ENODEV; }
@@ -209,7 +209,7 @@ static int netlink_print_originators(char *mesh_iface, char *orig_iface, if (!header) return -EINVAL;
- return netlink_print_common(mesh_iface, orig_iface, read_opts, + return netlink_print_common(state, orig_iface, read_opts, orig_timeout, watch_interval, header, BATADV_CMD_GET_ORIGINATORS, originators_callback); @@ -224,4 +224,5 @@ static struct debug_table_data batctl_debug_table_originators = { };
COMMAND_NAMED(DEBUGTABLE, originators, "o", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_originators, ""); + COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, + &batctl_debug_table_originators, ""); diff --git a/transglobal.c b/transglobal.c index f61aa9f..fbbce25 100644 --- a/transglobal.c +++ b/transglobal.c @@ -138,11 +138,11 @@ static int transglobal_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static int netlink_print_transglobal(char *mesh_iface, char *orig_iface, +static int netlink_print_transglobal(struct state *state, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) { - return netlink_print_common(mesh_iface, orig_iface, read_opts, + return netlink_print_common(state, orig_iface, read_opts, orig_timeout, watch_interval, " Client VID Flags Last ttvn Via ttvn (CRC )\n", BATADV_CMD_GET_TRANSTABLE_GLOBAL, @@ -158,4 +158,5 @@ static struct debug_table_data batctl_debug_table_transglobal = { };
COMMAND_NAMED(DEBUGTABLE, transglobal, "tg", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_transglobal, ""); + COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, + &batctl_debug_table_transglobal, ""); diff --git a/translocal.c b/translocal.c index 815dc1e..1057abd 100644 --- a/translocal.c +++ b/translocal.c @@ -134,11 +134,11 @@ static int translocal_callback(struct nl_msg *msg, void *arg) return NL_OK; }
-static int netlink_print_translocal(char *mesh_iface, char *orig_iface, +static int netlink_print_translocal(struct state *state, char *orig_iface, int read_opts, float orig_timeout, float watch_interval) { - return netlink_print_common(mesh_iface, orig_iface, read_opts, + return netlink_print_common(state, orig_iface, read_opts, orig_timeout, watch_interval, "Client VID Flags Last seen (CRC )\n", BATADV_CMD_GET_TRANSTABLE_LOCAL, @@ -154,4 +154,5 @@ static struct debug_table_data batctl_debug_table_translocal = { };
COMMAND_NAMED(DEBUGTABLE, translocal, "tl", handle_debug_table, - COMMAND_FLAG_MESH_IFACE, &batctl_debug_table_translocal, ""); + COMMAND_FLAG_MESH_IFACE | COMMAND_FLAG_NETLINK, + &batctl_debug_table_translocal, "");
It is easier to work on the actual command implementation when its source code is also saved it the correct source file. Only the shared code should be in the shared code location.
Signed-off-by: Sven Eckelmann sven@narfation.org --- debug.c | 15 ------- debug.h | 1 - functions.c | 10 ----- functions.h | 1 - netlink.c | 116 ++++--------------------------------------------- netlink.h | 8 +++- routing_algo.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 147 insertions(+), 137 deletions(-)
diff --git a/debug.c b/debug.c index b908e00..2979dff 100644 --- a/debug.c +++ b/debug.c @@ -183,18 +183,3 @@ int handle_debug_table(struct state *state, int argc, char **argv) read_opt, orig_timeout, watch_interval, debug_table->header_lines); } - -int debug_print_routing_algos(void) -{ - char full_path[MAX_PATH+1]; - char *debugfs_mnt; - - debugfs_mnt = debugfs_mount(NULL); - if (!debugfs_mnt) { - fprintf(stderr, "Error - can't mount or find debugfs\n"); - return -1; - } - - debugfs_make_path(DEBUG_BATIF_PATH_FMT, "", full_path, sizeof(full_path)); - return read_file(full_path, DEBUG_ROUTING_ALGOS, 0, 0, 0, 0); -} diff --git a/debug.h b/debug.h index 525a46b..2dac1b7 100644 --- a/debug.h +++ b/debug.h @@ -48,6 +48,5 @@ struct debug_table_data { };
int handle_debug_table(struct state *state, int argc, char **argv); -int debug_print_routing_algos(void);
#endif diff --git a/functions.c b/functions.c index 0a7b587..bdede8b 100644 --- a/functions.c +++ b/functions.c @@ -905,16 +905,6 @@ int vlan_get_link(const char *ifname, char **parent) return arg.vid; }
-int print_routing_algos(void) -{ - int err; - - err = netlink_print_routing_algos(); - if (err == -EOPNOTSUPP) - err = debug_print_routing_algos(); - return err; -} - int query_rtnl_link(int ifindex, nl_recvmsg_msg_cb_t func, void *arg) { struct ifinfomsg rt_hdr = { diff --git a/functions.h b/functions.h index d3144d0..c16ba2e 100644 --- a/functions.h +++ b/functions.h @@ -57,7 +57,6 @@ 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 print_routing_algos(void); extern char *line_ptr;
enum { diff --git a/netlink.c b/netlink.c index 8268037..5285759 100644 --- a/netlink.c +++ b/netlink.c @@ -179,9 +179,8 @@ int missing_mandatory_attrs(struct nlattr *attrs[], const int mandatory[], return 0; }
-static int print_error(struct sockaddr_nl *nla __maybe_unused, - struct nlmsgerr *nlerr, - void *arg __maybe_unused) +int netlink_print_error(struct sockaddr_nl *nla __maybe_unused, + struct nlmsgerr *nlerr, void *arg __maybe_unused) { if (nlerr->error != -EOPNOTSUPP) fprintf(stderr, "Error received: %s\n", @@ -192,7 +191,7 @@ static int print_error(struct sockaddr_nl *nla __maybe_unused, return NL_STOP; }
-static int stop_callback(struct nl_msg *msg, void *arg __maybe_unused) +int netlink_stop_callback(struct nl_msg *msg, void *arg __maybe_unused) { struct nlmsghdr *nlh = nlmsg_hdr(msg); int *error = nlmsg_data(nlh); @@ -381,7 +380,7 @@ char *netlink_get_info(int ifindex, uint8_t nl_cmd, const char *header) goto err_free_sock;
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, info_callback, &opts); - nl_cb_err(cb, NL_CB_CUSTOM, print_error, NULL); + nl_cb_err(cb, NL_CB_CUSTOM, netlink_print_error, NULL);
nl_recvmsgs(sock, cb);
@@ -391,7 +390,7 @@ char *netlink_get_info(int ifindex, uint8_t nl_cmd, const char *header) return opts.remaining_header; }
-static void netlink_print_remaining_header(struct print_opts *opts) +void netlink_print_remaining_header(struct print_opts *opts) { if (!opts->remaining_header) return; @@ -401,7 +400,7 @@ static void netlink_print_remaining_header(struct print_opts *opts) opts->remaining_header = NULL; }
-static int netlink_print_common_cb(struct nl_msg *msg, void *arg) +int netlink_print_common_cb(struct nl_msg *msg, void *arg) { struct print_opts *opts = arg;
@@ -410,105 +409,6 @@ static int netlink_print_common_cb(struct nl_msg *msg, void *arg) return opts->callback(msg, arg); }
-static const int routing_algos_mandatory[] = { - BATADV_ATTR_ALGO_NAME, -}; - -static int routing_algos_callback(struct nl_msg *msg, void *arg __maybe_unused) -{ - struct nlattr *attrs[BATADV_ATTR_MAX+1]; - struct nlmsghdr *nlh = nlmsg_hdr(msg); - struct genlmsghdr *ghdr; - const char *algo_name; - - if (!genlmsg_valid_hdr(nlh, 0)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - ghdr = nlmsg_data(nlh); - - if (ghdr->cmd != BATADV_CMD_GET_ROUTING_ALGOS) - return NL_OK; - - if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), - genlmsg_len(ghdr), batadv_netlink_policy)) { - fputs("Received invalid data from kernel.\n", stderr); - exit(1); - } - - if (missing_mandatory_attrs(attrs, routing_algos_mandatory, - ARRAY_SIZE(routing_algos_mandatory))) { - fputs("Missing attributes from kernel\n", stderr); - exit(1); - } - - algo_name = nla_get_string(attrs[BATADV_ATTR_ALGO_NAME]); - - printf(" * %s\n", algo_name); - - return NL_OK; -} - -int netlink_print_routing_algos(void) -{ - struct nl_sock *sock; - struct nl_msg *msg; - struct nl_cb *cb; - int family; - struct print_opts opts = { - .callback = routing_algos_callback, - }; - - sock = nl_socket_alloc(); - if (!sock) - return -ENOMEM; - - genl_connect(sock); - - family = genl_ctrl_resolve(sock, BATADV_NL_NAME); - if (family < 0) { - last_err = -EOPNOTSUPP; - goto err_free_sock; - } - - msg = nlmsg_alloc(); - if (!msg) { - last_err = -ENOMEM; - goto err_free_sock; - } - - genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_DUMP, - BATADV_CMD_GET_ROUTING_ALGOS, 1); - - nl_send_auto_complete(sock, msg); - - nlmsg_free(msg); - - opts.remaining_header = strdup("Available routing algorithms:\n"); - - cb = nl_cb_alloc(NL_CB_DEFAULT); - if (!cb) { - last_err = -ENOMEM; - goto err_free_sock; - } - - nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, netlink_print_common_cb, - &opts); - nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, stop_callback, NULL); - nl_cb_err(cb, NL_CB_CUSTOM, print_error, NULL); - - nl_recvmsgs(sock, cb); - -err_free_sock: - nl_socket_free(sock); - - if (!last_err) - netlink_print_remaining_header(&opts); - - return last_err; -} - int netlink_print_common(struct state *state, char *orig_iface, int read_opt, float orig_timeout, float watch_interval, const char *header, uint8_t nl_cmd, @@ -550,8 +450,8 @@ int netlink_print_common(struct state *state, char *orig_iface, int read_opt, bat_hosts_init(read_opt);
nl_cb_set(state->cb, NL_CB_VALID, NL_CB_CUSTOM, netlink_print_common_cb, &opts); - nl_cb_set(state->cb, NL_CB_FINISH, NL_CB_CUSTOM, stop_callback, NULL); - nl_cb_err(state->cb, NL_CB_CUSTOM, print_error, NULL); + nl_cb_set(state->cb, NL_CB_FINISH, NL_CB_CUSTOM, netlink_stop_callback, NULL); + nl_cb_err(state->cb, NL_CB_CUSTOM, netlink_print_error, NULL);
do { if (read_opt & CLR_CONT_READ) diff --git a/netlink.h b/netlink.h index 2526b07..b91ca10 100644 --- a/netlink.h +++ b/netlink.h @@ -44,8 +44,6 @@ struct ether_addr; int netlink_create(struct state *state); void netlink_destroy(struct state *state);
-int netlink_print_routing_algos(void); - char *netlink_get_info(int ifindex, uint8_t nl_cmd, const char *header); int translate_mac_netlink(const char *mesh_iface, const struct ether_addr *mac, struct ether_addr *mac_out); @@ -62,6 +60,12 @@ int netlink_print_common(struct state *state, char *orig_iface, int read_opt, const char *header, uint8_t nl_cmd, nl_recvmsg_msg_cb_t callback);
+int netlink_print_common_cb(struct nl_msg *msg, void *arg); +int netlink_stop_callback(struct nl_msg *msg, void *arg); +int netlink_print_error(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, + void *arg); +void netlink_print_remaining_header(struct print_opts *opts); + extern char algo_name_buf[256]; extern int last_err; extern int64_t mcast_flags; diff --git a/routing_algo.c b/routing_algo.c index ded9284..18d9ef7 100644 --- a/routing_algo.c +++ b/routing_algo.c @@ -23,12 +23,21 @@ #include <dirent.h> #include <errno.h> #include <getopt.h> +#include <netinet/if_ether.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> #include <stdio.h> #include <stdlib.h> #include <string.h>
+#include "batadv_packet.h" +#include "batman_adv.h" +#include "debug.h" +#include "debugfs.h" #include "functions.h" #include "main.h" +#include "netlink.h" #include "sys.h"
#define SYS_SELECTED_RA_PATH "/sys/module/batman_adv/parameters/routing_algo" @@ -41,6 +50,130 @@ static void ra_mode_usage(void) fprintf(stderr, " \t -h print this help\n"); }
+static const int routing_algos_mandatory[] = { + BATADV_ATTR_ALGO_NAME, +}; + +static int routing_algos_callback(struct nl_msg *msg, void *arg __maybe_unused) +{ + struct nlattr *attrs[BATADV_ATTR_MAX+1]; + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct genlmsghdr *ghdr; + const char *algo_name; + + if (!genlmsg_valid_hdr(nlh, 0)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + ghdr = nlmsg_data(nlh); + + if (ghdr->cmd != BATADV_CMD_GET_ROUTING_ALGOS) + return NL_OK; + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) { + fputs("Received invalid data from kernel.\n", stderr); + exit(1); + } + + if (missing_mandatory_attrs(attrs, routing_algos_mandatory, + ARRAY_SIZE(routing_algos_mandatory))) { + fputs("Missing attributes from kernel\n", stderr); + exit(1); + } + + algo_name = nla_get_string(attrs[BATADV_ATTR_ALGO_NAME]); + + printf(" * %s\n", algo_name); + + return NL_OK; +} + +static int netlink_print_routing_algos(void) +{ + struct nl_sock *sock; + struct nl_msg *msg; + struct nl_cb *cb; + int family; + struct print_opts opts = { + .callback = routing_algos_callback, + }; + + sock = nl_socket_alloc(); + if (!sock) + return -ENOMEM; + + genl_connect(sock); + + family = genl_ctrl_resolve(sock, BATADV_NL_NAME); + if (family < 0) { + last_err = -EOPNOTSUPP; + goto err_free_sock; + } + + msg = nlmsg_alloc(); + if (!msg) { + last_err = -ENOMEM; + goto err_free_sock; + } + + genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_DUMP, + BATADV_CMD_GET_ROUTING_ALGOS, 1); + + nl_send_auto_complete(sock, msg); + + nlmsg_free(msg); + + opts.remaining_header = strdup("Available routing algorithms:\n"); + + cb = nl_cb_alloc(NL_CB_DEFAULT); + if (!cb) { + last_err = -ENOMEM; + goto err_free_sock; + } + + nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, netlink_print_common_cb, + &opts); + nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, netlink_stop_callback, NULL); + nl_cb_err(cb, NL_CB_CUSTOM, netlink_print_error, NULL); + + nl_recvmsgs(sock, cb); + +err_free_sock: + nl_socket_free(sock); + + if (!last_err) + netlink_print_remaining_header(&opts); + + return last_err; +} + +static int debug_print_routing_algos(void) +{ + char full_path[MAX_PATH+1]; + char *debugfs_mnt; + + debugfs_mnt = debugfs_mount(NULL); + if (!debugfs_mnt) { + fprintf(stderr, "Error - can't mount or find debugfs\n"); + return -1; + } + + debugfs_make_path(DEBUG_BATIF_PATH_FMT, "", full_path, sizeof(full_path)); + return read_file(full_path, DEBUG_ROUTING_ALGOS, 0, 0, 0, 0); +} + +static int print_routing_algos(void) +{ + int err; + + err = netlink_print_routing_algos(); + if (err == -EOPNOTSUPP) + err = debug_print_routing_algos(); + return err; +} + static int routing_algo(struct state *state __maybe_unused, int argc, char **argv) { DIR *iface_base_dir;
The netlink multicast groups of batman-adv are currently used to inform userspace about finished throughputmeter runs. It will later also be used to inform about changes of settings of a specific batadv interface.
The "event" will wait for these messages and print brief summaries about the received data. This can be used during the development of new features or to monitor running systems.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 1 + event.c | 246 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ man/batctl.8 | 4 + 3 files changed, 251 insertions(+) create mode 100644 event.c
diff --git a/Makefile b/Makefile index a6971d8..cf2b1c7 100755 --- a/Makefile +++ b/Makefile @@ -43,6 +43,7 @@ OBJ += dat_cache.o OBJ += debugfs.o OBJ += debug.o OBJ += distributed_arp_table.o +OBJ += event.o OBJ += fragmentation.o OBJ += functions.o OBJ += gateways.o diff --git a/event.c b/event.c new file mode 100644 index 0000000..8eda269 --- /dev/null +++ b/event.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (C) 2009-2018 B.A.T.M.A.N. contributors: + * + * Sven Eckelmann sven@narfation.org + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + * License-Filename: LICENSES/preferred/GPL-2.0 + */ + +#include <errno.h> +#include <getopt.h> +#include <netinet/if_ether.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <sys/time.h> + +#include "batadv_packet.h" +#include "batman_adv.h" +#include "bat-hosts.h" +#include "debug.h" +#include "functions.h" +#include "genl.h" +#include "main.h" +#include "netlink.h" + +enum event_time_mode { + EVENT_TIME_NO, + EVENT_TIME_LOCAL, + EVENT_TIME_RELATIVE, +}; + +struct event_args { + enum event_time_mode mode; + struct timeval tv; +}; + +static void event_usage(void) +{ + fprintf(stderr, "Usage: batctl [options] event [parameters]\n"); + fprintf(stderr, "parameters:\n"); + fprintf(stderr, " \t -h print this help\n"); + fprintf(stderr, " \t -t print local timestamp\n"); + fprintf(stderr, " \t -r print relative timestamp\n"); +} + +static int event_prepare(struct state *state) +{ + int ret; + int mcid; + + if (!state->sock) + return -EOPNOTSUPP; + + mcid = nl_get_multicast_id(state->sock, BATADV_NL_NAME, + BATADV_NL_MCAST_GROUP_TPMETER); + if (mcid < 0) { + fprintf(stderr, "Failed to resolve batadv tp_meter multicast group: %d\n", + mcid); + /* ignore error for now */ + goto skip_tp_meter; + } + + ret = nl_socket_add_membership(state->sock, mcid); + if (ret) { + fprintf(stderr, "Failed to join batadv tp_meter multicast group: %d\n", + ret); + /* ignore error for now */ + goto skip_tp_meter; + } + +skip_tp_meter: + + return 0; +} + +static int no_seq_check(struct nl_msg *msg __maybe_unused, + void *arg __maybe_unused) +{ + return NL_OK; +} + +static const int tp_meter_mandatory[] = { + BATADV_ATTR_TPMETER_COOKIE, + BATADV_ATTR_TPMETER_RESULT, +}; + +static void event_parse_tp_meter(struct nlattr **attrs) +{ + const char *result_str; + uint32_t cookie; + uint8_t result; + + /* ignore entry when attributes are missing */ + if (missing_mandatory_attrs(attrs, tp_meter_mandatory, + ARRAY_SIZE(tp_meter_mandatory))) + return; + + cookie = nla_get_u32(attrs[BATADV_ATTR_TPMETER_COOKIE]); + result = nla_get_u8(attrs[BATADV_ATTR_TPMETER_RESULT]); + + switch (result) { + case BATADV_TP_REASON_DST_UNREACHABLE: + result_str = "Destination unreachable"; + break; + case BATADV_TP_REASON_RESEND_LIMIT: + result_str = "The number of retry for the same window exceeds the limit, test aborted"; + break; + case BATADV_TP_REASON_ALREADY_ONGOING: + result_str = "Cannot run two test towards the same node"; + break; + case BATADV_TP_REASON_MEMORY_ERROR: + result_str = "Kernel cannot allocate memory, aborted"; + break; + case BATADV_TP_REASON_TOO_MANY: + result_str = "Too many ongoing sessions"; + break; + case BATADV_TP_REASON_CANCEL: + result_str = "CANCEL received: test aborted"; + break; + case BATADV_TP_REASON_COMPLETE: + result_str = "complete"; + break; + default: + result_str = "unknown"; + break; + } + + printf("tp_meter 0x%08x: %s\n", cookie, result_str); +} + +static unsigned long long get_timestamp(struct event_args *event_args) +{ + unsigned long long prevtime = 0; + unsigned long long now; + struct timeval tv; + + gettimeofday(&tv, NULL); + now = 1000000ULL * tv.tv_sec + tv.tv_usec; + + if (event_args->mode == EVENT_TIME_RELATIVE) { + prevtime = 1000000ULL * event_args->tv.tv_sec + event_args->tv.tv_usec; + event_args->tv = tv; + } + + return now - prevtime; +} + +static int event_parse(struct nl_msg *msg, void *arg) +{ + struct nlmsghdr *nlh = nlmsg_hdr(msg); + struct nlattr *attrs[NUM_BATADV_ATTR]; + struct event_args *event_args = arg; + unsigned long long timestamp; + struct genlmsghdr *ghdr; + + if (!genlmsg_valid_hdr(nlh, 0)) + return NL_OK; + + ghdr = nlmsg_data(nlh); + + if (nla_parse(attrs, BATADV_ATTR_MAX, genlmsg_attrdata(ghdr, 0), + genlmsg_len(ghdr), batadv_netlink_policy)) { + fputs("Received invalid data from kernel.\n", stderr); + return NL_OK; + } + + if (event_args->mode != EVENT_TIME_NO) { + timestamp = get_timestamp(event_args); + printf("%llu.%06llu: ", timestamp / 1000000, timestamp % 1000000); + } + + switch (ghdr->cmd) { + case BATADV_CMD_TP_METER: + event_parse_tp_meter(attrs); + break; + default: + printf("Received unknown event %u\n", ghdr->cmd); + break; + } + + return NL_OK; +} + +static int event(struct state *state, int argc, char **argv) +{ + struct event_args event_args = { + .mode = EVENT_TIME_NO, + }; + int opt; + int ret; + + while ((opt = getopt(argc, argv, "htr")) != -1) { + switch (opt) { + case 'h': + event_usage(); + return EXIT_SUCCESS; + case 't': + event_args.mode = EVENT_TIME_LOCAL; + break; + case 'r': + event_args.mode = EVENT_TIME_RELATIVE; + break; + default: + event_usage(); + return EXIT_FAILURE; + } + } + + ret = event_prepare(state); + if (ret < 0) { + fprintf(stderr, "Failed to prepare event netlink: %s (%d)\n", + strerror(-ret), -ret); + return 1; + } + + if (event_args.mode == EVENT_TIME_RELATIVE) + get_timestamp(&event_args); + + nl_cb_set(state->cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL); + nl_cb_set(state->cb, NL_CB_VALID, NL_CB_CUSTOM, event_parse, &event_args); + + while (1) + nl_recvmsgs(state->sock, state->cb); + + return 0; +} + +COMMAND(SUBCOMMAND, event, "e", COMMAND_FLAG_NETLINK, NULL, + " \tdisplay events from batman-adv"); diff --git a/man/batctl.8 b/man/batctl.8 index d5fc530..fe6cf93 100644 --- a/man/batctl.8 +++ b/man/batctl.8 @@ -89,6 +89,10 @@ OGM packet aggregation. If no parameter is given the current bonding mode setting is displayed. Otherwise the parameter is used to enable or disable the bonding mode. .br +.IP "\fBevent\fP|\fBe\fP [\fB-t\fP|\fB-r\fP]" +batctl will monitor for events from the netlink kernel interface of batman-adv. The local timestamp of the event will be printed +when parameter \fB-t\fP is specified. Parameter \fB-r\fP will do the same but with relative timestamps. +.br .IP "\fBfragmentation\fP|\fBf\fP [\fB0\fP|\fB1\fP]" If no parameter is given the current fragmentation mode setting is displayed. Otherwise the parameter is used to enable or disable fragmentation.
The variable content of CONFIG_BATCTL_BISECT can be used to decide whether the bisect_iv command is enabled or not. This would make it possible in the future to introduce a generic way to enable or disable commands. Combining this with link-time-optimization and/or function/data-section allows to relatively freely scale the functionality of batctl and its size.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 96 +++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 46 insertions(+), 50 deletions(-)
diff --git a/Makefile b/Makefile index cf2b1c7..dfcfbd9 100755 --- a/Makefile +++ b/Makefile @@ -27,53 +27,49 @@ export CONFIG_BATCTL_BISECT=n # batctl build BINARY_NAME = batctl
-OBJ_BISECT = bisect_iv.o - -OBJ += aggregation.o -OBJ += ap_isolation.o -OBJ += bat-hosts.o -OBJ += backbonetable.o -ifeq ($(CONFIG_BATCTL_BISECT),y) -OBJ += $(OBJ_BISECT) -endif -OBJ += bonding.o -OBJ += bridge_loop_avoidance.o -OBJ += claimtable.o -OBJ += dat_cache.o -OBJ += debugfs.o -OBJ += debug.o -OBJ += distributed_arp_table.o -OBJ += event.o -OBJ += fragmentation.o -OBJ += functions.o -OBJ += gateways.o -OBJ += genl.o -OBJ += gw_mode.o -OBJ += hash.o -OBJ += icmp_helper.o -OBJ += interface.o -OBJ += isolation_mark.o -OBJ += loglevel.o -OBJ += log.o -OBJ += main.o -OBJ += mcast_flags.o -OBJ += multicast_mode.o -OBJ += nc_nodes.o -OBJ += neighbors.o -OBJ += netlink.o -OBJ += network_coding.o -OBJ += ping.o -OBJ += originators.o -OBJ += orig_interval.o -OBJ += routing_algo.o -OBJ += statistics.o -OBJ += sys.o -OBJ += tcpdump.o -OBJ += throughputmeter.o -OBJ += traceroute.o -OBJ += transglobal.o -OBJ += translate.o -OBJ += translocal.o +obj-y += aggregation.o +obj-y += ap_isolation.o +obj-y += bat-hosts.o +obj-y += backbonetable.o +obj-$(CONFIG_BATCTL_BISECT) += bisect_iv.o +obj-y += bonding.o +obj-y += bridge_loop_avoidance.o +obj-y += claimtable.o +obj-y += dat_cache.o +obj-y += debugfs.o +obj-y += debug.o +obj-y += distributed_arp_table.o +obj-y += event.o +obj-y += fragmentation.o +obj-y += functions.o +obj-y += gateways.o +obj-y += genl.o +obj-y += gw_mode.o +obj-y += hash.o +obj-y += icmp_helper.o +obj-y += interface.o +obj-y += isolation_mark.o +obj-y += loglevel.o +obj-y += log.o +obj-y += main.o +obj-y += mcast_flags.o +obj-y += multicast_mode.o +obj-y += nc_nodes.o +obj-y += neighbors.o +obj-y += netlink.o +obj-y += network_coding.o +obj-y += ping.o +obj-y += originators.o +obj-y += orig_interval.o +obj-y += routing_algo.o +obj-y += statistics.o +obj-y += sys.o +obj-y += tcpdump.o +obj-y += throughputmeter.o +obj-y += traceroute.o +obj-y += transglobal.o +obj-y += translate.o +obj-y += translocal.o
MANPAGE = man/batctl.8
@@ -150,11 +146,11 @@ all: $(BINARY_NAME) .c.o: $(COMPILE.c) -o $@ $<
-$(BINARY_NAME): $(OBJ) +$(BINARY_NAME): $(obj-y) $(LINK.o) $^ $(LDLIBS) -o $@
clean: - $(RM) $(BINARY_NAME) $(OBJ) $(OBJ_BISECT) $(DEP) + $(RM) $(BINARY_NAME) $(obj-y) $(obj-n) $(DEP)
install: $(BINARY_NAME) $(MKDIR) $(DESTDIR)$(SBINDIR) @@ -163,7 +159,7 @@ install: $(BINARY_NAME) $(INSTALL) -m 0644 $(MANPAGE) $(DESTDIR)$(MANDIR)/man8
# load dependencies -DEP = $(OBJ:.o=.d) $(OBJ_BISECT:.o=.d) +DEP = $(obj-y:.o=.d) $(obj-n:.o=.d) -include $(DEP)
.PHONY: all clean install
Systems with limited space are usually not using all the functionality of batman-adv and of batctl. Still, most of the batctl is still build even when the corresponding batman-adv functionality would not be available. This becomes especially important for subcommands which implement most functionality in userspace when it was previously completely handled by the kernel.
An external build system for such system can now just select the commands it really needs. Combining this with link-time-optimizationa and/or function/data-section garbage collection allows to find the right mix between size and functionality.
Signed-off-by: Sven Eckelmann sven@narfation.org --- Makefile | 83 +++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 48 insertions(+), 35 deletions(-)
diff --git a/Makefile b/Makefile index dfcfbd9..e6b2412 100755 --- a/Makefile +++ b/Makefile @@ -20,56 +20,69 @@ # # License-Filename: LICENSES/preferred/GPL-2.0
-# changing the CONFIG_* line to 'y' enables the related feature -# batctl advanced debugging tool bisect: +# just for backward compatibility - please use CONFIG_bisect_iv instead export CONFIG_BATCTL_BISECT=n
# batctl build BINARY_NAME = batctl
-obj-y += aggregation.o -obj-y += ap_isolation.o obj-y += bat-hosts.o -obj-y += backbonetable.o -obj-$(CONFIG_BATCTL_BISECT) += bisect_iv.o -obj-y += bonding.o -obj-y += bridge_loop_avoidance.o -obj-y += claimtable.o -obj-y += dat_cache.o obj-y += debugfs.o obj-y += debug.o -obj-y += distributed_arp_table.o -obj-y += event.o -obj-y += fragmentation.o obj-y += functions.o -obj-y += gateways.o obj-y += genl.o -obj-y += gw_mode.o obj-y += hash.o obj-y += icmp_helper.o -obj-y += interface.o -obj-y += isolation_mark.o -obj-y += loglevel.o -obj-y += log.o obj-y += main.o -obj-y += mcast_flags.o -obj-y += multicast_mode.o -obj-y += nc_nodes.o -obj-y += neighbors.o obj-y += netlink.o -obj-y += network_coding.o -obj-y += ping.o -obj-y += originators.o -obj-y += orig_interval.o -obj-y += routing_algo.o -obj-y += statistics.o obj-y += sys.o -obj-y += tcpdump.o -obj-y += throughputmeter.o -obj-y += traceroute.o -obj-y += transglobal.o -obj-y += translate.o -obj-y += translocal.o + +define add_command + CONFIG_$(1):=$(2) + ifneq ($$(CONFIG_$(1)),y) + ifneq ($$(CONFIG_$(1)),n) + $$(warning invalid value for parameter CONFIG_$(1): $$(CONFIG_$(1))) + endif + endif + + obj-$$(CONFIG_$(1)) += $(1).o +endef # add_command + +# using the make parameter CONFIG_* (e.g. CONFIG_bisect_iv) with the value 'y' +# enables the related feature and 'n' disables it +$(eval $(call add_command,aggregation,y)) +$(eval $(call add_command,ap_isolation,y)) +$(eval $(call add_command,backbonetable,y)) +$(eval $(call add_command,bisect_iv,$(CONFIG_BATCTL_BISECT))) +$(eval $(call add_command,bonding,y)) +$(eval $(call add_command,bridge_loop_avoidance,y)) +$(eval $(call add_command,claimtable,y)) +$(eval $(call add_command,dat_cache,y)) +$(eval $(call add_command,distributed_arp_table,y)) +$(eval $(call add_command,event,y)) +$(eval $(call add_command,fragmentation,y)) +$(eval $(call add_command,gateways,y)) +$(eval $(call add_command,gw_mode,y)) +$(eval $(call add_command,interface,y)) +$(eval $(call add_command,isolation_mark,y)) +$(eval $(call add_command,log,y)) +$(eval $(call add_command,loglevel,y)) +$(eval $(call add_command,mcast_flags,y)) +$(eval $(call add_command,multicast_mode,y)) +$(eval $(call add_command,nc_nodes,y)) +$(eval $(call add_command,neighbors,y)) +$(eval $(call add_command,network_coding,y)) +$(eval $(call add_command,orig_interval,y)) +$(eval $(call add_command,originators,y)) +$(eval $(call add_command,ping,y)) +$(eval $(call add_command,routing_algo,y)) +$(eval $(call add_command,statistics,y)) +$(eval $(call add_command,tcpdump,y)) +$(eval $(call add_command,throughputmeter,y)) +$(eval $(call add_command,traceroute,y)) +$(eval $(call add_command,transglobal,y)) +$(eval $(call add_command,translate,y)) +$(eval $(call add_command,translocal,y))
MANPAGE = man/batctl.8
On Donnerstag, 25. Oktober 2018 18:22:03 CET Sven Eckelmann wrote:
the batctl command already has support to get (previously debugfs) tables via netlink. It does this while still being able to fall back to the old debugfs tables on kernels which don't support the new generic netlink family.
Something similar should be done in the future for the settings which are currently part of sysfs. But we can already see that the current integration of netlink in batctl only done in a single file - netlink.c But this file is already starting to be so big that working with it is rather cumbersome.
So as first steps:
- restructure command registration
- move commands in separate files (which should store their actual implementation)
- add a new helper command to receive multicast group messages from the kernel
Added as 0a201c2..2f5dbd0 [1]
Kind regards, Sven
[1] https://git.open-mesh.org/batctl.git/log/2f5dbd056b8be344b5492835b0924f6cf46...
b.a.t.m.a.n@lists.open-mesh.org