diff options
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r-- | net/netlink/af_netlink.c | 104 |
1 files changed, 78 insertions, 26 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 406a493300d8..3029f865cd61 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -211,7 +211,7 @@ netlink_unlock_table(void) | |||
211 | wake_up(&nl_table_wait); | 211 | wake_up(&nl_table_wait); |
212 | } | 212 | } |
213 | 213 | ||
214 | static __inline__ struct sock *netlink_lookup(int protocol, u32 pid) | 214 | static __inline__ struct sock *netlink_lookup(struct net *net, int protocol, u32 pid) |
215 | { | 215 | { |
216 | struct nl_pid_hash *hash = &nl_table[protocol].hash; | 216 | struct nl_pid_hash *hash = &nl_table[protocol].hash; |
217 | struct hlist_head *head; | 217 | struct hlist_head *head; |
@@ -221,7 +221,7 @@ static __inline__ struct sock *netlink_lookup(int protocol, u32 pid) | |||
221 | read_lock(&nl_table_lock); | 221 | read_lock(&nl_table_lock); |
222 | head = nl_pid_hashfn(hash, pid); | 222 | head = nl_pid_hashfn(hash, pid); |
223 | sk_for_each(sk, node, head) { | 223 | sk_for_each(sk, node, head) { |
224 | if (nlk_sk(sk)->pid == pid) { | 224 | if ((sk->sk_net == net) && (nlk_sk(sk)->pid == pid)) { |
225 | sock_hold(sk); | 225 | sock_hold(sk); |
226 | goto found; | 226 | goto found; |
227 | } | 227 | } |
@@ -328,7 +328,7 @@ netlink_update_listeners(struct sock *sk) | |||
328 | * makes sure updates are visible before bind or setsockopt return. */ | 328 | * makes sure updates are visible before bind or setsockopt return. */ |
329 | } | 329 | } |
330 | 330 | ||
331 | static int netlink_insert(struct sock *sk, u32 pid) | 331 | static int netlink_insert(struct sock *sk, struct net *net, u32 pid) |
332 | { | 332 | { |
333 | struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash; | 333 | struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash; |
334 | struct hlist_head *head; | 334 | struct hlist_head *head; |
@@ -341,7 +341,7 @@ static int netlink_insert(struct sock *sk, u32 pid) | |||
341 | head = nl_pid_hashfn(hash, pid); | 341 | head = nl_pid_hashfn(hash, pid); |
342 | len = 0; | 342 | len = 0; |
343 | sk_for_each(osk, node, head) { | 343 | sk_for_each(osk, node, head) { |
344 | if (nlk_sk(osk)->pid == pid) | 344 | if ((osk->sk_net == net) && (nlk_sk(osk)->pid == pid)) |
345 | break; | 345 | break; |
346 | len++; | 346 | len++; |
347 | } | 347 | } |
@@ -419,9 +419,6 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol) | |||
419 | struct netlink_sock *nlk; | 419 | struct netlink_sock *nlk; |
420 | int err = 0; | 420 | int err = 0; |
421 | 421 | ||
422 | if (net != &init_net) | ||
423 | return -EAFNOSUPPORT; | ||
424 | |||
425 | sock->state = SS_UNCONNECTED; | 422 | sock->state = SS_UNCONNECTED; |
426 | 423 | ||
427 | if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) | 424 | if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) |
@@ -481,6 +478,7 @@ static int netlink_release(struct socket *sock) | |||
481 | 478 | ||
482 | if (nlk->pid && !nlk->subscriptions) { | 479 | if (nlk->pid && !nlk->subscriptions) { |
483 | struct netlink_notify n = { | 480 | struct netlink_notify n = { |
481 | .net = sk->sk_net, | ||
484 | .protocol = sk->sk_protocol, | 482 | .protocol = sk->sk_protocol, |
485 | .pid = nlk->pid, | 483 | .pid = nlk->pid, |
486 | }; | 484 | }; |
@@ -509,6 +507,7 @@ static int netlink_release(struct socket *sock) | |||
509 | static int netlink_autobind(struct socket *sock) | 507 | static int netlink_autobind(struct socket *sock) |
510 | { | 508 | { |
511 | struct sock *sk = sock->sk; | 509 | struct sock *sk = sock->sk; |
510 | struct net *net = sk->sk_net; | ||
512 | struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash; | 511 | struct nl_pid_hash *hash = &nl_table[sk->sk_protocol].hash; |
513 | struct hlist_head *head; | 512 | struct hlist_head *head; |
514 | struct sock *osk; | 513 | struct sock *osk; |
@@ -522,6 +521,8 @@ retry: | |||
522 | netlink_table_grab(); | 521 | netlink_table_grab(); |
523 | head = nl_pid_hashfn(hash, pid); | 522 | head = nl_pid_hashfn(hash, pid); |
524 | sk_for_each(osk, node, head) { | 523 | sk_for_each(osk, node, head) { |
524 | if ((osk->sk_net != net)) | ||
525 | continue; | ||
525 | if (nlk_sk(osk)->pid == pid) { | 526 | if (nlk_sk(osk)->pid == pid) { |
526 | /* Bind collision, search negative pid values. */ | 527 | /* Bind collision, search negative pid values. */ |
527 | pid = rover--; | 528 | pid = rover--; |
@@ -533,7 +534,7 @@ retry: | |||
533 | } | 534 | } |
534 | netlink_table_ungrab(); | 535 | netlink_table_ungrab(); |
535 | 536 | ||
536 | err = netlink_insert(sk, pid); | 537 | err = netlink_insert(sk, net, pid); |
537 | if (err == -EADDRINUSE) | 538 | if (err == -EADDRINUSE) |
538 | goto retry; | 539 | goto retry; |
539 | 540 | ||
@@ -598,6 +599,7 @@ static int netlink_realloc_groups(struct sock *sk) | |||
598 | static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len) | 599 | static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len) |
599 | { | 600 | { |
600 | struct sock *sk = sock->sk; | 601 | struct sock *sk = sock->sk; |
602 | struct net *net = sk->sk_net; | ||
601 | struct netlink_sock *nlk = nlk_sk(sk); | 603 | struct netlink_sock *nlk = nlk_sk(sk); |
602 | struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr; | 604 | struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr; |
603 | int err; | 605 | int err; |
@@ -619,7 +621,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len | |||
619 | return -EINVAL; | 621 | return -EINVAL; |
620 | } else { | 622 | } else { |
621 | err = nladdr->nl_pid ? | 623 | err = nladdr->nl_pid ? |
622 | netlink_insert(sk, nladdr->nl_pid) : | 624 | netlink_insert(sk, net, nladdr->nl_pid) : |
623 | netlink_autobind(sock); | 625 | netlink_autobind(sock); |
624 | if (err) | 626 | if (err) |
625 | return err; | 627 | return err; |
@@ -703,10 +705,12 @@ static void netlink_overrun(struct sock *sk) | |||
703 | static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid) | 705 | static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid) |
704 | { | 706 | { |
705 | int protocol = ssk->sk_protocol; | 707 | int protocol = ssk->sk_protocol; |
708 | struct net *net; | ||
706 | struct sock *sock; | 709 | struct sock *sock; |
707 | struct netlink_sock *nlk; | 710 | struct netlink_sock *nlk; |
708 | 711 | ||
709 | sock = netlink_lookup(protocol, pid); | 712 | net = ssk->sk_net; |
713 | sock = netlink_lookup(net, protocol, pid); | ||
710 | if (!sock) | 714 | if (!sock) |
711 | return ERR_PTR(-ECONNREFUSED); | 715 | return ERR_PTR(-ECONNREFUSED); |
712 | 716 | ||
@@ -887,6 +891,7 @@ static __inline__ int netlink_broadcast_deliver(struct sock *sk, struct sk_buff | |||
887 | 891 | ||
888 | struct netlink_broadcast_data { | 892 | struct netlink_broadcast_data { |
889 | struct sock *exclude_sk; | 893 | struct sock *exclude_sk; |
894 | struct net *net; | ||
890 | u32 pid; | 895 | u32 pid; |
891 | u32 group; | 896 | u32 group; |
892 | int failure; | 897 | int failure; |
@@ -909,6 +914,9 @@ static inline int do_one_broadcast(struct sock *sk, | |||
909 | !test_bit(p->group - 1, nlk->groups)) | 914 | !test_bit(p->group - 1, nlk->groups)) |
910 | goto out; | 915 | goto out; |
911 | 916 | ||
917 | if ((sk->sk_net != p->net)) | ||
918 | goto out; | ||
919 | |||
912 | if (p->failure) { | 920 | if (p->failure) { |
913 | netlink_overrun(sk); | 921 | netlink_overrun(sk); |
914 | goto out; | 922 | goto out; |
@@ -947,6 +955,7 @@ out: | |||
947 | int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, | 955 | int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, |
948 | u32 group, gfp_t allocation) | 956 | u32 group, gfp_t allocation) |
949 | { | 957 | { |
958 | struct net *net = ssk->sk_net; | ||
950 | struct netlink_broadcast_data info; | 959 | struct netlink_broadcast_data info; |
951 | struct hlist_node *node; | 960 | struct hlist_node *node; |
952 | struct sock *sk; | 961 | struct sock *sk; |
@@ -954,6 +963,7 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, | |||
954 | skb = netlink_trim(skb, allocation); | 963 | skb = netlink_trim(skb, allocation); |
955 | 964 | ||
956 | info.exclude_sk = ssk; | 965 | info.exclude_sk = ssk; |
966 | info.net = net; | ||
957 | info.pid = pid; | 967 | info.pid = pid; |
958 | info.group = group; | 968 | info.group = group; |
959 | info.failure = 0; | 969 | info.failure = 0; |
@@ -1002,6 +1012,9 @@ static inline int do_one_set_err(struct sock *sk, | |||
1002 | if (sk == p->exclude_sk) | 1012 | if (sk == p->exclude_sk) |
1003 | goto out; | 1013 | goto out; |
1004 | 1014 | ||
1015 | if (sk->sk_net != p->exclude_sk->sk_net) | ||
1016 | goto out; | ||
1017 | |||
1005 | if (nlk->pid == p->pid || p->group - 1 >= nlk->ngroups || | 1018 | if (nlk->pid == p->pid || p->group - 1 >= nlk->ngroups || |
1006 | !test_bit(p->group - 1, nlk->groups)) | 1019 | !test_bit(p->group - 1, nlk->groups)) |
1007 | goto out; | 1020 | goto out; |
@@ -1304,7 +1317,7 @@ static void netlink_data_ready(struct sock *sk, int len) | |||
1304 | */ | 1317 | */ |
1305 | 1318 | ||
1306 | struct sock * | 1319 | struct sock * |
1307 | netlink_kernel_create(int unit, unsigned int groups, | 1320 | netlink_kernel_create(struct net *net, int unit, unsigned int groups, |
1308 | void (*input)(struct sock *sk, int len), | 1321 | void (*input)(struct sock *sk, int len), |
1309 | struct mutex *cb_mutex, struct module *module) | 1322 | struct mutex *cb_mutex, struct module *module) |
1310 | { | 1323 | { |
@@ -1321,7 +1334,7 @@ netlink_kernel_create(int unit, unsigned int groups, | |||
1321 | if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock)) | 1334 | if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock)) |
1322 | return NULL; | 1335 | return NULL; |
1323 | 1336 | ||
1324 | if (__netlink_create(&init_net, sock, cb_mutex, unit) < 0) | 1337 | if (__netlink_create(net, sock, cb_mutex, unit) < 0) |
1325 | goto out_sock_release; | 1338 | goto out_sock_release; |
1326 | 1339 | ||
1327 | if (groups < 32) | 1340 | if (groups < 32) |
@@ -1336,18 +1349,20 @@ netlink_kernel_create(int unit, unsigned int groups, | |||
1336 | if (input) | 1349 | if (input) |
1337 | nlk_sk(sk)->data_ready = input; | 1350 | nlk_sk(sk)->data_ready = input; |
1338 | 1351 | ||
1339 | if (netlink_insert(sk, 0)) | 1352 | if (netlink_insert(sk, net, 0)) |
1340 | goto out_sock_release; | 1353 | goto out_sock_release; |
1341 | 1354 | ||
1342 | nlk = nlk_sk(sk); | 1355 | nlk = nlk_sk(sk); |
1343 | nlk->flags |= NETLINK_KERNEL_SOCKET; | 1356 | nlk->flags |= NETLINK_KERNEL_SOCKET; |
1344 | 1357 | ||
1345 | netlink_table_grab(); | 1358 | netlink_table_grab(); |
1346 | nl_table[unit].groups = groups; | 1359 | if (!nl_table[unit].registered) { |
1347 | nl_table[unit].listeners = listeners; | 1360 | nl_table[unit].groups = groups; |
1348 | nl_table[unit].cb_mutex = cb_mutex; | 1361 | nl_table[unit].listeners = listeners; |
1349 | nl_table[unit].module = module; | 1362 | nl_table[unit].cb_mutex = cb_mutex; |
1350 | nl_table[unit].registered = 1; | 1363 | nl_table[unit].module = module; |
1364 | nl_table[unit].registered = 1; | ||
1365 | } | ||
1351 | netlink_table_ungrab(); | 1366 | netlink_table_ungrab(); |
1352 | 1367 | ||
1353 | return sk; | 1368 | return sk; |
@@ -1513,7 +1528,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, | |||
1513 | atomic_inc(&skb->users); | 1528 | atomic_inc(&skb->users); |
1514 | cb->skb = skb; | 1529 | cb->skb = skb; |
1515 | 1530 | ||
1516 | sk = netlink_lookup(ssk->sk_protocol, NETLINK_CB(skb).pid); | 1531 | sk = netlink_lookup(ssk->sk_net, ssk->sk_protocol, NETLINK_CB(skb).pid); |
1517 | if (sk == NULL) { | 1532 | if (sk == NULL) { |
1518 | netlink_destroy_callback(cb); | 1533 | netlink_destroy_callback(cb); |
1519 | return -ECONNREFUSED; | 1534 | return -ECONNREFUSED; |
@@ -1555,7 +1570,8 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) | |||
1555 | if (!skb) { | 1570 | if (!skb) { |
1556 | struct sock *sk; | 1571 | struct sock *sk; |
1557 | 1572 | ||
1558 | sk = netlink_lookup(in_skb->sk->sk_protocol, | 1573 | sk = netlink_lookup(in_skb->sk->sk_net, |
1574 | in_skb->sk->sk_protocol, | ||
1559 | NETLINK_CB(in_skb).pid); | 1575 | NETLINK_CB(in_skb).pid); |
1560 | if (sk) { | 1576 | if (sk) { |
1561 | sk->sk_err = ENOBUFS; | 1577 | sk->sk_err = ENOBUFS; |
@@ -1706,6 +1722,7 @@ int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid, | |||
1706 | 1722 | ||
1707 | #ifdef CONFIG_PROC_FS | 1723 | #ifdef CONFIG_PROC_FS |
1708 | struct nl_seq_iter { | 1724 | struct nl_seq_iter { |
1725 | struct net *net; | ||
1709 | int link; | 1726 | int link; |
1710 | int hash_idx; | 1727 | int hash_idx; |
1711 | }; | 1728 | }; |
@@ -1723,6 +1740,8 @@ static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos) | |||
1723 | 1740 | ||
1724 | for (j = 0; j <= hash->mask; j++) { | 1741 | for (j = 0; j <= hash->mask; j++) { |
1725 | sk_for_each(s, node, &hash->table[j]) { | 1742 | sk_for_each(s, node, &hash->table[j]) { |
1743 | if (iter->net != s->sk_net) | ||
1744 | continue; | ||
1726 | if (off == pos) { | 1745 | if (off == pos) { |
1727 | iter->link = i; | 1746 | iter->link = i; |
1728 | iter->hash_idx = j; | 1747 | iter->hash_idx = j; |
@@ -1752,11 +1771,14 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
1752 | if (v == SEQ_START_TOKEN) | 1771 | if (v == SEQ_START_TOKEN) |
1753 | return netlink_seq_socket_idx(seq, 0); | 1772 | return netlink_seq_socket_idx(seq, 0); |
1754 | 1773 | ||
1755 | s = sk_next(v); | 1774 | iter = seq->private; |
1775 | s = v; | ||
1776 | do { | ||
1777 | s = sk_next(s); | ||
1778 | } while (s && (iter->net != s->sk_net)); | ||
1756 | if (s) | 1779 | if (s) |
1757 | return s; | 1780 | return s; |
1758 | 1781 | ||
1759 | iter = seq->private; | ||
1760 | i = iter->link; | 1782 | i = iter->link; |
1761 | j = iter->hash_idx + 1; | 1783 | j = iter->hash_idx + 1; |
1762 | 1784 | ||
@@ -1765,6 +1787,8 @@ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
1765 | 1787 | ||
1766 | for (; j <= hash->mask; j++) { | 1788 | for (; j <= hash->mask; j++) { |
1767 | s = sk_head(&hash->table[j]); | 1789 | s = sk_head(&hash->table[j]); |
1790 | while (s && (iter->net != s->sk_net)) | ||
1791 | s = sk_next(s); | ||
1768 | if (s) { | 1792 | if (s) { |
1769 | iter->link = i; | 1793 | iter->link = i; |
1770 | iter->hash_idx = j; | 1794 | iter->hash_idx = j; |
@@ -1835,15 +1859,24 @@ static int netlink_seq_open(struct inode *inode, struct file *file) | |||
1835 | 1859 | ||
1836 | seq = file->private_data; | 1860 | seq = file->private_data; |
1837 | seq->private = iter; | 1861 | seq->private = iter; |
1862 | iter->net = get_net(PROC_NET(inode)); | ||
1838 | return 0; | 1863 | return 0; |
1839 | } | 1864 | } |
1840 | 1865 | ||
1866 | static int netlink_seq_release(struct inode *inode, struct file *file) | ||
1867 | { | ||
1868 | struct seq_file *seq = file->private_data; | ||
1869 | struct nl_seq_iter *iter = seq->private; | ||
1870 | put_net(iter->net); | ||
1871 | return seq_release_private(inode, file); | ||
1872 | } | ||
1873 | |||
1841 | static const struct file_operations netlink_seq_fops = { | 1874 | static const struct file_operations netlink_seq_fops = { |
1842 | .owner = THIS_MODULE, | 1875 | .owner = THIS_MODULE, |
1843 | .open = netlink_seq_open, | 1876 | .open = netlink_seq_open, |
1844 | .read = seq_read, | 1877 | .read = seq_read, |
1845 | .llseek = seq_lseek, | 1878 | .llseek = seq_lseek, |
1846 | .release = seq_release_private, | 1879 | .release = netlink_seq_release, |
1847 | }; | 1880 | }; |
1848 | 1881 | ||
1849 | #endif | 1882 | #endif |
@@ -1885,6 +1918,27 @@ static struct net_proto_family netlink_family_ops = { | |||
1885 | .owner = THIS_MODULE, /* for consistency 8) */ | 1918 | .owner = THIS_MODULE, /* for consistency 8) */ |
1886 | }; | 1919 | }; |
1887 | 1920 | ||
1921 | static int netlink_net_init(struct net *net) | ||
1922 | { | ||
1923 | #ifdef CONFIG_PROC_FS | ||
1924 | if (!proc_net_fops_create(net, "netlink", 0, &netlink_seq_fops)) | ||
1925 | return -ENOMEM; | ||
1926 | #endif | ||
1927 | return 0; | ||
1928 | } | ||
1929 | |||
1930 | static void netlink_net_exit(struct net *net) | ||
1931 | { | ||
1932 | #ifdef CONFIG_PROC_FS | ||
1933 | proc_net_remove(net, "netlink"); | ||
1934 | #endif | ||
1935 | } | ||
1936 | |||
1937 | static struct pernet_operations netlink_net_ops = { | ||
1938 | .init = netlink_net_init, | ||
1939 | .exit = netlink_net_exit, | ||
1940 | }; | ||
1941 | |||
1888 | static int __init netlink_proto_init(void) | 1942 | static int __init netlink_proto_init(void) |
1889 | { | 1943 | { |
1890 | struct sk_buff *dummy_skb; | 1944 | struct sk_buff *dummy_skb; |
@@ -1930,9 +1984,7 @@ static int __init netlink_proto_init(void) | |||
1930 | } | 1984 | } |
1931 | 1985 | ||
1932 | sock_register(&netlink_family_ops); | 1986 | sock_register(&netlink_family_ops); |
1933 | #ifdef CONFIG_PROC_FS | 1987 | register_pernet_subsys(&netlink_net_ops); |
1934 | proc_net_fops_create(&init_net, "netlink", 0, &netlink_seq_fops); | ||
1935 | #endif | ||
1936 | /* The netlink device handler may be needed early. */ | 1988 | /* The netlink device handler may be needed early. */ |
1937 | rtnetlink_init(); | 1989 | rtnetlink_init(); |
1938 | out: | 1990 | out: |