aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-29 06:54:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-29 06:54:01 -0500
commit0ba6c33bcddc64a54b5f1c25a696c4767dc76292 (patch)
tree62e616f97a4762d8e75bf732e4827af2d15d52c5 /net/unix
parent21af0297c7e56024a5ccc4d8ad2a590f9ec371ba (diff)
parent85040bcb4643cba578839e953f25e2d1965d83d0 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.25
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.25: (1470 commits) [IPV6] ADDRLABEL: Fix double free on label deletion. [PPP]: Sparse warning fixes. [IPV4] fib_trie: remove unneeded NULL check [IPV4] fib_trie: More whitespace cleanup. [NET_SCHED]: Use nla_policy for attribute validation in ematches [NET_SCHED]: Use nla_policy for attribute validation in actions [NET_SCHED]: Use nla_policy for attribute validation in classifiers [NET_SCHED]: Use nla_policy for attribute validation in packet schedulers [NET_SCHED]: sch_api: introduce constant for rate table size [NET_SCHED]: Use typeful attribute parsing helpers [NET_SCHED]: Use typeful attribute construction helpers [NET_SCHED]: Use NLA_PUT_STRING for string dumping [NET_SCHED]: Use nla_nest_start/nla_nest_end [NET_SCHED]: Propagate nla_parse return value [NET_SCHED]: act_api: use PTR_ERR in tcf_action_init/tcf_action_get [NET_SCHED]: act_api: use nlmsg_parse [NET_SCHED]: act_api: fix netlink API conversion bug [NET_SCHED]: sch_netem: use nla_parse_nested_compat [NET_SCHED]: sch_atm: fix format string warning [NETNS]: Add namespace for ICMP replying code. ...
Diffstat (limited to 'net/unix')
-rw-r--r--net/unix/af_unix.c171
-rw-r--r--net/unix/sysctl_net_unix.c52
2 files changed, 138 insertions, 85 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 060bba4567d2..eea75888805e 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -117,8 +117,6 @@
117#include <net/checksum.h> 117#include <net/checksum.h>
118#include <linux/security.h> 118#include <linux/security.h>
119 119
120int sysctl_unix_max_dgram_qlen __read_mostly = 10;
121
122static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1]; 120static struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
123static DEFINE_SPINLOCK(unix_table_lock); 121static DEFINE_SPINLOCK(unix_table_lock);
124static atomic_t unix_nr_socks = ATOMIC_INIT(0); 122static atomic_t unix_nr_socks = ATOMIC_INIT(0);
@@ -127,32 +125,6 @@ static atomic_t unix_nr_socks = ATOMIC_INIT(0);
127 125
128#define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE) 126#define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE)
129 127
130static struct sock *first_unix_socket(int *i)
131{
132 for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) {
133 if (!hlist_empty(&unix_socket_table[*i]))
134 return __sk_head(&unix_socket_table[*i]);
135 }
136 return NULL;
137}
138
139static struct sock *next_unix_socket(int *i, struct sock *s)
140{
141 struct sock *next = sk_next(s);
142 /* More in this chain? */
143 if (next)
144 return next;
145 /* Look for next non-empty chain. */
146 for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
147 if (!hlist_empty(&unix_socket_table[*i]))
148 return __sk_head(&unix_socket_table[*i]);
149 }
150 return NULL;
151}
152
153#define forall_unix_sockets(i, s) \
154 for (s = first_unix_socket(&(i)); s; s = next_unix_socket(&(i),(s)))
155
156#ifdef CONFIG_SECURITY_NETWORK 128#ifdef CONFIG_SECURITY_NETWORK
157static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) 129static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
158{ 130{
@@ -270,7 +242,8 @@ static inline void unix_insert_socket(struct hlist_head *list, struct sock *sk)
270 spin_unlock(&unix_table_lock); 242 spin_unlock(&unix_table_lock);
271} 243}
272 244
273static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname, 245static struct sock *__unix_find_socket_byname(struct net *net,
246 struct sockaddr_un *sunname,
274 int len, int type, unsigned hash) 247 int len, int type, unsigned hash)
275{ 248{
276 struct sock *s; 249 struct sock *s;
@@ -279,6 +252,9 @@ static struct sock *__unix_find_socket_byname(struct sockaddr_un *sunname,
279 sk_for_each(s, node, &unix_socket_table[hash ^ type]) { 252 sk_for_each(s, node, &unix_socket_table[hash ^ type]) {
280 struct unix_sock *u = unix_sk(s); 253 struct unix_sock *u = unix_sk(s);
281 254
255 if (s->sk_net != net)
256 continue;
257
282 if (u->addr->len == len && 258 if (u->addr->len == len &&
283 !memcmp(u->addr->name, sunname, len)) 259 !memcmp(u->addr->name, sunname, len))
284 goto found; 260 goto found;
@@ -288,21 +264,22 @@ found:
288 return s; 264 return s;
289} 265}
290 266
291static inline struct sock *unix_find_socket_byname(struct sockaddr_un *sunname, 267static inline struct sock *unix_find_socket_byname(struct net *net,
268 struct sockaddr_un *sunname,
292 int len, int type, 269 int len, int type,
293 unsigned hash) 270 unsigned hash)
294{ 271{
295 struct sock *s; 272 struct sock *s;
296 273
297 spin_lock(&unix_table_lock); 274 spin_lock(&unix_table_lock);
298 s = __unix_find_socket_byname(sunname, len, type, hash); 275 s = __unix_find_socket_byname(net, sunname, len, type, hash);
299 if (s) 276 if (s)
300 sock_hold(s); 277 sock_hold(s);
301 spin_unlock(&unix_table_lock); 278 spin_unlock(&unix_table_lock);
302 return s; 279 return s;
303} 280}
304 281
305static struct sock *unix_find_socket_byinode(struct inode *i) 282static struct sock *unix_find_socket_byinode(struct net *net, struct inode *i)
306{ 283{
307 struct sock *s; 284 struct sock *s;
308 struct hlist_node *node; 285 struct hlist_node *node;
@@ -312,6 +289,9 @@ static struct sock *unix_find_socket_byinode(struct inode *i)
312 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) { 289 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
313 struct dentry *dentry = unix_sk(s)->dentry; 290 struct dentry *dentry = unix_sk(s)->dentry;
314 291
292 if (s->sk_net != net)
293 continue;
294
315 if(dentry && dentry->d_inode == i) 295 if(dentry && dentry->d_inode == i)
316 { 296 {
317 sock_hold(s); 297 sock_hold(s);
@@ -335,7 +315,7 @@ static void unix_write_space(struct sock *sk)
335 if (unix_writable(sk)) { 315 if (unix_writable(sk)) {
336 if (sk->sk_sleep && waitqueue_active(sk->sk_sleep)) 316 if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
337 wake_up_interruptible_sync(sk->sk_sleep); 317 wake_up_interruptible_sync(sk->sk_sleep);
338 sk_wake_async(sk, 2, POLL_OUT); 318 sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
339 } 319 }
340 read_unlock(&sk->sk_callback_lock); 320 read_unlock(&sk->sk_callback_lock);
341} 321}
@@ -421,7 +401,7 @@ static int unix_release_sock (struct sock *sk, int embrion)
421 unix_state_unlock(skpair); 401 unix_state_unlock(skpair);
422 skpair->sk_state_change(skpair); 402 skpair->sk_state_change(skpair);
423 read_lock(&skpair->sk_callback_lock); 403 read_lock(&skpair->sk_callback_lock);
424 sk_wake_async(skpair,1,POLL_HUP); 404 sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
425 read_unlock(&skpair->sk_callback_lock); 405 read_unlock(&skpair->sk_callback_lock);
426 } 406 }
427 sock_put(skpair); /* It may now die */ 407 sock_put(skpair); /* It may now die */
@@ -612,7 +592,7 @@ static struct sock * unix_create1(struct net *net, struct socket *sock)
612 &af_unix_sk_receive_queue_lock_key); 592 &af_unix_sk_receive_queue_lock_key);
613 593
614 sk->sk_write_space = unix_write_space; 594 sk->sk_write_space = unix_write_space;
615 sk->sk_max_ack_backlog = sysctl_unix_max_dgram_qlen; 595 sk->sk_max_ack_backlog = net->unx.sysctl_max_dgram_qlen;
616 sk->sk_destruct = unix_sock_destructor; 596 sk->sk_destruct = unix_sock_destructor;
617 u = unix_sk(sk); 597 u = unix_sk(sk);
618 u->dentry = NULL; 598 u->dentry = NULL;
@@ -631,9 +611,6 @@ out:
631 611
632static int unix_create(struct net *net, struct socket *sock, int protocol) 612static int unix_create(struct net *net, struct socket *sock, int protocol)
633{ 613{
634 if (net != &init_net)
635 return -EAFNOSUPPORT;
636
637 if (protocol && protocol != PF_UNIX) 614 if (protocol && protocol != PF_UNIX)
638 return -EPROTONOSUPPORT; 615 return -EPROTONOSUPPORT;
639 616
@@ -677,6 +654,7 @@ static int unix_release(struct socket *sock)
677static int unix_autobind(struct socket *sock) 654static int unix_autobind(struct socket *sock)
678{ 655{
679 struct sock *sk = sock->sk; 656 struct sock *sk = sock->sk;
657 struct net *net = sk->sk_net;
680 struct unix_sock *u = unix_sk(sk); 658 struct unix_sock *u = unix_sk(sk);
681 static u32 ordernum = 1; 659 static u32 ordernum = 1;
682 struct unix_address * addr; 660 struct unix_address * addr;
@@ -703,7 +681,7 @@ retry:
703 spin_lock(&unix_table_lock); 681 spin_lock(&unix_table_lock);
704 ordernum = (ordernum+1)&0xFFFFF; 682 ordernum = (ordernum+1)&0xFFFFF;
705 683
706 if (__unix_find_socket_byname(addr->name, addr->len, sock->type, 684 if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
707 addr->hash)) { 685 addr->hash)) {
708 spin_unlock(&unix_table_lock); 686 spin_unlock(&unix_table_lock);
709 /* Sanity yield. It is unusual case, but yet... */ 687 /* Sanity yield. It is unusual case, but yet... */
@@ -723,7 +701,8 @@ out: mutex_unlock(&u->readlock);
723 return err; 701 return err;
724} 702}
725 703
726static struct sock *unix_find_other(struct sockaddr_un *sunname, int len, 704static struct sock *unix_find_other(struct net *net,
705 struct sockaddr_un *sunname, int len,
727 int type, unsigned hash, int *error) 706 int type, unsigned hash, int *error)
728{ 707{
729 struct sock *u; 708 struct sock *u;
@@ -741,7 +720,7 @@ static struct sock *unix_find_other(struct sockaddr_un *sunname, int len,
741 err = -ECONNREFUSED; 720 err = -ECONNREFUSED;
742 if (!S_ISSOCK(nd.dentry->d_inode->i_mode)) 721 if (!S_ISSOCK(nd.dentry->d_inode->i_mode))
743 goto put_fail; 722 goto put_fail;
744 u=unix_find_socket_byinode(nd.dentry->d_inode); 723 u=unix_find_socket_byinode(net, nd.dentry->d_inode);
745 if (!u) 724 if (!u)
746 goto put_fail; 725 goto put_fail;
747 726
@@ -757,7 +736,7 @@ static struct sock *unix_find_other(struct sockaddr_un *sunname, int len,
757 } 736 }
758 } else { 737 } else {
759 err = -ECONNREFUSED; 738 err = -ECONNREFUSED;
760 u=unix_find_socket_byname(sunname, len, type, hash); 739 u=unix_find_socket_byname(net, sunname, len, type, hash);
761 if (u) { 740 if (u) {
762 struct dentry *dentry; 741 struct dentry *dentry;
763 dentry = unix_sk(u)->dentry; 742 dentry = unix_sk(u)->dentry;
@@ -779,6 +758,7 @@ fail:
779static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) 758static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
780{ 759{
781 struct sock *sk = sock->sk; 760 struct sock *sk = sock->sk;
761 struct net *net = sk->sk_net;
782 struct unix_sock *u = unix_sk(sk); 762 struct unix_sock *u = unix_sk(sk);
783 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr; 763 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
784 struct dentry * dentry = NULL; 764 struct dentry * dentry = NULL;
@@ -853,7 +833,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
853 833
854 if (!sunaddr->sun_path[0]) { 834 if (!sunaddr->sun_path[0]) {
855 err = -EADDRINUSE; 835 err = -EADDRINUSE;
856 if (__unix_find_socket_byname(sunaddr, addr_len, 836 if (__unix_find_socket_byname(net, sunaddr, addr_len,
857 sk->sk_type, hash)) { 837 sk->sk_type, hash)) {
858 unix_release_addr(addr); 838 unix_release_addr(addr);
859 goto out_unlock; 839 goto out_unlock;
@@ -919,6 +899,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
919 int alen, int flags) 899 int alen, int flags)
920{ 900{
921 struct sock *sk = sock->sk; 901 struct sock *sk = sock->sk;
902 struct net *net = sk->sk_net;
922 struct sockaddr_un *sunaddr=(struct sockaddr_un*)addr; 903 struct sockaddr_un *sunaddr=(struct sockaddr_un*)addr;
923 struct sock *other; 904 struct sock *other;
924 unsigned hash; 905 unsigned hash;
@@ -935,7 +916,7 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr,
935 goto out; 916 goto out;
936 917
937restart: 918restart:
938 other=unix_find_other(sunaddr, alen, sock->type, hash, &err); 919 other=unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
939 if (!other) 920 if (!other)
940 goto out; 921 goto out;
941 922
@@ -1015,6 +996,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
1015{ 996{
1016 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr; 997 struct sockaddr_un *sunaddr=(struct sockaddr_un *)uaddr;
1017 struct sock *sk = sock->sk; 998 struct sock *sk = sock->sk;
999 struct net *net = sk->sk_net;
1018 struct unix_sock *u = unix_sk(sk), *newu, *otheru; 1000 struct unix_sock *u = unix_sk(sk), *newu, *otheru;
1019 struct sock *newsk = NULL; 1001 struct sock *newsk = NULL;
1020 struct sock *other = NULL; 1002 struct sock *other = NULL;
@@ -1054,7 +1036,7 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
1054 1036
1055restart: 1037restart:
1056 /* Find listening sock. */ 1038 /* Find listening sock. */
1057 other = unix_find_other(sunaddr, addr_len, sk->sk_type, hash, &err); 1039 other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
1058 if (!other) 1040 if (!other)
1059 goto out; 1041 goto out;
1060 1042
@@ -1330,6 +1312,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1330{ 1312{
1331 struct sock_iocb *siocb = kiocb_to_siocb(kiocb); 1313 struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
1332 struct sock *sk = sock->sk; 1314 struct sock *sk = sock->sk;
1315 struct net *net = sk->sk_net;
1333 struct unix_sock *u = unix_sk(sk); 1316 struct unix_sock *u = unix_sk(sk);
1334 struct sockaddr_un *sunaddr=msg->msg_name; 1317 struct sockaddr_un *sunaddr=msg->msg_name;
1335 struct sock *other = NULL; 1318 struct sock *other = NULL;
@@ -1393,7 +1376,7 @@ restart:
1393 if (sunaddr == NULL) 1376 if (sunaddr == NULL)
1394 goto out_free; 1377 goto out_free;
1395 1378
1396 other = unix_find_other(sunaddr, namelen, sk->sk_type, 1379 other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
1397 hash, &err); 1380 hash, &err);
1398 if (other==NULL) 1381 if (other==NULL)
1399 goto out_free; 1382 goto out_free;
@@ -1915,9 +1898,9 @@ static int unix_shutdown(struct socket *sock, int mode)
1915 other->sk_state_change(other); 1898 other->sk_state_change(other);
1916 read_lock(&other->sk_callback_lock); 1899 read_lock(&other->sk_callback_lock);
1917 if (peer_mode == SHUTDOWN_MASK) 1900 if (peer_mode == SHUTDOWN_MASK)
1918 sk_wake_async(other,1,POLL_HUP); 1901 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP);
1919 else if (peer_mode & RCV_SHUTDOWN) 1902 else if (peer_mode & RCV_SHUTDOWN)
1920 sk_wake_async(other,1,POLL_IN); 1903 sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN);
1921 read_unlock(&other->sk_callback_lock); 1904 read_unlock(&other->sk_callback_lock);
1922 } 1905 }
1923 if (other) 1906 if (other)
@@ -2006,12 +1989,41 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl
2006 1989
2007 1990
2008#ifdef CONFIG_PROC_FS 1991#ifdef CONFIG_PROC_FS
2009static struct sock *unix_seq_idx(int *iter, loff_t pos) 1992static struct sock *first_unix_socket(int *i)
1993{
1994 for (*i = 0; *i <= UNIX_HASH_SIZE; (*i)++) {
1995 if (!hlist_empty(&unix_socket_table[*i]))
1996 return __sk_head(&unix_socket_table[*i]);
1997 }
1998 return NULL;
1999}
2000
2001static struct sock *next_unix_socket(int *i, struct sock *s)
2002{
2003 struct sock *next = sk_next(s);
2004 /* More in this chain? */
2005 if (next)
2006 return next;
2007 /* Look for next non-empty chain. */
2008 for ((*i)++; *i <= UNIX_HASH_SIZE; (*i)++) {
2009 if (!hlist_empty(&unix_socket_table[*i]))
2010 return __sk_head(&unix_socket_table[*i]);
2011 }
2012 return NULL;
2013}
2014
2015struct unix_iter_state {
2016 struct seq_net_private p;
2017 int i;
2018};
2019static struct sock *unix_seq_idx(struct unix_iter_state *iter, loff_t pos)
2010{ 2020{
2011 loff_t off = 0; 2021 loff_t off = 0;
2012 struct sock *s; 2022 struct sock *s;
2013 2023
2014 for (s = first_unix_socket(iter); s; s = next_unix_socket(iter, s)) { 2024 for (s = first_unix_socket(&iter->i); s; s = next_unix_socket(&iter->i, s)) {
2025 if (s->sk_net != iter->p.net)
2026 continue;
2015 if (off == pos) 2027 if (off == pos)
2016 return s; 2028 return s;
2017 ++off; 2029 ++off;
@@ -2021,21 +2033,30 @@ static struct sock *unix_seq_idx(int *iter, loff_t pos)
2021 2033
2022 2034
2023static void *unix_seq_start(struct seq_file *seq, loff_t *pos) 2035static void *unix_seq_start(struct seq_file *seq, loff_t *pos)
2036 __acquires(unix_table_lock)
2024{ 2037{
2038 struct unix_iter_state *iter = seq->private;
2025 spin_lock(&unix_table_lock); 2039 spin_lock(&unix_table_lock);
2026 return *pos ? unix_seq_idx(seq->private, *pos - 1) : ((void *) 1); 2040 return *pos ? unix_seq_idx(iter, *pos - 1) : ((void *) 1);
2027} 2041}
2028 2042
2029static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos) 2043static void *unix_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2030{ 2044{
2045 struct unix_iter_state *iter = seq->private;
2046 struct sock *sk = v;
2031 ++*pos; 2047 ++*pos;
2032 2048
2033 if (v == (void *)1) 2049 if (v == (void *)1)
2034 return first_unix_socket(seq->private); 2050 sk = first_unix_socket(&iter->i);
2035 return next_unix_socket(seq->private, v); 2051 else
2052 sk = next_unix_socket(&iter->i, sk);
2053 while (sk && (sk->sk_net != iter->p.net))
2054 sk = next_unix_socket(&iter->i, sk);
2055 return sk;
2036} 2056}
2037 2057
2038static void unix_seq_stop(struct seq_file *seq, void *v) 2058static void unix_seq_stop(struct seq_file *seq, void *v)
2059 __releases(unix_table_lock)
2039{ 2060{
2040 spin_unlock(&unix_table_lock); 2061 spin_unlock(&unix_table_lock);
2041} 2062}
@@ -2094,7 +2115,8 @@ static const struct seq_operations unix_seq_ops = {
2094 2115
2095static int unix_seq_open(struct inode *inode, struct file *file) 2116static int unix_seq_open(struct inode *inode, struct file *file)
2096{ 2117{
2097 return seq_open_private(file, &unix_seq_ops, sizeof(int)); 2118 return seq_open_net(inode, file, &unix_seq_ops,
2119 sizeof(struct unix_iter_state));
2098} 2120}
2099 2121
2100static const struct file_operations unix_seq_fops = { 2122static const struct file_operations unix_seq_fops = {
@@ -2102,7 +2124,7 @@ static const struct file_operations unix_seq_fops = {
2102 .open = unix_seq_open, 2124 .open = unix_seq_open,
2103 .read = seq_read, 2125 .read = seq_read,
2104 .llseek = seq_lseek, 2126 .llseek = seq_lseek,
2105 .release = seq_release_private, 2127 .release = seq_release_net,
2106}; 2128};
2107 2129
2108#endif 2130#endif
@@ -2113,6 +2135,37 @@ static struct net_proto_family unix_family_ops = {
2113 .owner = THIS_MODULE, 2135 .owner = THIS_MODULE,
2114}; 2136};
2115 2137
2138
2139static int unix_net_init(struct net *net)
2140{
2141 int error = -ENOMEM;
2142
2143 net->unx.sysctl_max_dgram_qlen = 10;
2144 if (unix_sysctl_register(net))
2145 goto out;
2146
2147#ifdef CONFIG_PROC_FS
2148 if (!proc_net_fops_create(net, "unix", 0, &unix_seq_fops)) {
2149 unix_sysctl_unregister(net);
2150 goto out;
2151 }
2152#endif
2153 error = 0;
2154out:
2155 return 0;
2156}
2157
2158static void unix_net_exit(struct net *net)
2159{
2160 unix_sysctl_unregister(net);
2161 proc_net_remove(net, "unix");
2162}
2163
2164static struct pernet_operations unix_net_ops = {
2165 .init = unix_net_init,
2166 .exit = unix_net_exit,
2167};
2168
2116static int __init af_unix_init(void) 2169static int __init af_unix_init(void)
2117{ 2170{
2118 int rc = -1; 2171 int rc = -1;
@@ -2128,10 +2181,7 @@ static int __init af_unix_init(void)
2128 } 2181 }
2129 2182
2130 sock_register(&unix_family_ops); 2183 sock_register(&unix_family_ops);
2131#ifdef CONFIG_PROC_FS 2184 register_pernet_subsys(&unix_net_ops);
2132 proc_net_fops_create(&init_net, "unix", 0, &unix_seq_fops);
2133#endif
2134 unix_sysctl_register();
2135out: 2185out:
2136 return rc; 2186 return rc;
2137} 2187}
@@ -2139,9 +2189,8 @@ out:
2139static void __exit af_unix_exit(void) 2189static void __exit af_unix_exit(void)
2140{ 2190{
2141 sock_unregister(PF_UNIX); 2191 sock_unregister(PF_UNIX);
2142 unix_sysctl_unregister();
2143 proc_net_remove(&init_net, "unix");
2144 proto_unregister(&unix_proto); 2192 proto_unregister(&unix_proto);
2193 unregister_pernet_subsys(&unix_net_ops);
2145} 2194}
2146 2195
2147module_init(af_unix_init); 2196module_init(af_unix_init);
diff --git a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c
index eb0bd57ebada..77513d7e35f2 100644
--- a/net/unix/sysctl_net_unix.c
+++ b/net/unix/sysctl_net_unix.c
@@ -18,7 +18,7 @@ static ctl_table unix_table[] = {
18 { 18 {
19 .ctl_name = NET_UNIX_MAX_DGRAM_QLEN, 19 .ctl_name = NET_UNIX_MAX_DGRAM_QLEN,
20 .procname = "max_dgram_qlen", 20 .procname = "max_dgram_qlen",
21 .data = &sysctl_unix_max_dgram_qlen, 21 .data = &init_net.unx.sysctl_max_dgram_qlen,
22 .maxlen = sizeof(int), 22 .maxlen = sizeof(int),
23 .mode = 0644, 23 .mode = 0644,
24 .proc_handler = &proc_dointvec 24 .proc_handler = &proc_dointvec
@@ -26,35 +26,39 @@ static ctl_table unix_table[] = {
26 { .ctl_name = 0 } 26 { .ctl_name = 0 }
27}; 27};
28 28
29static ctl_table unix_net_table[] = { 29static struct ctl_path unix_path[] = {
30 { 30 { .procname = "net", .ctl_name = CTL_NET, },
31 .ctl_name = NET_UNIX, 31 { .procname = "unix", .ctl_name = NET_UNIX, },
32 .procname = "unix", 32 { },
33 .mode = 0555,
34 .child = unix_table
35 },
36 { .ctl_name = 0 }
37}; 33};
38 34
39static ctl_table unix_root_table[] = { 35int unix_sysctl_register(struct net *net)
40 { 36{
41 .ctl_name = CTL_NET, 37 struct ctl_table *table;
42 .procname = "net",
43 .mode = 0555,
44 .child = unix_net_table
45 },
46 { .ctl_name = 0 }
47};
48 38
49static struct ctl_table_header * unix_sysctl_header; 39 table = kmemdup(unix_table, sizeof(unix_table), GFP_KERNEL);
40 if (table == NULL)
41 goto err_alloc;
50 42
51void unix_sysctl_register(void) 43 table[0].data = &net->unx.sysctl_max_dgram_qlen;
52{ 44 net->unx.ctl = register_net_sysctl_table(net, unix_path, table);
53 unix_sysctl_header = register_sysctl_table(unix_root_table); 45 if (net->unx.ctl == NULL)
46 goto err_reg;
47
48 return 0;
49
50err_reg:
51 kfree(table);
52err_alloc:
53 return -ENOMEM;
54} 54}
55 55
56void unix_sysctl_unregister(void) 56void unix_sysctl_unregister(struct net *net)
57{ 57{
58 unregister_sysctl_table(unix_sysctl_header); 58 struct ctl_table *table;
59
60 table = net->unx.ctl->ctl_table_arg;
61 unregister_sysctl_table(net->unx.ctl);
62 kfree(table);
59} 63}
60 64