@@ -22,6 +22,7 @@
#include <errno.h>
#include <getopt.h>
+#include <net/if.h>
#include <netinet/if_ether.h>
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
@@ -87,6 +88,25 @@ static int event_prepare(struct state *state)
skip_tp_meter:
+ mcid = nl_get_multicast_id(state->sock, BATADV_NL_NAME,
+ BATADV_NL_MCAST_GROUP_CONFIG);
+ if (mcid < 0) {
+ fprintf(stderr, "Failed to resolve batadv config multicast group: %d\n",
+ mcid);
+ /* ignore error for now */
+ goto skip_config;
+ }
+
+ ret = nl_socket_add_membership(state->sock, mcid);
+ if (ret) {
+ fprintf(stderr, "Failed to join batadv config multicast group: %d\n",
+ ret);
+ /* ignore error for now */
+ goto skip_config;
+ }
+
+skip_config:
+
return 0;
}
@@ -145,6 +165,81 @@ static void event_parse_tp_meter(struct nlattr **attrs)
printf("tp_meter 0x%08x: %s\n", cookie, result_str);
}
+static const int option_mandatory[] = {
+ BATADV_ATTR_MESH_IFINDEX,
+ BATADV_ATTR_OPTION_NAME,
+ BATADV_ATTR_OPTION_TYPE,
+ /* BATADV_ATTR_OPTION_VALUE, */
+};
+
+static void event_parse_option(struct nlattr **attrs)
+{
+ char meshif_buf[IF_NAMESIZE];
+ char hardif_buf[IF_NAMESIZE];
+ char extra_info[256];
+ char *meshif_name;
+ char *hardif_name;
+ uint32_t hardif_ifindex;
+ uint32_t mesh_ifindex;
+ const char *name;
+ uint16_t vid;
+ uint8_t type;
+
+ /* ignore entry when attributes are missing */
+ if (missing_mandatory_attrs(attrs, option_mandatory,
+ ARRAY_SIZE(option_mandatory)))
+ return;
+
+ mesh_ifindex = nla_get_u32(attrs[BATADV_ATTR_MESH_IFINDEX]);
+ meshif_name = if_indextoname(mesh_ifindex, meshif_buf);
+ if (!meshif_name)
+ return;
+
+ if (attrs[BATADV_ATTR_HARD_IFINDEX]) {
+ hardif_ifindex = nla_get_u32(attrs[BATADV_ATTR_HARD_IFINDEX]);
+ hardif_name = if_indextoname(hardif_ifindex, hardif_buf);
+ if (!hardif_name)
+ return;
+
+ snprintf(extra_info, sizeof(extra_info), " (%s)", hardif_name);
+ } else if (attrs[BATADV_ATTR_VLANID]) {
+ vid = nla_get_u16(attrs[BATADV_ATTR_VLANID]);
+
+ snprintf(extra_info, sizeof(extra_info), " (vid %u)", vid);
+ } else {
+ extra_info[0] = '\0';
+ }
+
+ name = nla_get_string(attrs[BATADV_ATTR_OPTION_NAME]);
+ type = nla_get_u8(attrs[BATADV_ATTR_OPTION_TYPE]);
+
+ if (type != NLA_FLAG && !attrs[BATADV_ATTR_OPTION_VALUE])
+ return;
+
+ switch (type) {
+ case NLA_U8:
+ printf("%s%s: %s u8 %u\n", meshif_name, extra_info, name,
+ nla_get_u8(attrs[BATADV_ATTR_OPTION_VALUE]));
+ break;
+ case NLA_U16:
+ printf("%s%s: %s u16 %u\n", meshif_name, extra_info, name,
+ nla_get_u16(attrs[BATADV_ATTR_OPTION_VALUE]));
+ break;
+ case NLA_U32:
+ printf("%s%s: %s u32 %u\n", meshif_name, extra_info, name,
+ nla_get_u32(attrs[BATADV_ATTR_OPTION_VALUE]));
+ break;
+ case NLA_NUL_STRING:
+ printf("%s%s: %s string %s\n", meshif_name, extra_info, name,
+ nla_get_string(attrs[BATADV_ATTR_OPTION_VALUE]));
+ break;
+ case NLA_FLAG:
+ printf("%s%s: %s bool %s\n", meshif_name, extra_info, name,
+ attrs[BATADV_ATTR_OPTION_VALUE] ? "true" : "false");
+ break;
+ }
+}
+
static unsigned long long get_timestamp(struct event_args *event_args)
{
unsigned long long prevtime = 0;
@@ -190,6 +285,11 @@ static int event_parse(struct nl_msg *msg, void *arg)
case BATADV_CMD_TP_METER:
event_parse_tp_meter(attrs);
break;
+ case BATADV_CMD_SET_OPTION:
+ case BATADV_CMD_SET_OPTION_HARDIF:
+ case BATADV_CMD_SET_OPTION_VLAN:
+ event_parse_option(attrs);
+ break;
default:
printf("Received unknown event %u\n", ghdr->cmd);
break;