summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Morris <jmorris@intercode.com.au>2002-06-24 18:43:11 -0700
committerDavid S. Miller <davem@nuts.ninka.net>2002-06-24 18:43:11 -0700
commit9acee33f410ab5ef8df06941ba13e48b732a23cd (patch)
treed4b1e140efee85f2fe8e2f26b5bbc9504711a288
parent0dd307f521d72555433f8d9eb1f786ff39c7fb7c (diff)
NETLINK: Add unicast release notifier.
-rw-r--r--include/linux/netlink.h8
-rw-r--r--include/linux/notifier.h2
-rw-r--r--net/netlink/af_netlink.c19
-rw-r--r--net/netsyms.c2
4 files changed, 31 insertions, 0 deletions
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index b3a7c5770c45..327e4efe7adc 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -110,6 +110,8 @@ extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int
extern void netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid,
__u32 group, int allocation);
extern void netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code);
+extern int netlink_register_notifier(struct notifier_block *nb);
+extern int netlink_unregister_notifier(struct notifier_block *nb);
/*
* skb should fit one page. This choice is good for headerless malloc.
@@ -129,6 +131,12 @@ struct netlink_callback
long args[4];
};
+struct netlink_notify
+{
+ int pid;
+ int protocol;
+};
+
static __inline__ struct nlmsghdr *
__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len)
{
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index 56204946541f..0db9736c1166 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -58,5 +58,7 @@ extern int notifier_call_chain(struct notifier_block **n, unsigned long val, voi
#define SYS_HALT 0x0002 /* Notify of system halt */
#define SYS_POWER_OFF 0x0003 /* Notify of system power off */
+#define NETLINK_URELEASE 0x0001 /* Unicast netlink socket released */
+
#endif /* __KERNEL__ */
#endif /* _LINUX_NOTIFIER_H */
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 6700570c7810..b14f074bb2ad 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -41,6 +41,7 @@
#include <linux/rtnetlink.h>
#include <linux/proc_fs.h>
#include <linux/smp_lock.h>
+#include <linux/notifier.h>
#include <net/sock.h>
#include <net/scm.h>
@@ -81,6 +82,8 @@ atomic_t netlink_sock_nr;
static rwlock_t nl_table_lock = RW_LOCK_UNLOCKED;
static atomic_t nl_table_users = ATOMIC_INIT(0);
+static struct notifier_block *netlink_chain;
+
static void netlink_sock_destruct(struct sock *sk)
{
skb_queue_purge(&sk->receive_queue);
@@ -276,6 +279,12 @@ static int netlink_release(struct socket *sock)
skb_queue_purge(&sk->write_queue);
+ if (sk->protinfo.af_netlink->pid && !sk->protinfo.af_netlink->groups) {
+ struct netlink_notify n = { protocol:sk->protocol,
+ pid:sk->protinfo.af_netlink->pid };
+ notifier_call_chain(&netlink_chain, NETLINK_URELEASE, &n);
+ }
+
sock_put(sk);
return 0;
}
@@ -967,6 +976,16 @@ done:
}
#endif
+int netlink_register_notifier(struct notifier_block *nb)
+{
+ return notifier_chain_register(&netlink_chain, nb);
+}
+
+int netlink_unregister_notifier(struct notifier_block *nb)
+{
+ return notifier_chain_unregister(&netlink_chain, nb);
+}
+
struct proto_ops netlink_ops = {
family: PF_NETLINK,
diff --git a/net/netsyms.c b/net/netsyms.c
index 658dca434a79..c75c1bd1c0d4 100644
--- a/net/netsyms.c
+++ b/net/netsyms.c
@@ -402,6 +402,8 @@ EXPORT_SYMBOL(netlink_unicast);
EXPORT_SYMBOL(netlink_kernel_create);
EXPORT_SYMBOL(netlink_dump_start);
EXPORT_SYMBOL(netlink_ack);
+EXPORT_SYMBOL(netlink_register_notifier);
+EXPORT_SYMBOL(netlink_unregister_notifier);
#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
EXPORT_SYMBOL(netlink_attach);
EXPORT_SYMBOL(netlink_detach);