Commit 9acee33f authored by James Morris's avatar James Morris Committed by David S. Miller

NETLINK: Add unicast release notifier.

parent 0dd307f5
...@@ -110,6 +110,8 @@ extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int ...@@ -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, extern void netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 pid,
__u32 group, int allocation); __u32 group, int allocation);
extern void netlink_set_err(struct sock *ssk, __u32 pid, __u32 group, int code); 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. * skb should fit one page. This choice is good for headerless malloc.
...@@ -129,6 +131,12 @@ struct netlink_callback ...@@ -129,6 +131,12 @@ struct netlink_callback
long args[4]; long args[4];
}; };
struct netlink_notify
{
int pid;
int protocol;
};
static __inline__ struct nlmsghdr * static __inline__ struct nlmsghdr *
__nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len) __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len)
{ {
......
...@@ -58,5 +58,7 @@ extern int notifier_call_chain(struct notifier_block **n, unsigned long val, voi ...@@ -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_HALT 0x0002 /* Notify of system halt */
#define SYS_POWER_OFF 0x0003 /* Notify of system power off */ #define SYS_POWER_OFF 0x0003 /* Notify of system power off */
#define NETLINK_URELEASE 0x0001 /* Unicast netlink socket released */
#endif /* __KERNEL__ */ #endif /* __KERNEL__ */
#endif /* _LINUX_NOTIFIER_H */ #endif /* _LINUX_NOTIFIER_H */
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/notifier.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/scm.h> #include <net/scm.h>
...@@ -81,6 +82,8 @@ atomic_t netlink_sock_nr; ...@@ -81,6 +82,8 @@ atomic_t netlink_sock_nr;
static rwlock_t nl_table_lock = RW_LOCK_UNLOCKED; static rwlock_t nl_table_lock = RW_LOCK_UNLOCKED;
static atomic_t nl_table_users = ATOMIC_INIT(0); static atomic_t nl_table_users = ATOMIC_INIT(0);
static struct notifier_block *netlink_chain;
static void netlink_sock_destruct(struct sock *sk) static void netlink_sock_destruct(struct sock *sk)
{ {
skb_queue_purge(&sk->receive_queue); skb_queue_purge(&sk->receive_queue);
...@@ -276,6 +279,12 @@ static int netlink_release(struct socket *sock) ...@@ -276,6 +279,12 @@ static int netlink_release(struct socket *sock)
skb_queue_purge(&sk->write_queue); 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); sock_put(sk);
return 0; return 0;
} }
...@@ -967,6 +976,16 @@ static int netlink_read_proc(char *buffer, char **start, off_t offset, ...@@ -967,6 +976,16 @@ static int netlink_read_proc(char *buffer, char **start, off_t offset,
} }
#endif #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 = { struct proto_ops netlink_ops = {
family: PF_NETLINK, family: PF_NETLINK,
......
...@@ -402,6 +402,8 @@ EXPORT_SYMBOL(netlink_unicast); ...@@ -402,6 +402,8 @@ EXPORT_SYMBOL(netlink_unicast);
EXPORT_SYMBOL(netlink_kernel_create); EXPORT_SYMBOL(netlink_kernel_create);
EXPORT_SYMBOL(netlink_dump_start); EXPORT_SYMBOL(netlink_dump_start);
EXPORT_SYMBOL(netlink_ack); EXPORT_SYMBOL(netlink_ack);
EXPORT_SYMBOL(netlink_register_notifier);
EXPORT_SYMBOL(netlink_unregister_notifier);
#if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE) #if defined(CONFIG_NETLINK_DEV) || defined(CONFIG_NETLINK_DEV_MODULE)
EXPORT_SYMBOL(netlink_attach); EXPORT_SYMBOL(netlink_attach);
EXPORT_SYMBOL(netlink_detach); EXPORT_SYMBOL(netlink_detach);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment