mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-28 15:53:26 +00:00
[NETLINK]: Add notification message sending interface
Adds nlmsg_notify() implementing proper notification logic. The message is multicasted to all listeners in the group. The applications the requests orignates from can request a unicast back report in which case said socket will be excluded from the multicast to avoid duplicated notifications. nlmsg_multicast() is extended to take allocation flags to allow notification in atomic contexts. Signed-off-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2942e90050
commit
d387f6ad10
5 changed files with 42 additions and 7 deletions
|
@ -133,11 +133,12 @@ static inline int genlmsg_cancel(struct sk_buff *skb, void *hdr)
|
||||||
* @skb: netlink message as socket buffer
|
* @skb: netlink message as socket buffer
|
||||||
* @pid: own netlink pid to avoid sending to yourself
|
* @pid: own netlink pid to avoid sending to yourself
|
||||||
* @group: multicast group id
|
* @group: multicast group id
|
||||||
|
* @flags: allocation flags
|
||||||
*/
|
*/
|
||||||
static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid,
|
static inline int genlmsg_multicast(struct sk_buff *skb, u32 pid,
|
||||||
unsigned int group)
|
unsigned int group, gfp_t flags)
|
||||||
{
|
{
|
||||||
return nlmsg_multicast(genl_sock, skb, pid, group);
|
return nlmsg_multicast(genl_sock, skb, pid, group, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
* Message Sending:
|
* Message Sending:
|
||||||
* nlmsg_multicast() multicast message to several groups
|
* nlmsg_multicast() multicast message to several groups
|
||||||
* nlmsg_unicast() unicast a message to a single socket
|
* nlmsg_unicast() unicast a message to a single socket
|
||||||
|
* nlmsg_notify() send notification message
|
||||||
*
|
*
|
||||||
* Message Length Calculations:
|
* Message Length Calculations:
|
||||||
* nlmsg_msg_size(payload) length of message w/o padding
|
* nlmsg_msg_size(payload) length of message w/o padding
|
||||||
|
@ -545,15 +546,16 @@ static inline void nlmsg_free(struct sk_buff *skb)
|
||||||
* @skb: netlink message as socket buffer
|
* @skb: netlink message as socket buffer
|
||||||
* @pid: own netlink pid to avoid sending to yourself
|
* @pid: own netlink pid to avoid sending to yourself
|
||||||
* @group: multicast group id
|
* @group: multicast group id
|
||||||
|
* @flags: allocation flags
|
||||||
*/
|
*/
|
||||||
static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
|
static inline int nlmsg_multicast(struct sock *sk, struct sk_buff *skb,
|
||||||
u32 pid, unsigned int group)
|
u32 pid, unsigned int group, gfp_t flags)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
NETLINK_CB(skb).dst_group = group;
|
NETLINK_CB(skb).dst_group = group;
|
||||||
|
|
||||||
err = netlink_broadcast(sk, skb, pid, group, GFP_KERNEL);
|
err = netlink_broadcast(sk, skb, pid, group, flags);
|
||||||
if (err > 0)
|
if (err > 0)
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
|
|
|
@ -154,5 +154,5 @@ int netlbl_netlink_snd(struct sk_buff *skb, u32 pid)
|
||||||
*/
|
*/
|
||||||
int netlbl_netlink_snd_multicast(struct sk_buff *skb, u32 pid, u32 group)
|
int netlbl_netlink_snd_multicast(struct sk_buff *skb, u32 pid, u32 group)
|
||||||
{
|
{
|
||||||
return genlmsg_multicast(skb, pid, group);
|
return genlmsg_multicast(skb, pid, group, GFP_KERNEL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1549,6 +1549,38 @@ void netlink_queue_skip(struct nlmsghdr *nlh, struct sk_buff *skb)
|
||||||
skb_pull(skb, msglen);
|
skb_pull(skb, msglen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nlmsg_notify - send a notification netlink message
|
||||||
|
* @sk: netlink socket to use
|
||||||
|
* @skb: notification message
|
||||||
|
* @pid: destination netlink pid for reports or 0
|
||||||
|
* @group: destination multicast group or 0
|
||||||
|
* @report: 1 to report back, 0 to disable
|
||||||
|
* @flags: allocation flags
|
||||||
|
*/
|
||||||
|
int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid,
|
||||||
|
unsigned int group, int report, gfp_t flags)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
if (group) {
|
||||||
|
int exclude_pid = 0;
|
||||||
|
|
||||||
|
if (report) {
|
||||||
|
atomic_inc(&skb->users);
|
||||||
|
exclude_pid = pid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* errors reported via destination sk->sk_err */
|
||||||
|
nlmsg_multicast(sk, skb, exclude_pid, group, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (report)
|
||||||
|
err = nlmsg_unicast(sk, skb, pid);
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PROC_FS
|
#ifdef CONFIG_PROC_FS
|
||||||
struct nl_seq_iter {
|
struct nl_seq_iter {
|
||||||
int link;
|
int link;
|
||||||
|
@ -1802,4 +1834,4 @@ EXPORT_SYMBOL(netlink_set_err);
|
||||||
EXPORT_SYMBOL(netlink_set_nonroot);
|
EXPORT_SYMBOL(netlink_set_nonroot);
|
||||||
EXPORT_SYMBOL(netlink_unicast);
|
EXPORT_SYMBOL(netlink_unicast);
|
||||||
EXPORT_SYMBOL(netlink_unregister_notifier);
|
EXPORT_SYMBOL(netlink_unregister_notifier);
|
||||||
|
EXPORT_SYMBOL(nlmsg_notify);
|
||||||
|
|
|
@ -510,7 +510,7 @@ static int genl_ctrl_event(int event, void *data)
|
||||||
if (IS_ERR(msg))
|
if (IS_ERR(msg))
|
||||||
return PTR_ERR(msg);
|
return PTR_ERR(msg);
|
||||||
|
|
||||||
genlmsg_multicast(msg, 0, GENL_ID_CTRL);
|
genlmsg_multicast(msg, 0, GENL_ID_CTRL, GFP_KERNEL);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue