This patchset adds netlink support for dumping DAT cache and multicast flags tables.
Changes in v2: ==============
- Added missing includes, "#include <linux/netlink.h>" and "#include <uapi/linux/batman_adv.h>", to distributed-arp-table.c - Added missing forward declaration for "struct netlink_callback" to distributed-arp-table.h - Changed nla_put_u32() to nla_put_in_addr() for BATADV_ATTR_DC_ADDRESS, removed the then obsolete ntohl() conversion - Added missing include, "#include <linux/netlink.h>", to multicast.c - Changed nla_put_u8() to nla_put_u32() for BATADV_ATTR_MCAST_FLAGS and BATADV_ATTR_MCAST_FLAGS_PRIV to enhance extensibility
Dump the list of DAT cache entries via the netlink socket.
Signed-off-by: Linus Lüssing linus.luessing@c0d3.blue --- compat-include/net/netlink.h | 51 +++++++++++ include/uapi/linux/batman_adv.h | 20 +++++ net/batman-adv/distributed-arp-table.c | 151 +++++++++++++++++++++++++++++++++ net/batman-adv/distributed-arp-table.h | 8 ++ net/batman-adv/netlink.c | 10 +++ 5 files changed, 240 insertions(+) create mode 100644 compat-include/net/netlink.h
diff --git a/compat-include/net/netlink.h b/compat-include/net/netlink.h new file mode 100644 index 00000000..d43576e2 --- /dev/null +++ b/compat-include/net/netlink.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (C) 2007-2018 B.A.T.M.A.N. contributors: + * + * Marek Lindner, Simon Wunderlich + * + * 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, see http://www.gnu.org/licenses/. + * + * This file contains macros for maintaining compatibility with older versions + * of the Linux kernel. + */ + +#ifndef _NET_BATMAN_ADV_COMPAT_NET_NETLINK_H_ +#define _NET_BATMAN_ADV_COMPAT_NET_NETLINK_H_ + +#include <linux/version.h> +#include_next <net/netlink.h> + +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 5, 0) + +static inline int nla_put_be32(struct sk_buff *skb, int attrtype, __be32 value) +{ + __be32 tmp = value; + + return nla_put(skb, attrtype, sizeof(__be32), &tmp); +} + +#endif /* < KERNEL_VERSION(3, 5, 0) */ + +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 1, 0) + +static inline int nla_put_in_addr(struct sk_buff *skb, int attrtype, + __be32 addr) +{ + __be32 tmp = addr; + + return nla_put_be32(skb, attrtype, tmp); +} + +#endif /* < KERNEL_VERSION(4, 1, 0) */ + +#endif /* _NET_BATMAN_ADV_COMPAT_NET_NETLINK_H_ */ diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h index 56ae2893..85c9fe8a 100644 --- a/include/uapi/linux/batman_adv.h +++ b/include/uapi/linux/batman_adv.h @@ -272,6 +272,21 @@ enum batadv_nl_attrs { */ BATADV_ATTR_BLA_CRC,
+ /** + * @BATADV_ATTR_DC_ADDRESS: Client IPv4 address + */ + BATADV_ATTR_DC_ADDRESS, + + /** + * @BATADV_ATTR_DC_HWADDRESS: Client MAC address + */ + BATADV_ATTR_DC_HWADDRESS, + + /** + * @BATADV_ATTR_DC_VID: VLAN ID + */ + BATADV_ATTR_DC_VID, + /* add attributes above here, update the policy in netlink.c */
/** @@ -361,6 +376,11 @@ enum batadv_nl_commands { */ BATADV_CMD_GET_BLA_BACKBONE,
+ /** + * @BATADV_CMD_GET_DAT_CACHE: Query list of DAT cache entries + */ + BATADV_CMD_GET_DAT_CACHE, + /* add new commands above here */
/** diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c index 19b15de4..0f972dd2 100644 --- a/net/batman-adv/distributed-arp-table.c +++ b/net/batman-adv/distributed-arp-table.c @@ -33,6 +33,7 @@ #include <linux/kernel.h> #include <linux/kref.h> #include <linux/list.h> +#include <linux/netlink.h> #include <linux/rculist.h> #include <linux/rcupdate.h> #include <linux/seq_file.h> @@ -43,13 +44,19 @@ #include <linux/string.h> #include <linux/workqueue.h> #include <net/arp.h> +#include <net/genetlink.h> +#include <net/netlink.h> +#include <net/sock.h> +#include <uapi/linux/batman_adv.h>
#include "bridge_loop_avoidance.h" #include "hard-interface.h" #include "hash.h" #include "log.h" +#include "netlink.h" #include "originator.h" #include "send.h" +#include "soft-interface.h" #include "translation-table.h" #include "tvlv.h"
@@ -852,6 +859,150 @@ int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset) #endif
/** + * batadv_dat_cache_dump_entry() - dump one entry of the DAT cache table to a + * netlink socket + * @msg: buffer for the message + * @portid: netlink port + * @seq: Sequence number of netlink message + * @dat_entry: entry to dump + * + * Return: 0 or error code. + */ +static int +batadv_dat_cache_dump_entry(struct sk_buff *msg, u32 portid, u32 seq, + struct batadv_dat_entry *dat_entry) +{ + int msecs; + void *hdr; + + hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, + NLM_F_MULTI, BATADV_CMD_GET_DAT_CACHE); + if (!hdr) + return -ENOBUFS; + + msecs = jiffies_to_msecs(jiffies - dat_entry->last_update); + + if (nla_put_in_addr(msg, BATADV_ATTR_DC_ADDRESS, dat_entry->ip) || + nla_put(msg, BATADV_ATTR_DC_HWADDRESS, ETH_ALEN, + dat_entry->mac_addr) || + nla_put_u16(msg, BATADV_ATTR_DC_VID, dat_entry->vid) || + nla_put_u32(msg, BATADV_ATTR_LAST_SEEN_MSECS, msecs)) { + genlmsg_cancel(msg, hdr); + return -EMSGSIZE; + } + + genlmsg_end(msg, hdr); + return 0; +} + +/** + * batadv_dat_cache_dump_bucket() - dump one bucket of the DAT cache table to + * a netlink socket + * @msg: buffer for the message + * @portid: netlink port + * @seq: Sequence number of netlink message + * @head: bucket to dump + * @idx_skip: How many entries to skip + * + * Return: 0 or error code. + */ +static int +batadv_dat_cache_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq, + struct hlist_head *head, int *idx_skip) +{ + struct batadv_dat_entry *dat_entry; + int idx = 0; + + rcu_read_lock(); + hlist_for_each_entry_rcu(dat_entry, head, hash_entry) { + if (idx < *idx_skip) + goto skip; + + if (batadv_dat_cache_dump_entry(msg, portid, seq, + dat_entry)) { + rcu_read_unlock(); + *idx_skip = idx; + + return -EMSGSIZE; + } + +skip: + idx++; + } + rcu_read_unlock(); + + return 0; +} + +/** + * batadv_dat_cache_dump() - dump DAT cache table to a netlink socket + * @msg: buffer for the message + * @cb: callback structure containing arguments + * + * Return: message length. + */ +int batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb) +{ + struct batadv_hard_iface *primary_if = NULL; + int portid = NETLINK_CB(cb->skb).portid; + struct net *net = sock_net(cb->skb->sk); + struct net_device *soft_iface; + struct batadv_hashtable *hash; + struct batadv_priv *bat_priv; + int bucket = cb->args[0]; + struct hlist_head *head; + int idx = cb->args[1]; + int ifindex; + int ret = 0; + + ifindex = batadv_netlink_get_ifindex(cb->nlh, + BATADV_ATTR_MESH_IFINDEX); + if (!ifindex) + return -EINVAL; + + soft_iface = dev_get_by_index(net, ifindex); + if (!soft_iface || !batadv_softif_is_valid(soft_iface)) { + ret = -ENODEV; + goto out; + } + + bat_priv = netdev_priv(soft_iface); + hash = bat_priv->dat.hash; + + primary_if = batadv_primary_if_get_selected(bat_priv); + if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) { + ret = -ENOENT; + goto out; + } + + while (bucket < hash->size) { + head = &hash->table[bucket]; + + if (batadv_dat_cache_dump_bucket(msg, portid, + cb->nlh->nlmsg_seq, head, + &idx)) + break; + + bucket++; + idx = 0; + } + + cb->args[0] = bucket; + cb->args[1] = idx; + + ret = msg->len; + +out: + if (primary_if) + batadv_hardif_put(primary_if); + + if (soft_iface) + dev_put(soft_iface); + + return ret; +} + +/** * batadv_arp_get_type() - parse an ARP packet and gets the type * @bat_priv: the bat priv with all the soft interface information * @skb: packet to analyse diff --git a/net/batman-adv/distributed-arp-table.h b/net/batman-adv/distributed-arp-table.h index e24aa960..a0459602 100644 --- a/net/batman-adv/distributed-arp-table.h +++ b/net/batman-adv/distributed-arp-table.h @@ -28,6 +28,7 @@
#include "originator.h"
+struct netlink_callback; struct seq_file; struct sk_buff;
@@ -81,6 +82,7 @@ batadv_dat_init_own_addr(struct batadv_priv *bat_priv, int batadv_dat_init(struct batadv_priv *bat_priv); void batadv_dat_free(struct batadv_priv *bat_priv); int batadv_dat_cache_seq_print_text(struct seq_file *seq, void *offset); +int batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb);
/** * batadv_dat_inc_counter() - increment the correct DAT packet counter @@ -169,6 +171,12 @@ static inline void batadv_dat_free(struct batadv_priv *bat_priv) { }
+static inline int +batadv_dat_cache_dump(struct sk_buff *msg, struct netlink_callback *cb) +{ + return -EOPNOTSUPP; +} + static inline void batadv_dat_inc_counter(struct batadv_priv *bat_priv, u8 subtype) { diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c index 129af56b..7812b531 100644 --- a/net/batman-adv/netlink.c +++ b/net/batman-adv/netlink.c @@ -45,6 +45,7 @@
#include "bat_algo.h" #include "bridge_loop_avoidance.h" +#include "distributed-arp-table.h" #include "gateway_client.h" #include "hard-interface.h" #include "originator.h" @@ -97,6 +98,9 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = { [BATADV_ATTR_BLA_VID] = { .type = NLA_U16 }, [BATADV_ATTR_BLA_BACKBONE] = { .len = ETH_ALEN }, [BATADV_ATTR_BLA_CRC] = { .type = NLA_U16 }, + [BATADV_ATTR_DC_ADDRESS] = { .type = NLA_U32 }, + [BATADV_ATTR_DC_HWADDRESS] = { .len = ETH_ALEN }, + [BATADV_ATTR_DC_VID] = { .type = NLA_U16 }, };
/** @@ -604,6 +608,12 @@ static const struct genl_ops batadv_netlink_ops[] = { .policy = batadv_netlink_policy, .dumpit = batadv_bla_backbone_dump, }, + { + .cmd = BATADV_CMD_GET_DAT_CACHE, + .flags = GENL_ADMIN_PERM, + .policy = batadv_netlink_policy, + .dumpit = batadv_dat_cache_dump, + },
};
Dump the list of multicast flags entries via the netlink socket.
Signed-off-by: Linus Lüssing linus.luessing@c0d3.blue --- include/uapi/linux/batman_adv.h | 62 +++++++++++ net/batman-adv/multicast.c | 237 ++++++++++++++++++++++++++++++++++++++++ net/batman-adv/multicast.h | 18 +++ net/batman-adv/netlink.c | 12 ++ 4 files changed, 329 insertions(+)
diff --git a/include/uapi/linux/batman_adv.h b/include/uapi/linux/batman_adv.h index 85c9fe8a..d17ea7ae 100644 --- a/include/uapi/linux/batman_adv.h +++ b/include/uapi/linux/batman_adv.h @@ -92,6 +92,53 @@ enum batadv_tt_client_flags { };
/** + * enum batadv_mcast_flags_priv - Private, own multicast flags + * + * These are internal, multicast related flags. Currently they describe certain + * multicast related attributes of the segment this originator bridges into the + * mesh. + * + * Those attributes are used to determine the public multicast flags this + * originator is going to announce via TT. + * + * For netlink, if BATADV_MCAST_FLAGS_BRIDGED is unset then all querier + * related flags are undefined. + */ +enum batadv_mcast_flags_priv { + /** + * @BATADV_MCAST_FLAGS_BRIDGED: There is a bridge on top of the mesh + * interface. + */ + BATADV_MCAST_FLAGS_BRIDGED = (1 << 0), + + /** + * @BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS: Whether an IGMP querier + * exists in the mesh + */ + BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS = (1 << 1), + + /** + * @BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS: Whether an MLD querier + * exists in the mesh + */ + BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS = (1 << 2), + + /** + * @BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING: If an IGMP querier + * exists, whether it is potentially shadowing multicast listeners + * (i.e. querier is behind our own bridge segment) + */ + BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING = (1 << 3), + + /** + * @BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING: If an MLD querier + * exists, whether it is potentially shadowing multicast listeners + * (i.e. querier is behind our own bridge segment) + */ + BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING = (1 << 4), +}; + +/** * enum batadv_nl_attrs - batman-adv netlink attributes */ enum batadv_nl_attrs { @@ -287,6 +334,16 @@ enum batadv_nl_attrs { */ BATADV_ATTR_DC_VID,
+ /** + * @BATADV_ATTR_MCAST_FLAGS: Per originator multicast flags + */ + BATADV_ATTR_MCAST_FLAGS, + + /** + * @BATADV_ATTR_MCAST_FLAGS_PRIV: Private, own multicast flags + */ + BATADV_ATTR_MCAST_FLAGS_PRIV, + /* add attributes above here, update the policy in netlink.c */
/** @@ -381,6 +438,11 @@ enum batadv_nl_commands { */ BATADV_CMD_GET_DAT_CACHE,
+ /** + * @BATADV_CMD_GET_MCAST_FLAGS: Query list of multicast flags + */ + BATADV_CMD_GET_MCAST_FLAGS, + /* add new commands above here */
/** diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c index 6eaffe50..9a1182ae 100644 --- a/net/batman-adv/multicast.c +++ b/net/batman-adv/multicast.c @@ -40,6 +40,7 @@ #include <linux/list.h> #include <linux/lockdep.h> #include <linux/netdevice.h> +#include <linux/netlink.h> #include <linux/printk.h> #include <linux/rculist.h> #include <linux/rcupdate.h> @@ -52,14 +53,20 @@ #include <linux/types.h> #include <linux/workqueue.h> #include <net/addrconf.h> +#include <net/genetlink.h> #include <net/if_inet6.h> #include <net/ip.h> #include <net/ipv6.h> +#include <net/netlink.h> +#include <net/sock.h> #include <uapi/linux/batadv_packet.h> +#include <uapi/linux/batman_adv.h>
#include "hard-interface.h" #include "hash.h" #include "log.h" +#include "netlink.h" +#include "soft-interface.h" #include "translation-table.h" #include "tvlv.h"
@@ -1286,6 +1293,236 @@ int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset) #endif
/** + * batadv_mcast_mesh_info_put() - put multicast info into a netlink message + * @msg: buffer for the message + * @bat_priv: the bat priv with all the soft interface information + * + * Return: 0 or error code. + */ +int batadv_mcast_mesh_info_put(struct sk_buff *msg, + struct batadv_priv *bat_priv) +{ + u32 flags = bat_priv->mcast.flags; + u32 flags_priv = BATADV_NO_FLAGS; + + if (bat_priv->mcast.bridged) { + flags_priv |= BATADV_MCAST_FLAGS_BRIDGED; + + if (bat_priv->mcast.querier_ipv4.exists) + flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_EXISTS; + if (bat_priv->mcast.querier_ipv6.exists) + flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_EXISTS; + if (bat_priv->mcast.querier_ipv4.shadowing) + flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV4_SHADOWING; + if (bat_priv->mcast.querier_ipv6.shadowing) + flags_priv |= BATADV_MCAST_FLAGS_QUERIER_IPV6_SHADOWING; + } + + if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS, flags) || + nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS_PRIV, flags_priv)) + return -EMSGSIZE; + + return 0; +} + +/** + * batadv_mcast_flags_dump_entry() - dump one entry of the multicast flags table + * to a netlink socket + * @msg: buffer for the message + * @portid: netlink port + * @seq: Sequence number of netlink message + * @orig_node: originator to dump the multicast flags of + * + * Return: 0 or error code. + */ +static int +batadv_mcast_flags_dump_entry(struct sk_buff *msg, u32 portid, u32 seq, + struct batadv_orig_node *orig_node) +{ + void *hdr; + + hdr = genlmsg_put(msg, portid, seq, &batadv_netlink_family, + NLM_F_MULTI, BATADV_CMD_GET_MCAST_FLAGS); + if (!hdr) + return -ENOBUFS; + + if (nla_put(msg, BATADV_ATTR_ORIG_ADDRESS, ETH_ALEN, + orig_node->orig)) { + genlmsg_cancel(msg, hdr); + return -EMSGSIZE; + } + + if (test_bit(BATADV_ORIG_CAPA_HAS_MCAST, + &orig_node->capabilities)) { + if (nla_put_u32(msg, BATADV_ATTR_MCAST_FLAGS, + orig_node->mcast_flags)) { + genlmsg_cancel(msg, hdr); + return -EMSGSIZE; + } + } + + genlmsg_end(msg, hdr); + return 0; +} + +/** + * batadv_mcast_flags_dump_bucket() - dump one bucket of the multicast flags + * table to a netlink socket + * @msg: buffer for the message + * @portid: netlink port + * @seq: Sequence number of netlink message + * @head: bucket to dump + * @idx_skip: How many entries to skip + * + * Return: 0 or error code. + */ +static int +batadv_mcast_flags_dump_bucket(struct sk_buff *msg, u32 portid, u32 seq, + struct hlist_head *head, long *idx_skip) +{ + struct batadv_orig_node *orig_node; + long idx = 0; + + rcu_read_lock(); + hlist_for_each_entry_rcu(orig_node, head, hash_entry) { + if (!test_bit(BATADV_ORIG_CAPA_HAS_MCAST, + &orig_node->capa_initialized)) + continue; + + if (idx < *idx_skip) + goto skip; + + if (batadv_mcast_flags_dump_entry(msg, portid, seq, + orig_node)) { + rcu_read_unlock(); + *idx_skip = idx; + + return -EMSGSIZE; + } + +skip: + idx++; + } + rcu_read_unlock(); + + return 0; +} + +/** + * __batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket + * @msg: buffer for the message + * @portid: netlink port + * @seq: Sequence number of netlink message + * @bat_priv: the bat priv with all the soft interface information + * @bucket: current bucket to dump + * @idx: index in current bucket to the next entry to dump + * + * Return: 0 or error code. + */ +static int +__batadv_mcast_flags_dump(struct sk_buff *msg, u32 portid, u32 seq, + struct batadv_priv *bat_priv, long *bucket, long *idx) +{ + struct batadv_hashtable *hash = bat_priv->orig_hash; + long bucket_tmp = *bucket; + struct hlist_head *head; + long idx_tmp = *idx; + + while (bucket_tmp < hash->size) { + head = &hash->table[bucket_tmp]; + + if (batadv_mcast_flags_dump_bucket(msg, portid, seq, head, + &idx_tmp)) + break; + + bucket_tmp++; + idx_tmp = 0; + } + + *bucket = bucket_tmp; + *idx = idx_tmp; + + return msg->len; +} + +/** + * batadv_mcast_netlink_get_primary() - get primary interface from netlink + * callback + * @cb: netlink callback structure + * @primary_if: the primary interface pointer to return the result in + * + * Return: 0 or error code. + */ +static int +batadv_mcast_netlink_get_primary(struct netlink_callback *cb, + struct batadv_hard_iface **primary_if) +{ + struct batadv_hard_iface *hard_iface = NULL; + struct net *net = sock_net(cb->skb->sk); + struct net_device *soft_iface; + struct batadv_priv *bat_priv; + int ifindex; + int ret = 0; + + ifindex = batadv_netlink_get_ifindex(cb->nlh, BATADV_ATTR_MESH_IFINDEX); + if (!ifindex) + return -EINVAL; + + soft_iface = dev_get_by_index(net, ifindex); + if (!soft_iface || !batadv_softif_is_valid(soft_iface)) { + ret = -ENODEV; + goto out; + } + + bat_priv = netdev_priv(soft_iface); + + hard_iface = batadv_primary_if_get_selected(bat_priv); + if (!hard_iface || hard_iface->if_status != BATADV_IF_ACTIVE) { + ret = -ENOENT; + goto out; + } + +out: + if (soft_iface) + dev_put(soft_iface); + + if (!ret && primary_if) + *primary_if = hard_iface; + else + batadv_hardif_put(hard_iface); + + return ret; +} + +/** + * batadv_mcast_flags_dump() - dump multicast flags table to a netlink socket + * @msg: buffer for the message + * @cb: callback structure containing arguments + * + * Return: message length. + */ +int batadv_mcast_flags_dump(struct sk_buff *msg, struct netlink_callback *cb) +{ + struct batadv_hard_iface *primary_if = NULL; + int portid = NETLINK_CB(cb->skb).portid; + struct batadv_priv *bat_priv; + long *bucket = &cb->args[0]; + long *idx = &cb->args[1]; + int ret; + + ret = batadv_mcast_netlink_get_primary(cb, &primary_if); + if (ret) + return ret; + + bat_priv = netdev_priv(primary_if->soft_iface); + ret = __batadv_mcast_flags_dump(msg, portid, cb->nlh->nlmsg_seq, + bat_priv, bucket, idx); + + batadv_hardif_put(primary_if); + return ret; +} + +/** * batadv_mcast_free() - free the multicast optimizations structures * @bat_priv: the bat priv with all the soft interface information */ diff --git a/net/batman-adv/multicast.h b/net/batman-adv/multicast.h index 6b8594e2..3b04ab13 100644 --- a/net/batman-adv/multicast.h +++ b/net/batman-adv/multicast.h @@ -21,6 +21,7 @@
#include "main.h"
+struct netlink_callback; struct seq_file; struct sk_buff;
@@ -54,6 +55,11 @@ void batadv_mcast_init(struct batadv_priv *bat_priv);
int batadv_mcast_flags_seq_print_text(struct seq_file *seq, void *offset);
+int batadv_mcast_mesh_info_put(struct sk_buff *msg, + struct batadv_priv *bat_priv); + +int batadv_mcast_flags_dump(struct sk_buff *msg, struct netlink_callback *cb); + void batadv_mcast_free(struct batadv_priv *bat_priv);
void batadv_mcast_purge_orig(struct batadv_orig_node *orig_node); @@ -72,6 +78,18 @@ static inline int batadv_mcast_init(struct batadv_priv *bat_priv) return 0; }
+static inline int +batadv_mcast_mesh_info_put(struct sk_buff *msg, struct batadv_priv *bat_priv) +{ + return 0; +} + +static inline int batadv_mcast_flags_dump(struct sk_buff *msg, + struct netlink_callback *cb) +{ + return -EOPNOTSUPP; +} + static inline void batadv_mcast_free(struct batadv_priv *bat_priv) { } diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c index 7812b531..4ea33c22 100644 --- a/net/batman-adv/netlink.c +++ b/net/batman-adv/netlink.c @@ -48,6 +48,7 @@ #include "distributed-arp-table.h" #include "gateway_client.h" #include "hard-interface.h" +#include "multicast.h" #include "originator.h" #include "soft-interface.h" #include "tp_meter.h" @@ -101,6 +102,8 @@ static const struct nla_policy batadv_netlink_policy[NUM_BATADV_ATTR] = { [BATADV_ATTR_DC_ADDRESS] = { .type = NLA_U32 }, [BATADV_ATTR_DC_HWADDRESS] = { .len = ETH_ALEN }, [BATADV_ATTR_DC_VID] = { .type = NLA_U16 }, + [BATADV_ATTR_MCAST_FLAGS] = { .type = NLA_U32 }, + [BATADV_ATTR_MCAST_FLAGS_PRIV] = { .type = NLA_U32 }, };
/** @@ -151,6 +154,9 @@ batadv_netlink_mesh_info_put(struct sk_buff *msg, struct net_device *soft_iface) goto out; #endif
+ if (batadv_mcast_mesh_info_put(msg, bat_priv)) + goto out; + primary_if = batadv_primary_if_get_selected(bat_priv); if (primary_if && primary_if->if_status == BATADV_IF_ACTIVE) { hard_iface = primary_if->net_dev; @@ -614,6 +620,12 @@ static const struct genl_ops batadv_netlink_ops[] = { .policy = batadv_netlink_policy, .dumpit = batadv_dat_cache_dump, }, + { + .cmd = BATADV_CMD_GET_MCAST_FLAGS, + .flags = GENL_ADMIN_PERM, + .policy = batadv_netlink_policy, + .dumpit = batadv_mcast_flags_dump, + },
};
On Sonntag, 11. März 2018 00:53:19 CET Linus Lüssing wrote:
This patchset adds netlink support for dumping DAT cache and multicast flags tables.
Changes in v2:
- Added missing includes, "#include <linux/netlink.h>" and "#include <uapi/linux/batman_adv.h>", to distributed-arp-table.c
- Added missing forward declaration for "struct netlink_callback" to distributed-arp-table.h
- Changed nla_put_u32() to nla_put_in_addr() for BATADV_ATTR_DC_ADDRESS, removed the then obsolete ntohl() conversion
- Added missing include, "#include <linux/netlink.h>", to multicast.c
- Changed nla_put_u8() to nla_put_u32() for BATADV_ATTR_MCAST_FLAGS and BATADV_ATTR_MCAST_FLAGS_PRIV to enhance extensibility
Thanks for the doing the requested changes.
@Antonio: Can you please check whether you are ok with the new netlink names and types.
[BATADV_ATTR_DC_ADDRESS] = { .type = NLA_U32 },
[BATADV_ATTR_DC_HWADDRESS] = { .len = ETH_ALEN },
[BATADV_ATTR_DC_VID] = { .type = NLA_U16 },
Kind regards, Sven
On 11/03/18 18:54, Sven Eckelmann wrote:
On Sonntag, 11. März 2018 00:53:19 CET Linus Lüssing wrote:
This patchset adds netlink support for dumping DAT cache and multicast flags tables.
Changes in v2:
- Added missing includes, "#include <linux/netlink.h>" and "#include <uapi/linux/batman_adv.h>", to distributed-arp-table.c
- Added missing forward declaration for "struct netlink_callback" to distributed-arp-table.h
- Changed nla_put_u32() to nla_put_in_addr() for BATADV_ATTR_DC_ADDRESS, removed the then obsolete ntohl() conversion
- Added missing include, "#include <linux/netlink.h>", to multicast.c
- Changed nla_put_u8() to nla_put_u32() for BATADV_ATTR_MCAST_FLAGS and BATADV_ATTR_MCAST_FLAGS_PRIV to enhance extensibility
Thanks for the doing the requested changes.
@Antonio: Can you please check whether you are ok with the new netlink names and types.
[BATADV_ATTR_DC_ADDRESS] = { .type = NLA_U32 },
[BATADV_ATTR_DC_HWADDRESS] = { .len = ETH_ALEN },
[BATADV_ATTR_DC_VID] = { .type = NLA_U16 },
Personally I'd find "DAT_CACHE" easier to parse than "DC". I know we have the "batctl dc" command, but that's more to keep the CLI compact.
This said, DAT was meant to be extended in the future and not store only IPv4 addresses. This said, shouldn't we use a more specific name for the address?
Another observation: do these attributes need to be DAT specific? or can we just define (or reuse) a generic HWADDRESS attribute that we might already be using somewhere else (i.e. for TT)?
Regards,
On Dienstag, 13. März 2018 16:02:34 CET Antonio Quartulli wrote: [...]
Another observation: do these attributes need to be DAT specific? or can we just define (or reuse) a generic HWADDRESS attribute that we might already be using somewhere else (i.e. for TT)?
I've asked myself the same but we have BLA_- and TT_ADDRESS and these are named in a way which connects them to these specific subsystems. Using one of them for DAT seems to be a little bit odd.
Kind regards, Sven
On 13/03/18 16:20, Sven Eckelmann wrote:
On Dienstag, 13. März 2018 16:02:34 CET Antonio Quartulli wrote: [...]
Another observation: do these attributes need to be DAT specific? or can we just define (or reuse) a generic HWADDRESS attribute that we might already be using somewhere else (i.e. for TT)?
I've asked myself the same but we have BLA_- and TT_ADDRESS and these are named in a way which connects them to these specific subsystems. Using one of them for DAT seems to be a little bit odd.
Oh ok. In this case it makes sense to have DAT specific attrs.
(if we wanted to, we could still rename all the attrs pointing to the very same data type and unify them, but I don't have a strong opinion about it at this time).
Cheers,
On Dienstag, 13. März 2018 16:22:24 CET Antonio Quartulli wrote: [...]
(if we wanted to, we could still rename all the attrs pointing to the very same data type and unify them, but I don't have a strong opinion about it at this time).
This would break backwards compatibility.
Kind regards, Sven
On 13/03/18 16:52, Sven Eckelmann wrote:
On Dienstag, 13. März 2018 16:22:24 CET Antonio Quartulli wrote: [...]
(if we wanted to, we could still rename all the attrs pointing to the very same data type and unify them, but I don't have a strong opinion about it at this time).
This would break backwards compatibility.
Ah right, those names are exported to user space too with the same header file.
We'll live with that then.
Cheers,
b.a.t.m.a.n@lists.open-mesh.org