@@ -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);
-}
@@ -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
@@ -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 = {
@@ -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 {
@@ -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)
@@ -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;
@@ -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;