aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink/af_netlink.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/netlink/af_netlink.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'net/netlink/af_netlink.c')
-rw-r--r--net/netlink/af_netlink.c96
1 files changed, 37 insertions, 59 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index cd96ed3ccee4..6ef64adf7362 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -83,9 +83,9 @@ struct netlink_sock {
83 struct module *module; 83 struct module *module;
84}; 84};
85 85
86struct listeners_rcu_head { 86struct listeners {
87 struct rcu_head rcu_head; 87 struct rcu_head rcu;
88 void *ptr; 88 unsigned long masks[0];
89}; 89};
90 90
91#define NETLINK_KERNEL_SOCKET 0x1 91#define NETLINK_KERNEL_SOCKET 0x1
@@ -119,7 +119,7 @@ struct nl_pid_hash {
119struct netlink_table { 119struct netlink_table {
120 struct nl_pid_hash hash; 120 struct nl_pid_hash hash;
121 struct hlist_head mc_list; 121 struct hlist_head mc_list;
122 unsigned long *listeners; 122 struct listeners __rcu *listeners;
123 unsigned int nl_nonroot; 123 unsigned int nl_nonroot;
124 unsigned int groups; 124 unsigned int groups;
125 struct mutex *cb_mutex; 125 struct mutex *cb_mutex;
@@ -338,7 +338,7 @@ netlink_update_listeners(struct sock *sk)
338 if (i < NLGRPLONGS(nlk_sk(sk)->ngroups)) 338 if (i < NLGRPLONGS(nlk_sk(sk)->ngroups))
339 mask |= nlk_sk(sk)->groups[i]; 339 mask |= nlk_sk(sk)->groups[i];
340 } 340 }
341 tbl->listeners[i] = mask; 341 tbl->listeners->masks[i] = mask;
342 } 342 }
343 /* this function is only called with the netlink table "grabbed", which 343 /* this function is only called with the netlink table "grabbed", which
344 * makes sure updates are visible before bind or setsockopt return. */ 344 * makes sure updates are visible before bind or setsockopt return. */
@@ -936,7 +936,7 @@ EXPORT_SYMBOL(netlink_unicast);
936int netlink_has_listeners(struct sock *sk, unsigned int group) 936int netlink_has_listeners(struct sock *sk, unsigned int group)
937{ 937{
938 int res = 0; 938 int res = 0;
939 unsigned long *listeners; 939 struct listeners *listeners;
940 940
941 BUG_ON(!netlink_is_kernel(sk)); 941 BUG_ON(!netlink_is_kernel(sk));
942 942
@@ -944,7 +944,7 @@ int netlink_has_listeners(struct sock *sk, unsigned int group)
944 listeners = rcu_dereference(nl_table[sk->sk_protocol].listeners); 944 listeners = rcu_dereference(nl_table[sk->sk_protocol].listeners);
945 945
946 if (group - 1 < nl_table[sk->sk_protocol].groups) 946 if (group - 1 < nl_table[sk->sk_protocol].groups)
947 res = test_bit(group - 1, listeners); 947 res = test_bit(group - 1, listeners->masks);
948 948
949 rcu_read_unlock(); 949 rcu_read_unlock();
950 950
@@ -1362,17 +1362,8 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
1362 1362
1363 NETLINK_CB(skb).pid = nlk->pid; 1363 NETLINK_CB(skb).pid = nlk->pid;
1364 NETLINK_CB(skb).dst_group = dst_group; 1364 NETLINK_CB(skb).dst_group = dst_group;
1365 NETLINK_CB(skb).loginuid = audit_get_loginuid(current);
1366 NETLINK_CB(skb).sessionid = audit_get_sessionid(current);
1367 security_task_getsecid(current, &(NETLINK_CB(skb).sid));
1368 memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); 1365 memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
1369 1366
1370 /* What can I do? Netlink is asynchronous, so that
1371 we will have to save current capabilities to
1372 check them, when this message will be delivered
1373 to corresponding kernel module. --ANK (980802)
1374 */
1375
1376 err = -EFAULT; 1367 err = -EFAULT;
1377 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) { 1368 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
1378 kfree_skb(skb); 1369 kfree_skb(skb);
@@ -1407,7 +1398,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
1407 int noblock = flags&MSG_DONTWAIT; 1398 int noblock = flags&MSG_DONTWAIT;
1408 size_t copied; 1399 size_t copied;
1409 struct sk_buff *skb, *data_skb; 1400 struct sk_buff *skb, *data_skb;
1410 int err; 1401 int err, ret;
1411 1402
1412 if (flags&MSG_OOB) 1403 if (flags&MSG_OOB)
1413 return -EOPNOTSUPP; 1404 return -EOPNOTSUPP;
@@ -1470,8 +1461,13 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
1470 1461
1471 skb_free_datagram(sk, skb); 1462 skb_free_datagram(sk, skb);
1472 1463
1473 if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) 1464 if (nlk->cb && atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
1474 netlink_dump(sk); 1465 ret = netlink_dump(sk);
1466 if (ret) {
1467 sk->sk_err = ret;
1468 sk->sk_error_report(sk);
1469 }
1470 }
1475 1471
1476 scm_recv(sock, msg, siocb->scm, flags); 1472 scm_recv(sock, msg, siocb->scm, flags);
1477out: 1473out:
@@ -1498,7 +1494,7 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
1498 struct socket *sock; 1494 struct socket *sock;
1499 struct sock *sk; 1495 struct sock *sk;
1500 struct netlink_sock *nlk; 1496 struct netlink_sock *nlk;
1501 unsigned long *listeners = NULL; 1497 struct listeners *listeners = NULL;
1502 1498
1503 BUG_ON(!nl_table); 1499 BUG_ON(!nl_table);
1504 1500
@@ -1523,8 +1519,7 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
1523 if (groups < 32) 1519 if (groups < 32)
1524 groups = 32; 1520 groups = 32;
1525 1521
1526 listeners = kzalloc(NLGRPSZ(groups) + sizeof(struct listeners_rcu_head), 1522 listeners = kzalloc(sizeof(*listeners) + NLGRPSZ(groups), GFP_KERNEL);
1527 GFP_KERNEL);
1528 if (!listeners) 1523 if (!listeners)
1529 goto out_sock_release; 1524 goto out_sock_release;
1530 1525
@@ -1541,7 +1536,7 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
1541 netlink_table_grab(); 1536 netlink_table_grab();
1542 if (!nl_table[unit].registered) { 1537 if (!nl_table[unit].registered) {
1543 nl_table[unit].groups = groups; 1538 nl_table[unit].groups = groups;
1544 nl_table[unit].listeners = listeners; 1539 rcu_assign_pointer(nl_table[unit].listeners, listeners);
1545 nl_table[unit].cb_mutex = cb_mutex; 1540 nl_table[unit].cb_mutex = cb_mutex;
1546 nl_table[unit].module = module; 1541 nl_table[unit].module = module;
1547 nl_table[unit].registered = 1; 1542 nl_table[unit].registered = 1;
@@ -1571,44 +1566,23 @@ netlink_kernel_release(struct sock *sk)
1571} 1566}
1572EXPORT_SYMBOL(netlink_kernel_release); 1567EXPORT_SYMBOL(netlink_kernel_release);
1573 1568
1574
1575static void netlink_free_old_listeners(struct rcu_head *rcu_head)
1576{
1577 struct listeners_rcu_head *lrh;
1578
1579 lrh = container_of(rcu_head, struct listeners_rcu_head, rcu_head);
1580 kfree(lrh->ptr);
1581}
1582
1583int __netlink_change_ngroups(struct sock *sk, unsigned int groups) 1569int __netlink_change_ngroups(struct sock *sk, unsigned int groups)
1584{ 1570{
1585 unsigned long *listeners, *old = NULL; 1571 struct listeners *new, *old;
1586 struct listeners_rcu_head *old_rcu_head;
1587 struct netlink_table *tbl = &nl_table[sk->sk_protocol]; 1572 struct netlink_table *tbl = &nl_table[sk->sk_protocol];
1588 1573
1589 if (groups < 32) 1574 if (groups < 32)
1590 groups = 32; 1575 groups = 32;
1591 1576
1592 if (NLGRPSZ(tbl->groups) < NLGRPSZ(groups)) { 1577 if (NLGRPSZ(tbl->groups) < NLGRPSZ(groups)) {
1593 listeners = kzalloc(NLGRPSZ(groups) + 1578 new = kzalloc(sizeof(*new) + NLGRPSZ(groups), GFP_ATOMIC);
1594 sizeof(struct listeners_rcu_head), 1579 if (!new)
1595 GFP_ATOMIC);
1596 if (!listeners)
1597 return -ENOMEM; 1580 return -ENOMEM;
1598 old = tbl->listeners; 1581 old = rcu_dereference_raw(tbl->listeners);
1599 memcpy(listeners, old, NLGRPSZ(tbl->groups)); 1582 memcpy(new->masks, old->masks, NLGRPSZ(tbl->groups));
1600 rcu_assign_pointer(tbl->listeners, listeners); 1583 rcu_assign_pointer(tbl->listeners, new);
1601 /* 1584
1602 * Free the old memory after an RCU grace period so we 1585 kfree_rcu(old, rcu);
1603 * don't leak it. We use call_rcu() here in order to be
1604 * able to call this function from atomic contexts. The
1605 * allocation of this memory will have reserved enough
1606 * space for struct listeners_rcu_head at the end.
1607 */
1608 old_rcu_head = (void *)(tbl->listeners +
1609 NLGRPLONGS(tbl->groups));
1610 old_rcu_head->ptr = old;
1611 call_rcu(&old_rcu_head->rcu_head, netlink_free_old_listeners);
1612 } 1586 }
1613 tbl->groups = groups; 1587 tbl->groups = groups;
1614 1588
@@ -1752,6 +1726,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
1752 struct netlink_callback *cb; 1726 struct netlink_callback *cb;
1753 struct sock *sk; 1727 struct sock *sk;
1754 struct netlink_sock *nlk; 1728 struct netlink_sock *nlk;
1729 int ret;
1755 1730
1756 cb = kzalloc(sizeof(*cb), GFP_KERNEL); 1731 cb = kzalloc(sizeof(*cb), GFP_KERNEL);
1757 if (cb == NULL) 1732 if (cb == NULL)
@@ -1780,9 +1755,13 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
1780 nlk->cb = cb; 1755 nlk->cb = cb;
1781 mutex_unlock(nlk->cb_mutex); 1756 mutex_unlock(nlk->cb_mutex);
1782 1757
1783 netlink_dump(sk); 1758 ret = netlink_dump(sk);
1759
1784 sock_put(sk); 1760 sock_put(sk);
1785 1761
1762 if (ret)
1763 return ret;
1764
1786 /* We successfully started a dump, by returning -EINTR we 1765 /* We successfully started a dump, by returning -EINTR we
1787 * signal not to send ACK even if it was requested. 1766 * signal not to send ACK even if it was requested.
1788 */ 1767 */
@@ -2006,7 +1985,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
2006 struct sock *s = v; 1985 struct sock *s = v;
2007 struct netlink_sock *nlk = nlk_sk(s); 1986 struct netlink_sock *nlk = nlk_sk(s);
2008 1987
2009 seq_printf(seq, "%p %-3d %-6d %08x %-8d %-8d %p %-8d %-8d %-8lu\n", 1988 seq_printf(seq, "%pK %-3d %-6d %08x %-8d %-8d %pK %-8d %-8d %-8lu\n",
2010 s, 1989 s,
2011 s->sk_protocol, 1990 s->sk_protocol,
2012 nlk->pid, 1991 nlk->pid,
@@ -2104,18 +2083,17 @@ static void __net_exit netlink_net_exit(struct net *net)
2104 2083
2105static void __init netlink_add_usersock_entry(void) 2084static void __init netlink_add_usersock_entry(void)
2106{ 2085{
2107 unsigned long *listeners; 2086 struct listeners *listeners;
2108 int groups = 32; 2087 int groups = 32;
2109 2088
2110 listeners = kzalloc(NLGRPSZ(groups) + sizeof(struct listeners_rcu_head), 2089 listeners = kzalloc(sizeof(*listeners) + NLGRPSZ(groups), GFP_KERNEL);
2111 GFP_KERNEL);
2112 if (!listeners) 2090 if (!listeners)
2113 panic("netlink_add_usersock_entry: Cannot allocate listneres\n"); 2091 panic("netlink_add_usersock_entry: Cannot allocate listeners\n");
2114 2092
2115 netlink_table_grab(); 2093 netlink_table_grab();
2116 2094
2117 nl_table[NETLINK_USERSOCK].groups = groups; 2095 nl_table[NETLINK_USERSOCK].groups = groups;
2118 nl_table[NETLINK_USERSOCK].listeners = listeners; 2096 rcu_assign_pointer(nl_table[NETLINK_USERSOCK].listeners, listeners);
2119 nl_table[NETLINK_USERSOCK].module = THIS_MODULE; 2097 nl_table[NETLINK_USERSOCK].module = THIS_MODULE;
2120 nl_table[NETLINK_USERSOCK].registered = 1; 2098 nl_table[NETLINK_USERSOCK].registered = 1;
2121 2099