diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/netfilter/nf_nat_core.c | 3 | ||||
-rw-r--r-- | net/ipv4/xfrm4_mode_tunnel.c | 2 | ||||
-rw-r--r-- | net/mac80211/tx.c | 2 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_extend.c | 9 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_h323_main.c | 22 | ||||
-rw-r--r-- | net/netlink/genetlink.c | 15 | ||||
-rw-r--r-- | net/unix/af_unix.c | 79 |
7 files changed, 102 insertions, 30 deletions
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c index 04578593e100..d2a887fc8d9b 100644 --- a/net/ipv4/netfilter/nf_nat_core.c +++ b/net/ipv4/netfilter/nf_nat_core.c | |||
@@ -556,7 +556,6 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct) | |||
556 | 556 | ||
557 | spin_lock_bh(&nf_nat_lock); | 557 | spin_lock_bh(&nf_nat_lock); |
558 | hlist_del_rcu(&nat->bysource); | 558 | hlist_del_rcu(&nat->bysource); |
559 | nat->ct = NULL; | ||
560 | spin_unlock_bh(&nf_nat_lock); | 559 | spin_unlock_bh(&nf_nat_lock); |
561 | } | 560 | } |
562 | 561 | ||
@@ -570,8 +569,8 @@ static void nf_nat_move_storage(void *new, void *old) | |||
570 | return; | 569 | return; |
571 | 570 | ||
572 | spin_lock_bh(&nf_nat_lock); | 571 | spin_lock_bh(&nf_nat_lock); |
573 | hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource); | ||
574 | new_nat->ct = ct; | 572 | new_nat->ct = ct; |
573 | hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource); | ||
575 | spin_unlock_bh(&nf_nat_lock); | 574 | spin_unlock_bh(&nf_nat_lock); |
576 | } | 575 | } |
577 | 576 | ||
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index 584e6d74e3a9..7135279f3f84 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c | |||
@@ -52,7 +52,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb) | |||
52 | IP_ECN_clear(top_iph); | 52 | IP_ECN_clear(top_iph); |
53 | 53 | ||
54 | top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? | 54 | top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? |
55 | 0 : XFRM_MODE_SKB_CB(skb)->frag_off; | 55 | 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF)); |
56 | ip_select_ident(top_iph, dst->child, NULL); | 56 | ip_select_ident(top_iph, dst->child, NULL); |
57 | 57 | ||
58 | top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT); | 58 | top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 195cb6dd02a0..ce06e791bf43 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1567,7 +1567,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1567 | * make it big enough for everything we may ever need. | 1567 | * make it big enough for everything we may ever need. |
1568 | */ | 1568 | */ |
1569 | 1569 | ||
1570 | if (head_need > 0 || skb_header_cloned(skb)) { | 1570 | if (head_need > 0 || skb_cloned(skb)) { |
1571 | head_need += IEEE80211_ENCRYPT_HEADROOM; | 1571 | head_need += IEEE80211_ENCRYPT_HEADROOM; |
1572 | head_need += local->tx_headroom; | 1572 | head_need += local->tx_headroom; |
1573 | head_need = max_t(int, 0, head_need); | 1573 | head_need = max_t(int, 0, head_need); |
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index ba1c4915e9eb..3469bc71a385 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c | |||
@@ -59,12 +59,19 @@ nf_ct_ext_create(struct nf_ct_ext **ext, enum nf_ct_ext_id id, gfp_t gfp) | |||
59 | if (!*ext) | 59 | if (!*ext) |
60 | return NULL; | 60 | return NULL; |
61 | 61 | ||
62 | INIT_RCU_HEAD(&(*ext)->rcu); | ||
62 | (*ext)->offset[id] = off; | 63 | (*ext)->offset[id] = off; |
63 | (*ext)->len = len; | 64 | (*ext)->len = len; |
64 | 65 | ||
65 | return (void *)(*ext) + off; | 66 | return (void *)(*ext) + off; |
66 | } | 67 | } |
67 | 68 | ||
69 | static void __nf_ct_ext_free_rcu(struct rcu_head *head) | ||
70 | { | ||
71 | struct nf_ct_ext *ext = container_of(head, struct nf_ct_ext, rcu); | ||
72 | kfree(ext); | ||
73 | } | ||
74 | |||
68 | void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) | 75 | void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) |
69 | { | 76 | { |
70 | struct nf_ct_ext *new; | 77 | struct nf_ct_ext *new; |
@@ -104,7 +111,7 @@ void *__nf_ct_ext_add(struct nf_conn *ct, enum nf_ct_ext_id id, gfp_t gfp) | |||
104 | (void *)ct->ext + ct->ext->offset[i]); | 111 | (void *)ct->ext + ct->ext->offset[i]); |
105 | rcu_read_unlock(); | 112 | rcu_read_unlock(); |
106 | } | 113 | } |
107 | kfree(ct->ext); | 114 | call_rcu(&ct->ext->rcu, __nf_ct_ext_free_rcu); |
108 | ct->ext = new; | 115 | ct->ext = new; |
109 | } | 116 | } |
110 | 117 | ||
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c index 95da1a24aab7..2f83c158934d 100644 --- a/net/netfilter/nf_conntrack_h323_main.c +++ b/net/netfilter/nf_conntrack_h323_main.c | |||
@@ -619,6 +619,7 @@ static const struct nf_conntrack_expect_policy h245_exp_policy = { | |||
619 | static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = { | 619 | static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = { |
620 | .name = "H.245", | 620 | .name = "H.245", |
621 | .me = THIS_MODULE, | 621 | .me = THIS_MODULE, |
622 | .tuple.src.l3num = AF_UNSPEC, | ||
622 | .tuple.dst.protonum = IPPROTO_UDP, | 623 | .tuple.dst.protonum = IPPROTO_UDP, |
623 | .help = h245_help, | 624 | .help = h245_help, |
624 | .expect_policy = &h245_exp_policy, | 625 | .expect_policy = &h245_exp_policy, |
@@ -1765,6 +1766,7 @@ static void __exit nf_conntrack_h323_fini(void) | |||
1765 | nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]); | 1766 | nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]); |
1766 | nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]); | 1767 | nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]); |
1767 | nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]); | 1768 | nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]); |
1769 | nf_conntrack_helper_unregister(&nf_conntrack_helper_h245); | ||
1768 | kfree(h323_buffer); | 1770 | kfree(h323_buffer); |
1769 | pr_debug("nf_ct_h323: fini\n"); | 1771 | pr_debug("nf_ct_h323: fini\n"); |
1770 | } | 1772 | } |
@@ -1777,28 +1779,34 @@ static int __init nf_conntrack_h323_init(void) | |||
1777 | h323_buffer = kmalloc(65536, GFP_KERNEL); | 1779 | h323_buffer = kmalloc(65536, GFP_KERNEL); |
1778 | if (!h323_buffer) | 1780 | if (!h323_buffer) |
1779 | return -ENOMEM; | 1781 | return -ENOMEM; |
1780 | ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[0]); | 1782 | ret = nf_conntrack_helper_register(&nf_conntrack_helper_h245); |
1781 | if (ret < 0) | 1783 | if (ret < 0) |
1782 | goto err1; | 1784 | goto err1; |
1783 | ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[1]); | 1785 | ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[0]); |
1784 | if (ret < 0) | 1786 | if (ret < 0) |
1785 | goto err2; | 1787 | goto err2; |
1786 | ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[0]); | 1788 | ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[1]); |
1787 | if (ret < 0) | 1789 | if (ret < 0) |
1788 | goto err3; | 1790 | goto err3; |
1789 | ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[1]); | 1791 | ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[0]); |
1790 | if (ret < 0) | 1792 | if (ret < 0) |
1791 | goto err4; | 1793 | goto err4; |
1794 | ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[1]); | ||
1795 | if (ret < 0) | ||
1796 | goto err5; | ||
1792 | pr_debug("nf_ct_h323: init success\n"); | 1797 | pr_debug("nf_ct_h323: init success\n"); |
1793 | return 0; | 1798 | return 0; |
1794 | 1799 | ||
1795 | err4: | 1800 | err5: |
1796 | nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]); | 1801 | nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]); |
1797 | err3: | 1802 | err4: |
1798 | nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]); | 1803 | nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]); |
1799 | err2: | 1804 | err3: |
1800 | nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]); | 1805 | nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]); |
1806 | err2: | ||
1807 | nf_conntrack_helper_unregister(&nf_conntrack_helper_h245); | ||
1801 | err1: | 1808 | err1: |
1809 | kfree(h323_buffer); | ||
1802 | return ret; | 1810 | return ret; |
1803 | } | 1811 | } |
1804 | 1812 | ||
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index f5aa23c3e886..3e1191cecaf0 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -444,8 +444,11 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
444 | if (ops->dumpit == NULL) | 444 | if (ops->dumpit == NULL) |
445 | return -EOPNOTSUPP; | 445 | return -EOPNOTSUPP; |
446 | 446 | ||
447 | return netlink_dump_start(genl_sock, skb, nlh, | 447 | genl_unlock(); |
448 | ops->dumpit, ops->done); | 448 | err = netlink_dump_start(genl_sock, skb, nlh, |
449 | ops->dumpit, ops->done); | ||
450 | genl_lock(); | ||
451 | return err; | ||
449 | } | 452 | } |
450 | 453 | ||
451 | if (ops->doit == NULL) | 454 | if (ops->doit == NULL) |
@@ -603,9 +606,6 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb) | |||
603 | int chains_to_skip = cb->args[0]; | 606 | int chains_to_skip = cb->args[0]; |
604 | int fams_to_skip = cb->args[1]; | 607 | int fams_to_skip = cb->args[1]; |
605 | 608 | ||
606 | if (chains_to_skip != 0) | ||
607 | genl_lock(); | ||
608 | |||
609 | for (i = 0; i < GENL_FAM_TAB_SIZE; i++) { | 609 | for (i = 0; i < GENL_FAM_TAB_SIZE; i++) { |
610 | if (i < chains_to_skip) | 610 | if (i < chains_to_skip) |
611 | continue; | 611 | continue; |
@@ -623,9 +623,6 @@ static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb) | |||
623 | } | 623 | } |
624 | 624 | ||
625 | errout: | 625 | errout: |
626 | if (chains_to_skip != 0) | ||
627 | genl_unlock(); | ||
628 | |||
629 | cb->args[0] = i; | 626 | cb->args[0] = i; |
630 | cb->args[1] = n; | 627 | cb->args[1] = n; |
631 | 628 | ||
@@ -770,7 +767,7 @@ static int __init genl_init(void) | |||
770 | 767 | ||
771 | /* we'll bump the group number right afterwards */ | 768 | /* we'll bump the group number right afterwards */ |
772 | genl_sock = netlink_kernel_create(&init_net, NETLINK_GENERIC, 0, | 769 | genl_sock = netlink_kernel_create(&init_net, NETLINK_GENERIC, 0, |
773 | genl_rcv, NULL, THIS_MODULE); | 770 | genl_rcv, &genl_mutex, THIS_MODULE); |
774 | if (genl_sock == NULL) | 771 | if (genl_sock == NULL) |
775 | panic("GENL: Cannot initialize generic netlink\n"); | 772 | panic("GENL: Cannot initialize generic netlink\n"); |
776 | 773 | ||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 392e80e3268d..b4280490cf6e 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -167,6 +167,11 @@ static inline int unix_may_send(struct sock *sk, struct sock *osk) | |||
167 | return (unix_peer(osk) == NULL || unix_our_peer(sk, osk)); | 167 | return (unix_peer(osk) == NULL || unix_our_peer(sk, osk)); |
168 | } | 168 | } |
169 | 169 | ||
170 | static inline int unix_recvq_full(struct sock const *sk) | ||
171 | { | ||
172 | return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog; | ||
173 | } | ||
174 | |||
170 | static struct sock *unix_peer_get(struct sock *s) | 175 | static struct sock *unix_peer_get(struct sock *s) |
171 | { | 176 | { |
172 | struct sock *peer; | 177 | struct sock *peer; |
@@ -480,6 +485,8 @@ static int unix_socketpair(struct socket *, struct socket *); | |||
480 | static int unix_accept(struct socket *, struct socket *, int); | 485 | static int unix_accept(struct socket *, struct socket *, int); |
481 | static int unix_getname(struct socket *, struct sockaddr *, int *, int); | 486 | static int unix_getname(struct socket *, struct sockaddr *, int *, int); |
482 | static unsigned int unix_poll(struct file *, struct socket *, poll_table *); | 487 | static unsigned int unix_poll(struct file *, struct socket *, poll_table *); |
488 | static unsigned int unix_datagram_poll(struct file *, struct socket *, | ||
489 | poll_table *); | ||
483 | static int unix_ioctl(struct socket *, unsigned int, unsigned long); | 490 | static int unix_ioctl(struct socket *, unsigned int, unsigned long); |
484 | static int unix_shutdown(struct socket *, int); | 491 | static int unix_shutdown(struct socket *, int); |
485 | static int unix_stream_sendmsg(struct kiocb *, struct socket *, | 492 | static int unix_stream_sendmsg(struct kiocb *, struct socket *, |
@@ -525,7 +532,7 @@ static const struct proto_ops unix_dgram_ops = { | |||
525 | .socketpair = unix_socketpair, | 532 | .socketpair = unix_socketpair, |
526 | .accept = sock_no_accept, | 533 | .accept = sock_no_accept, |
527 | .getname = unix_getname, | 534 | .getname = unix_getname, |
528 | .poll = datagram_poll, | 535 | .poll = unix_datagram_poll, |
529 | .ioctl = unix_ioctl, | 536 | .ioctl = unix_ioctl, |
530 | .listen = sock_no_listen, | 537 | .listen = sock_no_listen, |
531 | .shutdown = unix_shutdown, | 538 | .shutdown = unix_shutdown, |
@@ -546,7 +553,7 @@ static const struct proto_ops unix_seqpacket_ops = { | |||
546 | .socketpair = unix_socketpair, | 553 | .socketpair = unix_socketpair, |
547 | .accept = unix_accept, | 554 | .accept = unix_accept, |
548 | .getname = unix_getname, | 555 | .getname = unix_getname, |
549 | .poll = datagram_poll, | 556 | .poll = unix_datagram_poll, |
550 | .ioctl = unix_ioctl, | 557 | .ioctl = unix_ioctl, |
551 | .listen = unix_listen, | 558 | .listen = unix_listen, |
552 | .shutdown = unix_shutdown, | 559 | .shutdown = unix_shutdown, |
@@ -981,8 +988,7 @@ static long unix_wait_for_peer(struct sock *other, long timeo) | |||
981 | 988 | ||
982 | sched = !sock_flag(other, SOCK_DEAD) && | 989 | sched = !sock_flag(other, SOCK_DEAD) && |
983 | !(other->sk_shutdown & RCV_SHUTDOWN) && | 990 | !(other->sk_shutdown & RCV_SHUTDOWN) && |
984 | (skb_queue_len(&other->sk_receive_queue) > | 991 | unix_recvq_full(other); |
985 | other->sk_max_ack_backlog); | ||
986 | 992 | ||
987 | unix_state_unlock(other); | 993 | unix_state_unlock(other); |
988 | 994 | ||
@@ -1056,8 +1062,7 @@ restart: | |||
1056 | if (other->sk_state != TCP_LISTEN) | 1062 | if (other->sk_state != TCP_LISTEN) |
1057 | goto out_unlock; | 1063 | goto out_unlock; |
1058 | 1064 | ||
1059 | if (skb_queue_len(&other->sk_receive_queue) > | 1065 | if (unix_recvq_full(other)) { |
1060 | other->sk_max_ack_backlog) { | ||
1061 | err = -EAGAIN; | 1066 | err = -EAGAIN; |
1062 | if (!timeo) | 1067 | if (!timeo) |
1063 | goto out_unlock; | 1068 | goto out_unlock; |
@@ -1426,9 +1431,7 @@ restart: | |||
1426 | goto out_unlock; | 1431 | goto out_unlock; |
1427 | } | 1432 | } |
1428 | 1433 | ||
1429 | if (unix_peer(other) != sk && | 1434 | if (unix_peer(other) != sk && unix_recvq_full(other)) { |
1430 | (skb_queue_len(&other->sk_receive_queue) > | ||
1431 | other->sk_max_ack_backlog)) { | ||
1432 | if (!timeo) { | 1435 | if (!timeo) { |
1433 | err = -EAGAIN; | 1436 | err = -EAGAIN; |
1434 | goto out_unlock; | 1437 | goto out_unlock; |
@@ -1989,6 +1992,64 @@ static unsigned int unix_poll(struct file * file, struct socket *sock, poll_tabl | |||
1989 | return mask; | 1992 | return mask; |
1990 | } | 1993 | } |
1991 | 1994 | ||
1995 | static unsigned int unix_datagram_poll(struct file *file, struct socket *sock, | ||
1996 | poll_table *wait) | ||
1997 | { | ||
1998 | struct sock *sk = sock->sk, *peer; | ||
1999 | unsigned int mask; | ||
2000 | |||
2001 | poll_wait(file, sk->sk_sleep, wait); | ||
2002 | |||
2003 | peer = unix_peer_get(sk); | ||
2004 | if (peer) { | ||
2005 | if (peer != sk) { | ||
2006 | /* | ||
2007 | * Writability of a connected socket additionally | ||
2008 | * depends on the state of the receive queue of the | ||
2009 | * peer. | ||
2010 | */ | ||
2011 | poll_wait(file, &unix_sk(peer)->peer_wait, wait); | ||
2012 | } else { | ||
2013 | sock_put(peer); | ||
2014 | peer = NULL; | ||
2015 | } | ||
2016 | } | ||
2017 | |||
2018 | mask = 0; | ||
2019 | |||
2020 | /* exceptional events? */ | ||
2021 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) | ||
2022 | mask |= POLLERR; | ||
2023 | if (sk->sk_shutdown & RCV_SHUTDOWN) | ||
2024 | mask |= POLLRDHUP; | ||
2025 | if (sk->sk_shutdown == SHUTDOWN_MASK) | ||
2026 | mask |= POLLHUP; | ||
2027 | |||
2028 | /* readable? */ | ||
2029 | if (!skb_queue_empty(&sk->sk_receive_queue) || | ||
2030 | (sk->sk_shutdown & RCV_SHUTDOWN)) | ||
2031 | mask |= POLLIN | POLLRDNORM; | ||
2032 | |||
2033 | /* Connection-based need to check for termination and startup */ | ||
2034 | if (sk->sk_type == SOCK_SEQPACKET) { | ||
2035 | if (sk->sk_state == TCP_CLOSE) | ||
2036 | mask |= POLLHUP; | ||
2037 | /* connection hasn't started yet? */ | ||
2038 | if (sk->sk_state == TCP_SYN_SENT) | ||
2039 | return mask; | ||
2040 | } | ||
2041 | |||
2042 | /* writable? */ | ||
2043 | if (unix_writable(sk) && !(peer && unix_recvq_full(peer))) | ||
2044 | mask |= POLLOUT | POLLWRNORM | POLLWRBAND; | ||
2045 | else | ||
2046 | set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); | ||
2047 | |||
2048 | if (peer) | ||
2049 | sock_put(peer); | ||
2050 | |||
2051 | return mask; | ||
2052 | } | ||
1992 | 2053 | ||
1993 | #ifdef CONFIG_PROC_FS | 2054 | #ifdef CONFIG_PROC_FS |
1994 | static struct sock *first_unix_socket(int *i) | 2055 | static struct sock *first_unix_socket(int *i) |