genetlink: introduce helpers to do filtered multicast
Currently it is possible for netlink kernel user to pass custom filter function to broadcast send function netlink_broadcast_filtered(). However, this is not exposed to multicast send and to generic netlink users. Extend the api and introduce a netlink helper nlmsg_multicast_filtered() and a generic netlink helper genlmsg_multicast_netns_filtered() to allow generic netlink families to specify filter function while sending multicast messages. Signed-off-by: Jiri Pirko <jiri@nvidia.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
403863e985
commit
971b4ad882
@ -448,6 +448,35 @@ static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
|
||||
nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
|
||||
}
|
||||
|
||||
/**
|
||||
* genlmsg_multicast_netns_filtered - multicast a netlink message
|
||||
* to a specific netns with filter
|
||||
* function
|
||||
* @family: the generic netlink family
|
||||
* @net: the net namespace
|
||||
* @skb: netlink message as socket buffer
|
||||
* @portid: own netlink portid to avoid sending to yourself
|
||||
* @group: offset of multicast group in groups array
|
||||
* @flags: allocation flags
|
||||
* @filter: filter function
|
||||
* @filter_data: filter function private data
|
||||
*
|
||||
* Return: 0 on success, negative error code for failure.
|
||||
*/
|
||||
static inline int
|
||||
genlmsg_multicast_netns_filtered(const struct genl_family *family,
|
||||
struct net *net, struct sk_buff *skb,
|
||||
u32 portid, unsigned int group, gfp_t flags,
|
||||
netlink_filter_fn filter,
|
||||
void *filter_data)
|
||||
{
|
||||
if (WARN_ON_ONCE(group >= family->n_mcgrps))
|
||||
return -EINVAL;
|
||||
group = family->mcgrp_offset + group;
|
||||
return nlmsg_multicast_filtered(net->genl_sock, skb, portid, group,
|
||||
flags, filter, filter_data);
|
||||
}
|
||||
|
||||
/**
|
||||
* genlmsg_multicast_netns - multicast a netlink message to a specific netns
|
||||
* @family: the generic netlink family
|
||||
@ -461,10 +490,8 @@ static inline int genlmsg_multicast_netns(const struct genl_family *family,
|
||||
struct net *net, struct sk_buff *skb,
|
||||
u32 portid, unsigned int group, gfp_t flags)
|
||||
{
|
||||
if (WARN_ON_ONCE(group >= family->n_mcgrps))
|
||||
return -EINVAL;
|
||||
group = family->mcgrp_offset + group;
|
||||
return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
|
||||
return genlmsg_multicast_netns_filtered(family, net, skb, portid,
|
||||
group, flags, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1086,6 +1086,36 @@ static inline void nlmsg_free(struct sk_buff *skb)
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
/**
|
||||
* nlmsg_multicast_filtered - multicast a netlink message with filter function
|
||||
* @sk: netlink socket to spread messages to
|
||||
* @skb: netlink message as socket buffer
|
||||
* @portid: own netlink portid to avoid sending to yourself
|
||||
* @group: multicast group id
|
||||
* @flags: allocation flags
|
||||
* @filter: filter function
|
||||
* @filter_data: filter function private data
|
||||
*
|
||||
* Return: 0 on success, negative error code for failure.
|
||||
*/
|
||||
static inline int nlmsg_multicast_filtered(struct sock *sk, struct sk_buff *skb,
|
||||
u32 portid, unsigned int group,
|
||||
gfp_t flags,
|
||||
netlink_filter_fn filter,
|
||||
void *filter_data)
|
||||
{
|
||||
int err;
|
||||
|
||||
NETLINK_CB(skb).dst_group = group;
|
||||
|
||||
err = netlink_broadcast_filtered(sk, skb, portid, group, flags,
|
||||
filter, filter_data);
|
||||
if (err > 0)
|
||||
err = 0;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* nlmsg_multicast - multicast a netlink message
|
||||
* @sk: netlink socket to spread messages to
|
||||
@ -1097,15 +1127,8 @@ static inline void nlmsg_free(struct sk_buff *skb)
|
||||
static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
|
||||
u32 portid, unsigned int group, gfp_t flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
NETLINK_CB(skb).dst_group = group;
|
||||
|
||||
err = netlink_broadcast(sk, skb, portid, group, flags);
|
||||
if (err > 0)
|
||||
err = 0;
|
||||
|
||||
return err;
|
||||
return nlmsg_multicast_filtered(sk, skb, portid, group, flags,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user