forked from luck/tmp_suning_uos_patched
batman-adv: Move common genl doit code pre/post hooks
The commit ff4c92d85c
("genetlink: introduce pre_doit/post_doit hooks")
intoduced a mechanism to run specific code for doit hooks before/after the
hooks are run. Since all doit hooks are requiring the batadv softif, it
should be retrieved/freed in these helpers to simplify the code.
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
This commit is contained in:
parent
180cf62cec
commit
c4a7a8d9bb
|
@ -20,8 +20,10 @@
|
|||
#include "main.h"
|
||||
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/byteorder/generic.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/genetlink.h>
|
||||
|
@ -54,6 +56,8 @@
|
|||
#include "tp_meter.h"
|
||||
#include "translation-table.h"
|
||||
|
||||
struct net;
|
||||
|
||||
struct genl_family batadv_netlink_family;
|
||||
|
||||
/* multicast groups */
|
||||
|
@ -61,6 +65,18 @@ enum batadv_netlink_multicast_groups {
|
|||
BATADV_NL_MCGRP_TPMETER,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum batadv_genl_ops_flags - flags for genl_ops's internal_flags
|
||||
*/
|
||||
enum batadv_genl_ops_flags {
|
||||
/**
|
||||
* @BATADV_FLAG_NEED_MESH: request requires valid soft interface in
|
||||
* attribute BATADV_ATTR_MESH_IFINDEX and expects a pointer to it to be
|
||||
* saved in info->user_ptr[0]
|
||||
*/
|
||||
BATADV_FLAG_NEED_MESH = BIT(0),
|
||||
};
|
||||
|
||||
static const struct genl_multicast_group batadv_netlink_mcgrps[] = {
|
||||
[BATADV_NL_MCGRP_TPMETER] = { .name = BATADV_NL_MCAST_GROUP_TPMETER },
|
||||
};
|
||||
|
@ -329,40 +345,24 @@ int batadv_netlink_tpmeter_notify(struct batadv_priv *bat_priv, const u8 *dst,
|
|||
static int
|
||||
batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct net *net = genl_info_net(info);
|
||||
struct net_device *soft_iface;
|
||||
struct batadv_priv *bat_priv;
|
||||
struct batadv_priv *bat_priv = info->user_ptr[0];
|
||||
struct sk_buff *msg = NULL;
|
||||
u32 test_length;
|
||||
void *msg_head;
|
||||
int ifindex;
|
||||
u32 cookie;
|
||||
u8 *dst;
|
||||
int ret;
|
||||
|
||||
if (!info->attrs[BATADV_ATTR_MESH_IFINDEX])
|
||||
return -EINVAL;
|
||||
|
||||
if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS])
|
||||
return -EINVAL;
|
||||
|
||||
if (!info->attrs[BATADV_ATTR_TPMETER_TEST_TIME])
|
||||
return -EINVAL;
|
||||
|
||||
ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]);
|
||||
if (!ifindex)
|
||||
return -EINVAL;
|
||||
|
||||
dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]);
|
||||
|
||||
test_length = nla_get_u32(info->attrs[BATADV_ATTR_TPMETER_TEST_TIME]);
|
||||
|
||||
soft_iface = dev_get_by_index(net, ifindex);
|
||||
if (!soft_iface || !batadv_softif_is_valid(soft_iface)) {
|
||||
ret = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
||||
if (!msg) {
|
||||
ret = -ENOMEM;
|
||||
|
@ -377,15 +377,11 @@ batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info)
|
|||
goto out;
|
||||
}
|
||||
|
||||
bat_priv = netdev_priv(soft_iface);
|
||||
batadv_tp_start(bat_priv, dst, test_length, &cookie);
|
||||
|
||||
ret = batadv_netlink_tp_meter_put(msg, cookie);
|
||||
|
||||
out:
|
||||
if (soft_iface)
|
||||
dev_put(soft_iface);
|
||||
|
||||
if (ret) {
|
||||
if (msg)
|
||||
nlmsg_free(msg);
|
||||
|
@ -406,38 +402,17 @@ batadv_netlink_tp_meter_start(struct sk_buff *skb, struct genl_info *info)
|
|||
static int
|
||||
batadv_netlink_tp_meter_cancel(struct sk_buff *skb, struct genl_info *info)
|
||||
{
|
||||
struct net *net = genl_info_net(info);
|
||||
struct net_device *soft_iface;
|
||||
struct batadv_priv *bat_priv;
|
||||
int ifindex;
|
||||
struct batadv_priv *bat_priv = info->user_ptr[0];
|
||||
u8 *dst;
|
||||
int ret = 0;
|
||||
|
||||
if (!info->attrs[BATADV_ATTR_MESH_IFINDEX])
|
||||
return -EINVAL;
|
||||
|
||||
if (!info->attrs[BATADV_ATTR_ORIG_ADDRESS])
|
||||
return -EINVAL;
|
||||
|
||||
ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]);
|
||||
if (!ifindex)
|
||||
return -EINVAL;
|
||||
|
||||
dst = nla_data(info->attrs[BATADV_ATTR_ORIG_ADDRESS]);
|
||||
|
||||
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);
|
||||
batadv_tp_stop(bat_priv, dst, BATADV_TP_REASON_CANCEL);
|
||||
|
||||
out:
|
||||
if (soft_iface)
|
||||
dev_put(soft_iface);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -545,6 +520,84 @@ batadv_netlink_dump_hardifs(struct sk_buff *msg, struct netlink_callback *cb)
|
|||
return msg->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_get_softif_from_info() - Retrieve soft interface from genl attributes
|
||||
* @net: the applicable net namespace
|
||||
* @info: receiver information
|
||||
*
|
||||
* Return: Pointer to soft interface (with increased refcnt) on success, error
|
||||
* pointer on error
|
||||
*/
|
||||
static struct net_device *
|
||||
batadv_get_softif_from_info(struct net *net, struct genl_info *info)
|
||||
{
|
||||
struct net_device *soft_iface;
|
||||
int ifindex;
|
||||
|
||||
if (!info->attrs[BATADV_ATTR_MESH_IFINDEX])
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
ifindex = nla_get_u32(info->attrs[BATADV_ATTR_MESH_IFINDEX]);
|
||||
|
||||
soft_iface = dev_get_by_index(net, ifindex);
|
||||
if (!soft_iface)
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
if (!batadv_softif_is_valid(soft_iface))
|
||||
goto err_put_softif;
|
||||
|
||||
return soft_iface;
|
||||
|
||||
err_put_softif:
|
||||
dev_put(soft_iface);
|
||||
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_pre_doit() - Prepare batman-adv genl doit request
|
||||
* @ops: requested netlink operation
|
||||
* @skb: Netlink message with request data
|
||||
* @info: receiver information
|
||||
*
|
||||
* Return: 0 on success or negative error number in case of failure
|
||||
*/
|
||||
static int batadv_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
|
||||
struct genl_info *info)
|
||||
{
|
||||
struct net *net = genl_info_net(info);
|
||||
struct net_device *soft_iface;
|
||||
struct batadv_priv *bat_priv;
|
||||
|
||||
if (ops->internal_flags & BATADV_FLAG_NEED_MESH) {
|
||||
soft_iface = batadv_get_softif_from_info(net, info);
|
||||
if (IS_ERR(soft_iface))
|
||||
return PTR_ERR(soft_iface);
|
||||
|
||||
bat_priv = netdev_priv(soft_iface);
|
||||
info->user_ptr[0] = bat_priv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* batadv_post_doit() - End batman-adv genl doit request
|
||||
* @ops: requested netlink operation
|
||||
* @skb: Netlink message with request data
|
||||
* @info: receiver information
|
||||
*/
|
||||
static void batadv_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
|
||||
struct genl_info *info)
|
||||
{
|
||||
struct batadv_priv *bat_priv;
|
||||
|
||||
if (ops->internal_flags & BATADV_FLAG_NEED_MESH && info->user_ptr[0]) {
|
||||
bat_priv = info->user_ptr[0];
|
||||
dev_put(bat_priv->soft_iface);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct genl_ops batadv_netlink_ops[] = {
|
||||
{
|
||||
.cmd = BATADV_CMD_GET_MESH_INFO,
|
||||
|
@ -557,12 +610,14 @@ static const struct genl_ops batadv_netlink_ops[] = {
|
|||
.flags = GENL_ADMIN_PERM,
|
||||
.policy = batadv_netlink_policy,
|
||||
.doit = batadv_netlink_tp_meter_start,
|
||||
.internal_flags = BATADV_FLAG_NEED_MESH,
|
||||
},
|
||||
{
|
||||
.cmd = BATADV_CMD_TP_METER_CANCEL,
|
||||
.flags = GENL_ADMIN_PERM,
|
||||
.policy = batadv_netlink_policy,
|
||||
.doit = batadv_netlink_tp_meter_cancel,
|
||||
.internal_flags = BATADV_FLAG_NEED_MESH,
|
||||
},
|
||||
{
|
||||
.cmd = BATADV_CMD_GET_ROUTING_ALGOS,
|
||||
|
@ -639,6 +694,8 @@ struct genl_family batadv_netlink_family __ro_after_init = {
|
|||
.version = 1,
|
||||
.maxattr = BATADV_ATTR_MAX,
|
||||
.netnsok = true,
|
||||
.pre_doit = batadv_pre_doit,
|
||||
.post_doit = batadv_post_doit,
|
||||
.module = THIS_MODULE,
|
||||
.ops = batadv_netlink_ops,
|
||||
.n_ops = ARRAY_SIZE(batadv_netlink_ops),
|
||||
|
|
Loading…
Reference in New Issue
Block a user