diff options
author | Thomas Graf <tgraf@suug.ch> | 2006-08-15 03:31:06 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-09-22 17:54:49 -0400 |
commit | d387f6ad10764fc2174373b4a1cca443adee36e3 (patch) | |
tree | ed22c34f55de9c668eed1727d46239f3b48599b7 /net/netlink | |
parent | 2942e90050569525628a9f34e0daaa9b661b49cc (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.c | 34 | ||||
-rw-r--r-- | net/netlink/genetlink.c | 2 |
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 | */ | ||
1561 | int 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 |
1553 | struct nl_seq_iter { | 1585 | struct nl_seq_iter { |
1554 | int link; | 1586 | int link; |
@@ -1802,4 +1834,4 @@ EXPORT_SYMBOL(netlink_set_err); | |||
1802 | EXPORT_SYMBOL(netlink_set_nonroot); | 1834 | EXPORT_SYMBOL(netlink_set_nonroot); |
1803 | EXPORT_SYMBOL(netlink_unicast); | 1835 | EXPORT_SYMBOL(netlink_unicast); |
1804 | EXPORT_SYMBOL(netlink_unregister_notifier); | 1836 | EXPORT_SYMBOL(netlink_unregister_notifier); |
1805 | 1837 | EXPORT_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 | ||