aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink
diff options
context:
space:
mode:
authorThomas Graf <tgraf@suug.ch>2006-08-15 03:31:06 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-09-22 17:54:49 -0400
commitd387f6ad10764fc2174373b4a1cca443adee36e3 (patch)
treeed22c34f55de9c668eed1727d46239f3b48599b7 /net/netlink
parent2942e90050569525628a9f34e0daaa9b661b49cc (diff)
[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>
Diffstat (limited to 'net/netlink')
-rw-r--r--net/netlink/af_netlink.c34
-rw-r--r--net/netlink/genetlink.c2
2 files changed, 34 insertions, 2 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 0f36ddc0b72d..a80e4456e204 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1549,6 +1549,38 @@ void netlink_queue_skip(struct nlmsghdr *nlh, struct sk_buff *skb)
1549 skb_pull(skb, msglen); 1549 skb_pull(skb, msglen);
1550} 1550}
1551 1551
1552/**
1553 * nlmsg_notify - send a notification netlink message
1554 * @sk: netlink socket to use
1555 * @skb: notification message
1556 * @pid: destination netlink pid for reports or 0
1557 * @group: destination multicast group or 0
1558 * @report: 1 to report back, 0 to disable
1559 * @flags: allocation flags
1560 */
1561int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid,
1562 unsigned int group, int report, gfp_t flags)
1563{
1564 int err = 0;
1565
1566 if (group) {
1567 int exclude_pid = 0;
1568
1569 if (report) {
1570 atomic_inc(&skb->users);
1571 exclude_pid = pid;
1572 }
1573
1574 /* errors reported via destination sk->sk_err */
1575 nlmsg_multicast(sk, skb, exclude_pid, group, flags);
1576 }
1577
1578 if (report)
1579 err = nlmsg_unicast(sk, skb, pid);
1580
1581 return err;
1582}
1583
1552#ifdef CONFIG_PROC_FS 1584#ifdef CONFIG_PROC_FS
1553struct nl_seq_iter { 1585struct nl_seq_iter {
1554 int link; 1586 int link;
@@ -1802,4 +1834,4 @@ EXPORT_SYMBOL(netlink_set_err);
1802EXPORT_SYMBOL(netlink_set_nonroot); 1834EXPORT_SYMBOL(netlink_set_nonroot);
1803EXPORT_SYMBOL(netlink_unicast); 1835EXPORT_SYMBOL(netlink_unicast);
1804EXPORT_SYMBOL(netlink_unregister_notifier); 1836EXPORT_SYMBOL(netlink_unregister_notifier);
1805 1837EXPORT_SYMBOL(nlmsg_notify);
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 75bb47a898dd..d32599116c56 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -510,7 +510,7 @@ static int genl_ctrl_event(int event, void *data)
510 if (IS_ERR(msg)) 510 if (IS_ERR(msg))
511 return PTR_ERR(msg); 511 return PTR_ERR(msg);
512 512
513 genlmsg_multicast(msg, 0, GENL_ID_CTRL); 513 genlmsg_multicast(msg, 0, GENL_ID_CTRL, GFP_KERNEL);
514 break; 514 break;
515 } 515 }
516 516