aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2007-09-12 07:05:38 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:49:09 -0400
commitb4b510290b056b86611757ce1175a230f1080f53 (patch)
tree7bd1d45855ac7457be6d50338c60751f19e436d9 /net/netlink
parente9dc86534051b78e41e5b746cccc291b57a3a311 (diff)
[NET]: Support multiple network namespaces with netlink
Each netlink socket will live in exactly one network namespace, this includes the controlling kernel sockets. This patch updates all of the existing netlink protocols to only support the initial network namespace. Request by clients in other namespaces will get -ECONREFUSED. As they would if the kernel did not have the support for that netlink protocol compiled in. As each netlink protocol is updated to be multiple network namespace safe it can register multiple kernel sockets to acquire a presence in the rest of the network namespaces. The implementation in af_netlink is a simple filter implementation at hash table insertion and hash table look up time. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netlink')
-rw-r--r--net/netlink/af_netlink.c104
-rw-r--r--net/netlink/genetlink.c4
2 files changed, 80 insertions, 28 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
214static __inline__ struct sock *netlink_lookup(int protocol, u32 pid) 214static __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
331static int netlink_insert(struct sock *sk, u32 pid) 331static 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)
509static int netlink_autobind(struct socket *sock) 507static 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)
598static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len) 599static 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)
703static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid) 705static 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
888struct netlink_broadcast_data { 892struct 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:
947int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, 955int 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
1306struct sock * 1319struct sock *
1307netlink_kernel_create(int unit, unsigned int groups, 1320netlink_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
1708struct nl_seq_iter { 1724struct 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
1866static 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
1841static const struct file_operations netlink_seq_fops = { 1874static 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
1921static 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
1930static void netlink_net_exit(struct net *net)
1931{
1932#ifdef CONFIG_PROC_FS
1933 proc_net_remove(net, "netlink");
1934#endif
1935}
1936
1937static struct pernet_operations netlink_net_ops = {
1938 .init = netlink_net_init,
1939 .exit = netlink_net_exit,
1940};
1941
1888static int __init netlink_proto_init(void) 1942static 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();
1938out: 1990out:
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 8c11ca4a2121..af8fe26815fa 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -782,8 +782,8 @@ static int __init genl_init(void)
782 netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV); 782 netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV);
783 783
784 /* we'll bump the group number right afterwards */ 784 /* we'll bump the group number right afterwards */
785 genl_sock = netlink_kernel_create(NETLINK_GENERIC, 0, genl_rcv, 785 genl_sock = netlink_kernel_create(&init_net, NETLINK_GENERIC, 0,
786 NULL, THIS_MODULE); 786 genl_rcv, NULL, THIS_MODULE);
787 if (genl_sock == NULL) 787 if (genl_sock == NULL)
788 panic("GENL: Cannot initialize generic netlink\n"); 788 panic("GENL: Cannot initialize generic netlink\n");
789 789