aboutsummaryrefslogtreecommitdiffstats
path: root/net/netlink
diff options
context:
space:
mode:
Diffstat (limited to 'net/netlink')
-rw-r--r--net/netlink/af_netlink.c81
1 files changed, 43 insertions, 38 deletions
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 1518244ffad9..2e02b19e4552 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -156,7 +156,7 @@ static void netlink_sock_destruct(struct sock *sk)
156 skb_queue_purge(&sk->sk_receive_queue); 156 skb_queue_purge(&sk->sk_receive_queue);
157 157
158 if (!sock_flag(sk, SOCK_DEAD)) { 158 if (!sock_flag(sk, SOCK_DEAD)) {
159 printk("Freeing alive netlink socket %p\n", sk); 159 printk(KERN_ERR "Freeing alive netlink socket %p\n", sk);
160 return; 160 return;
161 } 161 }
162 BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc)); 162 BUG_TRAP(!atomic_read(&sk->sk_rmem_alloc));
@@ -164,8 +164,8 @@ static void netlink_sock_destruct(struct sock *sk)
164 BUG_TRAP(!nlk_sk(sk)->groups); 164 BUG_TRAP(!nlk_sk(sk)->groups);
165} 165}
166 166
167/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on SMP. 167/* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on
168 * Look, when several writers sleep and reader wakes them up, all but one 168 * SMP. Look, when several writers sleep and reader wakes them up, all but one
169 * immediately hit write lock and grab all the cpus. Exclusive sleep solves 169 * immediately hit write lock and grab all the cpus. Exclusive sleep solves
170 * this, _but_ remember, it adds useless work on UP machines. 170 * this, _but_ remember, it adds useless work on UP machines.
171 */ 171 */
@@ -178,7 +178,7 @@ static void netlink_table_grab(void)
178 DECLARE_WAITQUEUE(wait, current); 178 DECLARE_WAITQUEUE(wait, current);
179 179
180 add_wait_queue_exclusive(&nl_table_wait, &wait); 180 add_wait_queue_exclusive(&nl_table_wait, &wait);
181 for(;;) { 181 for (;;) {
182 set_current_state(TASK_UNINTERRUPTIBLE); 182 set_current_state(TASK_UNINTERRUPTIBLE);
183 if (atomic_read(&nl_table_users) == 0) 183 if (atomic_read(&nl_table_users) == 0)
184 break; 184 break;
@@ -192,13 +192,13 @@ static void netlink_table_grab(void)
192 } 192 }
193} 193}
194 194
195static __inline__ void netlink_table_ungrab(void) 195static inline void netlink_table_ungrab(void)
196{ 196{
197 write_unlock_irq(&nl_table_lock); 197 write_unlock_irq(&nl_table_lock);
198 wake_up(&nl_table_wait); 198 wake_up(&nl_table_wait);
199} 199}
200 200
201static __inline__ void 201static inline void
202netlink_lock_table(void) 202netlink_lock_table(void)
203{ 203{
204 /* read_lock() synchronizes us to netlink_table_grab */ 204 /* read_lock() synchronizes us to netlink_table_grab */
@@ -208,14 +208,15 @@ netlink_lock_table(void)
208 read_unlock(&nl_table_lock); 208 read_unlock(&nl_table_lock);
209} 209}
210 210
211static __inline__ void 211static inline void
212netlink_unlock_table(void) 212netlink_unlock_table(void)
213{ 213{
214 if (atomic_dec_and_test(&nl_table_users)) 214 if (atomic_dec_and_test(&nl_table_users))
215 wake_up(&nl_table_wait); 215 wake_up(&nl_table_wait);
216} 216}
217 217
218static __inline__ struct sock *netlink_lookup(struct net *net, int protocol, u32 pid) 218static inline struct sock *netlink_lookup(struct net *net, int protocol,
219 u32 pid)
219{ 220{
220 struct nl_pid_hash *hash = &nl_table[protocol].hash; 221 struct nl_pid_hash *hash = &nl_table[protocol].hash;
221 struct hlist_head *head; 222 struct hlist_head *head;
@@ -428,7 +429,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol)
428 if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM) 429 if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
429 return -ESOCKTNOSUPPORT; 430 return -ESOCKTNOSUPPORT;
430 431
431 if (protocol<0 || protocol >= MAX_LINKS) 432 if (protocol < 0 || protocol >= MAX_LINKS)
432 return -EPROTONOSUPPORT; 433 return -EPROTONOSUPPORT;
433 434
434 netlink_lock_table(); 435 netlink_lock_table();
@@ -445,7 +446,8 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol)
445 cb_mutex = nl_table[protocol].cb_mutex; 446 cb_mutex = nl_table[protocol].cb_mutex;
446 netlink_unlock_table(); 447 netlink_unlock_table();
447 448
448 if ((err = __netlink_create(net, sock, cb_mutex, protocol)) < 0) 449 err = __netlink_create(net, sock, cb_mutex, protocol);
450 if (err < 0)
449 goto out_module; 451 goto out_module;
450 452
451 nlk = nlk_sk(sock->sk); 453 nlk = nlk_sk(sock->sk);
@@ -590,7 +592,7 @@ static int netlink_realloc_groups(struct sock *sk)
590 err = -ENOMEM; 592 err = -ENOMEM;
591 goto out_unlock; 593 goto out_unlock;
592 } 594 }
593 memset((char*)new_groups + NLGRPSZ(nlk->ngroups), 0, 595 memset((char *)new_groups + NLGRPSZ(nlk->ngroups), 0,
594 NLGRPSZ(groups) - NLGRPSZ(nlk->ngroups)); 596 NLGRPSZ(groups) - NLGRPSZ(nlk->ngroups));
595 597
596 nlk->groups = new_groups; 598 nlk->groups = new_groups;
@@ -600,7 +602,8 @@ static int netlink_realloc_groups(struct sock *sk)
600 return err; 602 return err;
601} 603}
602 604
603static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len) 605static int netlink_bind(struct socket *sock, struct sockaddr *addr,
606 int addr_len)
604{ 607{
605 struct sock *sk = sock->sk; 608 struct sock *sk = sock->sk;
606 struct net *net = sk->sk_net; 609 struct net *net = sk->sk_net;
@@ -651,7 +654,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
651 int err = 0; 654 int err = 0;
652 struct sock *sk = sock->sk; 655 struct sock *sk = sock->sk;
653 struct netlink_sock *nlk = nlk_sk(sk); 656 struct netlink_sock *nlk = nlk_sk(sk);
654 struct sockaddr_nl *nladdr=(struct sockaddr_nl*)addr; 657 struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
655 658
656 if (addr->sa_family == AF_UNSPEC) { 659 if (addr->sa_family == AF_UNSPEC) {
657 sk->sk_state = NETLINK_UNCONNECTED; 660 sk->sk_state = NETLINK_UNCONNECTED;
@@ -678,11 +681,12 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
678 return err; 681 return err;
679} 682}
680 683
681static int netlink_getname(struct socket *sock, struct sockaddr *addr, int *addr_len, int peer) 684static int netlink_getname(struct socket *sock, struct sockaddr *addr,
685 int *addr_len, int peer)
682{ 686{
683 struct sock *sk = sock->sk; 687 struct sock *sk = sock->sk;
684 struct netlink_sock *nlk = nlk_sk(sk); 688 struct netlink_sock *nlk = nlk_sk(sk);
685 struct sockaddr_nl *nladdr=(struct sockaddr_nl *)addr; 689 struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
686 690
687 nladdr->nl_family = AF_NETLINK; 691 nladdr->nl_family = AF_NETLINK;
688 nladdr->nl_pad = 0; 692 nladdr->nl_pad = 0;
@@ -885,6 +889,7 @@ retry:
885 889
886 return netlink_sendskb(sk, skb); 890 return netlink_sendskb(sk, skb);
887} 891}
892EXPORT_SYMBOL(netlink_unicast);
888 893
889int netlink_has_listeners(struct sock *sk, unsigned int group) 894int netlink_has_listeners(struct sock *sk, unsigned int group)
890{ 895{
@@ -905,7 +910,8 @@ int netlink_has_listeners(struct sock *sk, unsigned int group)
905} 910}
906EXPORT_SYMBOL_GPL(netlink_has_listeners); 911EXPORT_SYMBOL_GPL(netlink_has_listeners);
907 912
908static __inline__ int netlink_broadcast_deliver(struct sock *sk, struct sk_buff *skb) 913static inline int netlink_broadcast_deliver(struct sock *sk,
914 struct sk_buff *skb)
909{ 915{
910 struct netlink_sock *nlk = nlk_sk(sk); 916 struct netlink_sock *nlk = nlk_sk(sk);
911 917
@@ -1026,6 +1032,7 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid,
1026 return -ENOBUFS; 1032 return -ENOBUFS;
1027 return -ESRCH; 1033 return -ESRCH;
1028} 1034}
1035EXPORT_SYMBOL(netlink_broadcast);
1029 1036
1030struct netlink_set_err_data { 1037struct netlink_set_err_data {
1031 struct sock *exclude_sk; 1038 struct sock *exclude_sk;
@@ -1182,7 +1189,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
1182 struct sock_iocb *siocb = kiocb_to_siocb(kiocb); 1189 struct sock_iocb *siocb = kiocb_to_siocb(kiocb);
1183 struct sock *sk = sock->sk; 1190 struct sock *sk = sock->sk;
1184 struct netlink_sock *nlk = nlk_sk(sk); 1191 struct netlink_sock *nlk = nlk_sk(sk);
1185 struct sockaddr_nl *addr=msg->msg_name; 1192 struct sockaddr_nl *addr = msg->msg_name;
1186 u32 dst_pid; 1193 u32 dst_pid;
1187 u32 dst_group; 1194 u32 dst_group;
1188 struct sk_buff *skb; 1195 struct sk_buff *skb;
@@ -1221,7 +1228,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
1221 goto out; 1228 goto out;
1222 err = -ENOBUFS; 1229 err = -ENOBUFS;
1223 skb = alloc_skb(len, GFP_KERNEL); 1230 skb = alloc_skb(len, GFP_KERNEL);
1224 if (skb==NULL) 1231 if (skb == NULL)
1225 goto out; 1232 goto out;
1226 1233
1227 NETLINK_CB(skb).pid = nlk->pid; 1234 NETLINK_CB(skb).pid = nlk->pid;
@@ -1237,7 +1244,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
1237 */ 1244 */
1238 1245
1239 err = -EFAULT; 1246 err = -EFAULT;
1240 if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) { 1247 if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
1241 kfree_skb(skb); 1248 kfree_skb(skb);
1242 goto out; 1249 goto out;
1243 } 1250 }
@@ -1276,8 +1283,8 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
1276 1283
1277 copied = 0; 1284 copied = 0;
1278 1285
1279 skb = skb_recv_datagram(sk,flags,noblock,&err); 1286 skb = skb_recv_datagram(sk, flags, noblock, &err);
1280 if (skb==NULL) 1287 if (skb == NULL)
1281 goto out; 1288 goto out;
1282 1289
1283 msg->msg_namelen = 0; 1290 msg->msg_namelen = 0;
@@ -1292,7 +1299,7 @@ static int netlink_recvmsg(struct kiocb *kiocb, struct socket *sock,
1292 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); 1299 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
1293 1300
1294 if (msg->msg_name) { 1301 if (msg->msg_name) {
1295 struct sockaddr_nl *addr = (struct sockaddr_nl*)msg->msg_name; 1302 struct sockaddr_nl *addr = (struct sockaddr_nl *)msg->msg_name;
1296 addr->nl_family = AF_NETLINK; 1303 addr->nl_family = AF_NETLINK;
1297 addr->nl_pad = 0; 1304 addr->nl_pad = 0;
1298 addr->nl_pid = NETLINK_CB(skb).pid; 1305 addr->nl_pid = NETLINK_CB(skb).pid;
@@ -1344,7 +1351,7 @@ netlink_kernel_create(struct net *net, int unit, unsigned int groups,
1344 1351
1345 BUG_ON(!nl_table); 1352 BUG_ON(!nl_table);
1346 1353
1347 if (unit<0 || unit>=MAX_LINKS) 1354 if (unit < 0 || unit >= MAX_LINKS)
1348 return NULL; 1355 return NULL;
1349 1356
1350 if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock)) 1357 if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
@@ -1390,6 +1397,7 @@ out_sock_release:
1390 sock_release(sock); 1397 sock_release(sock);
1391 return NULL; 1398 return NULL;
1392} 1399}
1400EXPORT_SYMBOL(netlink_kernel_create);
1393 1401
1394/** 1402/**
1395 * netlink_change_ngroups - change number of multicast groups 1403 * netlink_change_ngroups - change number of multicast groups
@@ -1461,6 +1469,7 @@ void netlink_set_nonroot(int protocol, unsigned int flags)
1461 if ((unsigned int)protocol < MAX_LINKS) 1469 if ((unsigned int)protocol < MAX_LINKS)
1462 nl_table[protocol].nl_nonroot = flags; 1470 nl_table[protocol].nl_nonroot = flags;
1463} 1471}
1472EXPORT_SYMBOL(netlink_set_nonroot);
1464 1473
1465static void netlink_destroy_callback(struct netlink_callback *cb) 1474static void netlink_destroy_callback(struct netlink_callback *cb)
1466{ 1475{
@@ -1529,8 +1538,9 @@ errout:
1529 1538
1530int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, 1539int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
1531 struct nlmsghdr *nlh, 1540 struct nlmsghdr *nlh,
1532 int (*dump)(struct sk_buff *skb, struct netlink_callback*), 1541 int (*dump)(struct sk_buff *skb,
1533 int (*done)(struct netlink_callback*)) 1542 struct netlink_callback *),
1543 int (*done)(struct netlink_callback *))
1534{ 1544{
1535 struct netlink_callback *cb; 1545 struct netlink_callback *cb;
1536 struct sock *sk; 1546 struct sock *sk;
@@ -1571,6 +1581,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
1571 */ 1581 */
1572 return -EINTR; 1582 return -EINTR;
1573} 1583}
1584EXPORT_SYMBOL(netlink_dump_start);
1574 1585
1575void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) 1586void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
1576{ 1587{
@@ -1605,6 +1616,7 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
1605 memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(*nlh)); 1616 memcpy(&errmsg->msg, nlh, err ? nlh->nlmsg_len : sizeof(*nlh));
1606 netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); 1617 netlink_unicast(in_skb->sk, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT);
1607} 1618}
1619EXPORT_SYMBOL(netlink_ack);
1608 1620
1609int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *, 1621int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
1610 struct nlmsghdr *)) 1622 struct nlmsghdr *))
@@ -1638,7 +1650,7 @@ ack:
1638 netlink_ack(skb, nlh, err); 1650 netlink_ack(skb, nlh, err);
1639 1651
1640skip: 1652skip:
1641 msglen = NLMSG_ALIGN(nlh->nlmsg_len); 1653 msglen = NLMSG_ALIGN(nlh->nlmsg_len);
1642 if (msglen > skb->len) 1654 if (msglen > skb->len)
1643 msglen = skb->len; 1655 msglen = skb->len;
1644 skb_pull(skb, msglen); 1656 skb_pull(skb, msglen);
@@ -1646,6 +1658,7 @@ skip:
1646 1658
1647 return 0; 1659 return 0;
1648} 1660}
1661EXPORT_SYMBOL(netlink_rcv_skb);
1649 1662
1650/** 1663/**
1651 * nlmsg_notify - send a notification netlink message 1664 * nlmsg_notify - send a notification netlink message
@@ -1678,6 +1691,7 @@ int nlmsg_notify(struct sock *sk, struct sk_buff *skb, u32 pid,
1678 1691
1679 return err; 1692 return err;
1680} 1693}
1694EXPORT_SYMBOL(nlmsg_notify);
1681 1695
1682#ifdef CONFIG_PROC_FS 1696#ifdef CONFIG_PROC_FS
1683struct nl_seq_iter { 1697struct nl_seq_iter {
@@ -1694,7 +1708,7 @@ static struct sock *netlink_seq_socket_idx(struct seq_file *seq, loff_t pos)
1694 struct hlist_node *node; 1708 struct hlist_node *node;
1695 loff_t off = 0; 1709 loff_t off = 0;
1696 1710
1697 for (i=0; i<MAX_LINKS; i++) { 1711 for (i = 0; i < MAX_LINKS; i++) {
1698 struct nl_pid_hash *hash = &nl_table[i].hash; 1712 struct nl_pid_hash *hash = &nl_table[i].hash;
1699 1713
1700 for (j = 0; j <= hash->mask; j++) { 1714 for (j = 0; j <= hash->mask; j++) {
@@ -1820,11 +1834,13 @@ int netlink_register_notifier(struct notifier_block *nb)
1820{ 1834{
1821 return atomic_notifier_chain_register(&netlink_chain, nb); 1835 return atomic_notifier_chain_register(&netlink_chain, nb);
1822} 1836}
1837EXPORT_SYMBOL(netlink_register_notifier);
1823 1838
1824int netlink_unregister_notifier(struct notifier_block *nb) 1839int netlink_unregister_notifier(struct notifier_block *nb)
1825{ 1840{
1826 return atomic_notifier_chain_unregister(&netlink_chain, nb); 1841 return atomic_notifier_chain_unregister(&netlink_chain, nb);
1827} 1842}
1843EXPORT_SYMBOL(netlink_unregister_notifier);
1828 1844
1829static const struct proto_ops netlink_ops = { 1845static const struct proto_ops netlink_ops = {
1830 .family = PF_NETLINK, 1846 .family = PF_NETLINK,
@@ -1929,14 +1945,3 @@ panic:
1929} 1945}
1930 1946
1931core_initcall(netlink_proto_init); 1947core_initcall(netlink_proto_init);
1932
1933EXPORT_SYMBOL(netlink_ack);
1934EXPORT_SYMBOL(netlink_rcv_skb);
1935EXPORT_SYMBOL(netlink_broadcast);
1936EXPORT_SYMBOL(netlink_dump_start);
1937EXPORT_SYMBOL(netlink_kernel_create);
1938EXPORT_SYMBOL(netlink_register_notifier);
1939EXPORT_SYMBOL(netlink_set_nonroot);
1940EXPORT_SYMBOL(netlink_unicast);
1941EXPORT_SYMBOL(netlink_unregister_notifier);
1942EXPORT_SYMBOL(nlmsg_notify);