Skip to content

Commit 971b4ad

Browse files
Jiri PirkoPaolo Abeni
Jiri Pirko
authored and
Paolo Abeni
committed
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 <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 403863e commit 971b4ad

File tree

2 files changed

+58
-8
lines changed

2 files changed

+58
-8
lines changed

include/net/genetlink.h

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,35 @@ static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
448448
nlmsg_cancel(skb, hdr - GENL_HDRLEN - NLMSG_HDRLEN);
449449
}
450450

451+
/**
452+
* genlmsg_multicast_netns_filtered - multicast a netlink message
453+
* to a specific netns with filter
454+
* function
455+
* @family: the generic netlink family
456+
* @net: the net namespace
457+
* @skb: netlink message as socket buffer
458+
* @portid: own netlink portid to avoid sending to yourself
459+
* @group: offset of multicast group in groups array
460+
* @flags: allocation flags
461+
* @filter: filter function
462+
* @filter_data: filter function private data
463+
*
464+
* Return: 0 on success, negative error code for failure.
465+
*/
466+
static inline int
467+
genlmsg_multicast_netns_filtered(const struct genl_family *family,
468+
struct net *net, struct sk_buff *skb,
469+
u32 portid, unsigned int group, gfp_t flags,
470+
netlink_filter_fn filter,
471+
void *filter_data)
472+
{
473+
if (WARN_ON_ONCE(group >= family->n_mcgrps))
474+
return -EINVAL;
475+
group = family->mcgrp_offset + group;
476+
return nlmsg_multicast_filtered(net->genl_sock, skb, portid, group,
477+
flags, filter, filter_data);
478+
}
479+
451480
/**
452481
* genlmsg_multicast_netns - multicast a netlink message to a specific netns
453482
* @family: the generic netlink family
@@ -461,10 +490,8 @@ static inline int genlmsg_multicast_netns(const struct genl_family *family,
461490
struct net *net, struct sk_buff *skb,
462491
u32 portid, unsigned int group, gfp_t flags)
463492
{
464-
if (WARN_ON_ONCE(group >= family->n_mcgrps))
465-
return -EINVAL;
466-
group = family->mcgrp_offset + group;
467-
return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
493+
return genlmsg_multicast_netns_filtered(family, net, skb, portid,
494+
group, flags, NULL, NULL);
468495
}
469496

470497
/**

include/net/netlink.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,27 +1087,50 @@ static inline void nlmsg_free(struct sk_buff *skb)
10871087
}
10881088

10891089
/**
1090-
* nlmsg_multicast - multicast a netlink message
1090+
* nlmsg_multicast_filtered - multicast a netlink message with filter function
10911091
* @sk: netlink socket to spread messages to
10921092
* @skb: netlink message as socket buffer
10931093
* @portid: own netlink portid to avoid sending to yourself
10941094
* @group: multicast group id
10951095
* @flags: allocation flags
1096+
* @filter: filter function
1097+
* @filter_data: filter function private data
1098+
*
1099+
* Return: 0 on success, negative error code for failure.
10961100
*/
1097-
static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
1098-
u32 portid, unsigned int group, gfp_t flags)
1101+
static inline int nlmsg_multicast_filtered(struct sock *sk, struct sk_buff *skb,
1102+
u32 portid, unsigned int group,
1103+
gfp_t flags,
1104+
netlink_filter_fn filter,
1105+
void *filter_data)
10991106
{
11001107
int err;
11011108

11021109
NETLINK_CB(skb).dst_group = group;
11031110

1104-
err = netlink_broadcast(sk, skb, portid, group, flags);
1111+
err = netlink_broadcast_filtered(sk, skb, portid, group, flags,
1112+
filter, filter_data);
11051113
if (err > 0)
11061114
err = 0;
11071115

11081116
return err;
11091117
}
11101118

1119+
/**
1120+
* nlmsg_multicast - multicast a netlink message
1121+
* @sk: netlink socket to spread messages to
1122+
* @skb: netlink message as socket buffer
1123+
* @portid: own netlink portid to avoid sending to yourself
1124+
* @group: multicast group id
1125+
* @flags: allocation flags
1126+
*/
1127+
static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
1128+
u32 portid, unsigned int group, gfp_t flags)
1129+
{
1130+
return nlmsg_multicast_filtered(sk, skb, portid, group, flags,
1131+
NULL, NULL);
1132+
}
1133+
11111134
/**
11121135
* nlmsg_unicast - unicast a netlink message
11131136
* @sk: netlink socket to spread message to

0 commit comments

Comments
 (0)