diff options
| author | James Morris <jmorris@intercode.com.au> | 2002-06-24 18:43:11 -0700 |
|---|---|---|
| committer | David S. Miller <davem@nuts.ninka.net> | 2002-06-24 18:43:11 -0700 |
| commit | 9acee33f410ab5ef8df06941ba13e48b732a23cd (patch) | |
| tree | d4b1e140efee85f2fe8e2f26b5bbc9504711a288 | |
| parent | 0dd307f521d72555433f8d9eb1f786ff39c7fb7c (diff) | |
NETLINK: Add unicast release notifier.
| -rw-r--r-- | include/linux/netlink.h | 8 | ||||
| -rw-r--r-- | include/linux/notifier.h | 2 | ||||
| -rw-r--r-- | net/netlink/af_netlink.c | 19 | ||||
| -rw-r--r-- | net/netsyms.c | 2 |
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); |
