batman-adv: netlink: add originator and neighbor table queries
Add BATADV_CMD_GET_ORIGINATORS and BATADV_CMD_GET_NEIGHBORS commands, using handlers bat_orig_dump and bat_neigh_dump in batadv_algo_ops. Will always return -EOPNOTSUPP for now, as no implementations exist yet. Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net> Signed-off-by: Andrew Lunn <andrew@lunn.ch> [sven@narfation.org: Rewrite based on new algo_ops structures] Signed-off-by: Sven Eckelmann <sven@narfation.org> Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de> Signed-off-by: Marek Lindner <mareklindner@neomailbox.ch>
This commit is contained in:
parent
f32ed4b54e
commit
85cf8c859d
|
@ -131,6 +131,8 @@ enum batadv_nl_attrs {
|
||||||
* @BATADV_CMD_GET_HARDIFS: Query list of hard interfaces
|
* @BATADV_CMD_GET_HARDIFS: Query list of hard interfaces
|
||||||
* @BATADV_CMD_GET_TRANSTABLE_LOCAL: Query list of local translations
|
* @BATADV_CMD_GET_TRANSTABLE_LOCAL: Query list of local translations
|
||||||
* @BATADV_CMD_GET_TRANSTABLE_GLOBAL Query list of global translations
|
* @BATADV_CMD_GET_TRANSTABLE_GLOBAL Query list of global translations
|
||||||
|
* @BATADV_CMD_GET_ORIGINATORS: Query list of originators
|
||||||
|
* @BATADV_CMD_GET_NEIGHBORS: Query list of neighbours
|
||||||
* @__BATADV_CMD_AFTER_LAST: internal use
|
* @__BATADV_CMD_AFTER_LAST: internal use
|
||||||
* @BATADV_CMD_MAX: highest used command number
|
* @BATADV_CMD_MAX: highest used command number
|
||||||
*/
|
*/
|
||||||
|
@ -143,6 +145,8 @@ enum batadv_nl_commands {
|
||||||
BATADV_CMD_GET_HARDIFS,
|
BATADV_CMD_GET_HARDIFS,
|
||||||
BATADV_CMD_GET_TRANSTABLE_LOCAL,
|
BATADV_CMD_GET_TRANSTABLE_LOCAL,
|
||||||
BATADV_CMD_GET_TRANSTABLE_GLOBAL,
|
BATADV_CMD_GET_TRANSTABLE_GLOBAL,
|
||||||
|
BATADV_CMD_GET_ORIGINATORS,
|
||||||
|
BATADV_CMD_GET_NEIGHBORS,
|
||||||
/* add new commands above here */
|
/* add new commands above here */
|
||||||
__BATADV_CMD_AFTER_LAST,
|
__BATADV_CMD_AFTER_LAST,
|
||||||
BATADV_CMD_MAX = __BATADV_CMD_AFTER_LAST - 1
|
BATADV_CMD_MAX = __BATADV_CMD_AFTER_LAST - 1
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
|
|
||||||
#include "bat_algo.h"
|
#include "bat_algo.h"
|
||||||
#include "hard-interface.h"
|
#include "hard-interface.h"
|
||||||
|
#include "originator.h"
|
||||||
#include "soft-interface.h"
|
#include "soft-interface.h"
|
||||||
#include "tp_meter.h"
|
#include "tp_meter.h"
|
||||||
#include "translation-table.h"
|
#include "translation-table.h"
|
||||||
|
@ -554,6 +555,18 @@ static struct genl_ops batadv_netlink_ops[] = {
|
||||||
.policy = batadv_netlink_policy,
|
.policy = batadv_netlink_policy,
|
||||||
.dumpit = batadv_tt_global_dump,
|
.dumpit = batadv_tt_global_dump,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_ORIGINATORS,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_orig_dump,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.cmd = BATADV_CMD_GET_NEIGHBORS,
|
||||||
|
.flags = GENL_ADMIN_PERM,
|
||||||
|
.policy = batadv_netlink_policy,
|
||||||
|
.dumpit = batadv_hardif_neigh_dump,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,11 +28,15 @@
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/lockdep.h>
|
#include <linux/lockdep.h>
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
#include <linux/rculist.h>
|
#include <linux/rculist.h>
|
||||||
#include <linux/seq_file.h>
|
#include <linux/seq_file.h>
|
||||||
|
#include <linux/skbuff.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
#include <net/sock.h>
|
||||||
|
#include <uapi/linux/batman_adv.h>
|
||||||
|
|
||||||
#include "bat_algo.h"
|
#include "bat_algo.h"
|
||||||
#include "distributed-arp-table.h"
|
#include "distributed-arp-table.h"
|
||||||
|
@ -42,8 +46,10 @@
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "multicast.h"
|
#include "multicast.h"
|
||||||
|
#include "netlink.h"
|
||||||
#include "network-coding.h"
|
#include "network-coding.h"
|
||||||
#include "routing.h"
|
#include "routing.h"
|
||||||
|
#include "soft-interface.h"
|
||||||
#include "translation-table.h"
|
#include "translation-table.h"
|
||||||
|
|
||||||
/* hash class keys */
|
/* hash class keys */
|
||||||
|
@ -720,6 +726,83 @@ int batadv_hardif_neigh_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_hardif_neigh_dump - Dump to netlink the neighbor infos for a specific
|
||||||
|
* outgoing interface
|
||||||
|
* @msg: message to dump into
|
||||||
|
* @cb: parameters for the dump
|
||||||
|
*
|
||||||
|
* Return: 0 or error value
|
||||||
|
*/
|
||||||
|
int batadv_hardif_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb)
|
||||||
|
{
|
||||||
|
struct net *net = sock_net(cb->skb->sk);
|
||||||
|
struct net_device *soft_iface;
|
||||||
|
struct net_device *hard_iface = NULL;
|
||||||
|
struct batadv_hard_iface *hardif = BATADV_IF_DEFAULT;
|
||||||
|
struct batadv_priv *bat_priv;
|
||||||
|
struct batadv_hard_iface *primary_if = NULL;
|
||||||
|
int ret;
|
||||||
|
int ifindex, hard_ifindex;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
primary_if = batadv_primary_if_get_selected(bat_priv);
|
||||||
|
if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
hard_ifindex = batadv_netlink_get_ifindex(cb->nlh,
|
||||||
|
BATADV_ATTR_HARD_IFINDEX);
|
||||||
|
if (hard_ifindex) {
|
||||||
|
hard_iface = dev_get_by_index(net, hard_ifindex);
|
||||||
|
if (hard_iface)
|
||||||
|
hardif = batadv_hardif_get_by_netdev(hard_iface);
|
||||||
|
|
||||||
|
if (!hardif) {
|
||||||
|
ret = -ENODEV;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hardif->soft_iface != soft_iface) {
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bat_priv->algo_ops->neigh.dump) {
|
||||||
|
ret = -EOPNOTSUPP;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
bat_priv->algo_ops->neigh.dump(msg, cb, bat_priv, hardif);
|
||||||
|
|
||||||
|
ret = msg->len;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (hardif)
|
||||||
|
batadv_hardif_put(hardif);
|
||||||
|
if (hard_iface)
|
||||||
|
dev_put(hard_iface);
|
||||||
|
if (primary_if)
|
||||||
|
batadv_hardif_put(primary_if);
|
||||||
|
if (soft_iface)
|
||||||
|
dev_put(soft_iface);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* batadv_orig_ifinfo_release - release orig_ifinfo from lists and queue for
|
* batadv_orig_ifinfo_release - release orig_ifinfo from lists and queue for
|
||||||
* free after rcu grace period
|
* free after rcu grace period
|
||||||
|
@ -1330,6 +1413,83 @@ int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* batadv_orig_dump - Dump to netlink the originator infos for a specific
|
||||||
|
* outgoing interface
|
||||||
|
* @msg: message to dump into
|
||||||
|
* @cb: parameters for the dump
|
||||||
|
*
|
||||||
|
* Return: 0 or error value
|
||||||
|
*/
|
||||||
|
int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb)
|
||||||
|
{
|
||||||
|
struct net *net = sock_net(cb->skb->sk);
|
||||||
|
struct net_device *soft_iface;
|
||||||
|
struct net_device *hard_iface = NULL;
|
||||||
|
struct batadv_hard_iface *hardif = BATADV_IF_DEFAULT;
|
||||||
|
struct batadv_priv *bat_priv;
|
||||||
|
struct batadv_hard_iface *primary_if = NULL;
|
||||||
|
int ret;
|
||||||
|
int ifindex, hard_ifindex;
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
primary_if = batadv_primary_if_get_selected(bat_priv);
|
||||||
|
if (!primary_if || primary_if->if_status != BATADV_IF_ACTIVE) {
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
hard_ifindex = batadv_netlink_get_ifindex(cb->nlh,
|
||||||
|
BATADV_ATTR_HARD_IFINDEX);
|
||||||
|
if (hard_ifindex) {
|
||||||
|
hard_iface = dev_get_by_index(net, hard_ifindex);
|
||||||
|
if (hard_iface)
|
||||||
|
hardif = batadv_hardif_get_by_netdev(hard_iface);
|
||||||
|
|
||||||
|
if (!hardif) {
|
||||||
|
ret = -ENODEV;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hardif->soft_iface != soft_iface) {
|
||||||
|
ret = -ENOENT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bat_priv->algo_ops->orig.dump) {
|
||||||
|
ret = -EOPNOTSUPP;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
bat_priv->algo_ops->orig.dump(msg, cb, bat_priv, hardif);
|
||||||
|
|
||||||
|
ret = msg->len;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (hardif)
|
||||||
|
batadv_hardif_put(hardif);
|
||||||
|
if (hard_iface)
|
||||||
|
dev_put(hard_iface);
|
||||||
|
if (primary_if)
|
||||||
|
batadv_hardif_put(primary_if);
|
||||||
|
if (soft_iface)
|
||||||
|
dev_put(soft_iface);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
|
int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
|
||||||
int max_if_num)
|
int max_if_num)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,7 +31,9 @@
|
||||||
|
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
|
|
||||||
|
struct netlink_callback;
|
||||||
struct seq_file;
|
struct seq_file;
|
||||||
|
struct sk_buff;
|
||||||
|
|
||||||
bool batadv_compare_orig(const struct hlist_node *node, const void *data2);
|
bool batadv_compare_orig(const struct hlist_node *node, const void *data2);
|
||||||
int batadv_originator_init(struct batadv_priv *bat_priv);
|
int batadv_originator_init(struct batadv_priv *bat_priv);
|
||||||
|
@ -61,6 +63,7 @@ batadv_neigh_ifinfo_get(struct batadv_neigh_node *neigh,
|
||||||
struct batadv_hard_iface *if_outgoing);
|
struct batadv_hard_iface *if_outgoing);
|
||||||
void batadv_neigh_ifinfo_put(struct batadv_neigh_ifinfo *neigh_ifinfo);
|
void batadv_neigh_ifinfo_put(struct batadv_neigh_ifinfo *neigh_ifinfo);
|
||||||
|
|
||||||
|
int batadv_hardif_neigh_dump(struct sk_buff *msg, struct netlink_callback *cb);
|
||||||
int batadv_hardif_neigh_seq_print_text(struct seq_file *seq, void *offset);
|
int batadv_hardif_neigh_seq_print_text(struct seq_file *seq, void *offset);
|
||||||
|
|
||||||
struct batadv_orig_ifinfo *
|
struct batadv_orig_ifinfo *
|
||||||
|
@ -72,6 +75,7 @@ batadv_orig_ifinfo_new(struct batadv_orig_node *orig_node,
|
||||||
void batadv_orig_ifinfo_put(struct batadv_orig_ifinfo *orig_ifinfo);
|
void batadv_orig_ifinfo_put(struct batadv_orig_ifinfo *orig_ifinfo);
|
||||||
|
|
||||||
int batadv_orig_seq_print_text(struct seq_file *seq, void *offset);
|
int batadv_orig_seq_print_text(struct seq_file *seq, void *offset);
|
||||||
|
int batadv_orig_dump(struct sk_buff *msg, struct netlink_callback *cb);
|
||||||
int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset);
|
int batadv_orig_hardif_seq_print_text(struct seq_file *seq, void *offset);
|
||||||
int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
|
int batadv_orig_hash_add_if(struct batadv_hard_iface *hard_iface,
|
||||||
int max_if_num);
|
int max_if_num);
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <linux/if_ether.h>
|
#include <linux/if_ether.h>
|
||||||
#include <linux/kref.h>
|
#include <linux/kref.h>
|
||||||
#include <linux/netdevice.h>
|
#include <linux/netdevice.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
#include <linux/sched.h> /* for linux/wait.h */
|
#include <linux/sched.h> /* for linux/wait.h */
|
||||||
#include <linux/spinlock.h>
|
#include <linux/spinlock.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
@ -1418,6 +1419,7 @@ struct batadv_algo_iface_ops {
|
||||||
* @is_similar_or_better: check if neigh1 is equally similar or better than
|
* @is_similar_or_better: check if neigh1 is equally similar or better than
|
||||||
* neigh2 for their respective outgoing interface from the metric prospective
|
* neigh2 for their respective outgoing interface from the metric prospective
|
||||||
* @print: print the single hop neighbor list (optional)
|
* @print: print the single hop neighbor list (optional)
|
||||||
|
* @dump: dump neighbors to a netlink socket (optional)
|
||||||
*/
|
*/
|
||||||
struct batadv_algo_neigh_ops {
|
struct batadv_algo_neigh_ops {
|
||||||
void (*hardif_init)(struct batadv_hardif_neigh_node *neigh);
|
void (*hardif_init)(struct batadv_hardif_neigh_node *neigh);
|
||||||
|
@ -1430,6 +1432,9 @@ struct batadv_algo_neigh_ops {
|
||||||
struct batadv_neigh_node *neigh2,
|
struct batadv_neigh_node *neigh2,
|
||||||
struct batadv_hard_iface *if_outgoing2);
|
struct batadv_hard_iface *if_outgoing2);
|
||||||
void (*print)(struct batadv_priv *priv, struct seq_file *seq);
|
void (*print)(struct batadv_priv *priv, struct seq_file *seq);
|
||||||
|
void (*dump)(struct sk_buff *msg, struct netlink_callback *cb,
|
||||||
|
struct batadv_priv *priv,
|
||||||
|
struct batadv_hard_iface *hard_iface);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1441,6 +1446,7 @@ struct batadv_algo_neigh_ops {
|
||||||
* @del_if: ask the routing algorithm to apply the needed changes to the
|
* @del_if: ask the routing algorithm to apply the needed changes to the
|
||||||
* orig_node due to an hard-interface being removed from the mesh (optional)
|
* orig_node due to an hard-interface being removed from the mesh (optional)
|
||||||
* @print: print the originator table (optional)
|
* @print: print the originator table (optional)
|
||||||
|
* @dump: dump originators to a netlink socket (optional)
|
||||||
*/
|
*/
|
||||||
struct batadv_algo_orig_ops {
|
struct batadv_algo_orig_ops {
|
||||||
void (*free)(struct batadv_orig_node *orig_node);
|
void (*free)(struct batadv_orig_node *orig_node);
|
||||||
|
@ -1449,6 +1455,9 @@ struct batadv_algo_orig_ops {
|
||||||
int del_if_num);
|
int del_if_num);
|
||||||
void (*print)(struct batadv_priv *priv, struct seq_file *seq,
|
void (*print)(struct batadv_priv *priv, struct seq_file *seq,
|
||||||
struct batadv_hard_iface *hard_iface);
|
struct batadv_hard_iface *hard_iface);
|
||||||
|
void (*dump)(struct sk_buff *msg, struct netlink_callback *cb,
|
||||||
|
struct batadv_priv *priv,
|
||||||
|
struct batadv_hard_iface *hard_iface);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue
Block a user