diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/br.c | 2 | ||||
-rw-r--r-- | net/core/dev.c | 8 | ||||
-rw-r--r-- | net/decnet/af_decnet.c | 2 | ||||
-rw-r--r-- | net/ieee802154/netlink.c | 6 | ||||
-rw-r--r-- | net/ipv4/arp.c | 7 | ||||
-rw-r--r-- | net/ipv4/fib_trie.c | 3 | ||||
-rw-r--r-- | net/ipv4/ip_input.c | 3 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_nat_helper.c | 17 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 15 | ||||
-rw-r--r-- | net/ipv4/tcp_minisocks.c | 3 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 3 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 5 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_input.c | 3 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 2 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_expect.c | 4 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_extend.c | 2 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_proto_tcp.c | 6 | ||||
-rw-r--r-- | net/netfilter/xt_conntrack.c | 66 | ||||
-rw-r--r-- | net/phonet/pn_dev.c | 52 | ||||
-rw-r--r-- | net/phonet/pn_netlink.c | 4 | ||||
-rw-r--r-- | net/sctp/output.c | 2 | ||||
-rw-r--r-- | net/sunrpc/sunrpc_syms.c | 1 | ||||
-rw-r--r-- | net/xfrm/xfrm_algo.c | 4 | ||||
-rw-r--r-- | net/xfrm/xfrm_state.c | 57 |
25 files changed, 169 insertions, 110 deletions
diff --git a/net/bridge/br.c b/net/bridge/br.c index 9aac5213105a..e1241c76239a 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c | |||
@@ -93,7 +93,7 @@ static void __exit br_deinit(void) | |||
93 | 93 | ||
94 | unregister_pernet_subsys(&br_net_ops); | 94 | unregister_pernet_subsys(&br_net_ops); |
95 | 95 | ||
96 | synchronize_net(); | 96 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ |
97 | 97 | ||
98 | br_netfilter_fini(); | 98 | br_netfilter_fini(); |
99 | #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) | 99 | #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) |
diff --git a/net/core/dev.c b/net/core/dev.c index 60b572812278..70c27e0c7c32 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2823,9 +2823,11 @@ static void net_rx_action(struct softirq_action *h) | |||
2823 | * move the instance around on the list at-will. | 2823 | * move the instance around on the list at-will. |
2824 | */ | 2824 | */ |
2825 | if (unlikely(work == weight)) { | 2825 | if (unlikely(work == weight)) { |
2826 | if (unlikely(napi_disable_pending(n))) | 2826 | if (unlikely(napi_disable_pending(n))) { |
2827 | __napi_complete(n); | 2827 | local_irq_enable(); |
2828 | else | 2828 | napi_complete(n); |
2829 | local_irq_disable(); | ||
2830 | } else | ||
2829 | list_move_tail(&n->poll_list, list); | 2831 | list_move_tail(&n->poll_list, list); |
2830 | } | 2832 | } |
2831 | 2833 | ||
diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index d351b8db0df5..77d40289653c 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c | |||
@@ -2413,6 +2413,8 @@ static void __exit decnet_exit(void) | |||
2413 | proc_net_remove(&init_net, "decnet"); | 2413 | proc_net_remove(&init_net, "decnet"); |
2414 | 2414 | ||
2415 | proto_unregister(&dn_proto); | 2415 | proto_unregister(&dn_proto); |
2416 | |||
2417 | rcu_barrier_bh(); /* Wait for completion of call_rcu_bh()'s */ | ||
2416 | } | 2418 | } |
2417 | module_exit(decnet_exit); | 2419 | module_exit(decnet_exit); |
2418 | #endif | 2420 | #endif |
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c index 105ad10876af..27eda9fdf3c2 100644 --- a/net/ieee802154/netlink.c +++ b/net/ieee802154/netlink.c | |||
@@ -276,6 +276,9 @@ static struct net_device *ieee802154_nl_get_dev(struct genl_info *info) | |||
276 | else | 276 | else |
277 | return NULL; | 277 | return NULL; |
278 | 278 | ||
279 | if (!dev) | ||
280 | return NULL; | ||
281 | |||
279 | if (dev->type != ARPHRD_IEEE802154) { | 282 | if (dev->type != ARPHRD_IEEE802154) { |
280 | dev_put(dev); | 283 | dev_put(dev); |
281 | return NULL; | 284 | return NULL; |
@@ -521,3 +524,6 @@ static void __exit ieee802154_nl_exit(void) | |||
521 | } | 524 | } |
522 | module_exit(ieee802154_nl_exit); | 525 | module_exit(ieee802154_nl_exit); |
523 | 526 | ||
527 | MODULE_LICENSE("GPL v2"); | ||
528 | MODULE_DESCRIPTION("ieee 802.15.4 configuration interface"); | ||
529 | |||
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 8a3881e28aca..c29d75d8f1b1 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -801,11 +801,8 @@ static int arp_process(struct sk_buff *skb) | |||
801 | * cache. | 801 | * cache. |
802 | */ | 802 | */ |
803 | 803 | ||
804 | /* | 804 | /* Special case: IPv4 duplicate address detection packet (RFC2131) */ |
805 | * Special case: IPv4 duplicate address detection packet (RFC2131) | 805 | if (sip == 0) { |
806 | * and Gratuitous ARP/ARP Announce. (RFC3927, Section 2.4) | ||
807 | */ | ||
808 | if (sip == 0 || tip == sip) { | ||
809 | if (arp->ar_op == htons(ARPOP_REQUEST) && | 806 | if (arp->ar_op == htons(ARPOP_REQUEST) && |
810 | inet_addr_type(net, tip) == RTN_LOCAL && | 807 | inet_addr_type(net, tip) == RTN_LOCAL && |
811 | !arp_ignore(in_dev, sip, tip)) | 808 | !arp_ignore(in_dev, sip, tip)) |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 012cf5a68581..00a54b246dfe 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -1021,6 +1021,9 @@ static void trie_rebalance(struct trie *t, struct tnode *tn) | |||
1021 | (struct node *)tn, wasfull); | 1021 | (struct node *)tn, wasfull); |
1022 | 1022 | ||
1023 | tp = node_parent((struct node *) tn); | 1023 | tp = node_parent((struct node *) tn); |
1024 | if (!tp) | ||
1025 | rcu_assign_pointer(t->trie, (struct node *)tn); | ||
1026 | |||
1024 | tnode_free_flush(); | 1027 | tnode_free_flush(); |
1025 | if (!tp) | 1028 | if (!tp) |
1026 | break; | 1029 | break; |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 490ce20faf38..db46b4b5b2b9 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -440,6 +440,9 @@ int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, | |||
440 | /* Remove any debris in the socket control block */ | 440 | /* Remove any debris in the socket control block */ |
441 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); | 441 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); |
442 | 442 | ||
443 | /* Must drop socket now because of tproxy. */ | ||
444 | skb_orphan(skb); | ||
445 | |||
443 | return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, dev, NULL, | 446 | return NF_HOOK(PF_INET, NF_INET_PRE_ROUTING, skb, dev, NULL, |
444 | ip_rcv_finish); | 447 | ip_rcv_finish); |
445 | 448 | ||
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c index 155c008626c8..09172a65d9b6 100644 --- a/net/ipv4/netfilter/nf_nat_helper.c +++ b/net/ipv4/netfilter/nf_nat_helper.c | |||
@@ -191,7 +191,8 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb, | |||
191 | ct, ctinfo); | 191 | ct, ctinfo); |
192 | /* Tell TCP window tracking about seq change */ | 192 | /* Tell TCP window tracking about seq change */ |
193 | nf_conntrack_tcp_update(skb, ip_hdrlen(skb), | 193 | nf_conntrack_tcp_update(skb, ip_hdrlen(skb), |
194 | ct, CTINFO2DIR(ctinfo)); | 194 | ct, CTINFO2DIR(ctinfo), |
195 | (int)rep_len - (int)match_len); | ||
195 | 196 | ||
196 | nf_conntrack_event_cache(IPCT_NATSEQADJ, ct); | 197 | nf_conntrack_event_cache(IPCT_NATSEQADJ, ct); |
197 | } | 198 | } |
@@ -377,6 +378,7 @@ nf_nat_seq_adjust(struct sk_buff *skb, | |||
377 | struct tcphdr *tcph; | 378 | struct tcphdr *tcph; |
378 | int dir; | 379 | int dir; |
379 | __be32 newseq, newack; | 380 | __be32 newseq, newack; |
381 | s16 seqoff, ackoff; | ||
380 | struct nf_conn_nat *nat = nfct_nat(ct); | 382 | struct nf_conn_nat *nat = nfct_nat(ct); |
381 | struct nf_nat_seq *this_way, *other_way; | 383 | struct nf_nat_seq *this_way, *other_way; |
382 | 384 | ||
@@ -390,15 +392,18 @@ nf_nat_seq_adjust(struct sk_buff *skb, | |||
390 | 392 | ||
391 | tcph = (void *)skb->data + ip_hdrlen(skb); | 393 | tcph = (void *)skb->data + ip_hdrlen(skb); |
392 | if (after(ntohl(tcph->seq), this_way->correction_pos)) | 394 | if (after(ntohl(tcph->seq), this_way->correction_pos)) |
393 | newseq = htonl(ntohl(tcph->seq) + this_way->offset_after); | 395 | seqoff = this_way->offset_after; |
394 | else | 396 | else |
395 | newseq = htonl(ntohl(tcph->seq) + this_way->offset_before); | 397 | seqoff = this_way->offset_before; |
396 | 398 | ||
397 | if (after(ntohl(tcph->ack_seq) - other_way->offset_before, | 399 | if (after(ntohl(tcph->ack_seq) - other_way->offset_before, |
398 | other_way->correction_pos)) | 400 | other_way->correction_pos)) |
399 | newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_after); | 401 | ackoff = other_way->offset_after; |
400 | else | 402 | else |
401 | newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before); | 403 | ackoff = other_way->offset_before; |
404 | |||
405 | newseq = htonl(ntohl(tcph->seq) + seqoff); | ||
406 | newack = htonl(ntohl(tcph->ack_seq) - ackoff); | ||
402 | 407 | ||
403 | inet_proto_csum_replace4(&tcph->check, skb, tcph->seq, newseq, 0); | 408 | inet_proto_csum_replace4(&tcph->check, skb, tcph->seq, newseq, 0); |
404 | inet_proto_csum_replace4(&tcph->check, skb, tcph->ack_seq, newack, 0); | 409 | inet_proto_csum_replace4(&tcph->check, skb, tcph->ack_seq, newack, 0); |
@@ -413,7 +418,7 @@ nf_nat_seq_adjust(struct sk_buff *skb, | |||
413 | if (!nf_nat_sack_adjust(skb, tcph, ct, ctinfo)) | 418 | if (!nf_nat_sack_adjust(skb, tcph, ct, ctinfo)) |
414 | return 0; | 419 | return 0; |
415 | 420 | ||
416 | nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir); | 421 | nf_conntrack_tcp_update(skb, ip_hdrlen(skb), ct, dir, seqoff); |
417 | 422 | ||
418 | return 1; | 423 | return 1; |
419 | } | 424 | } |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 17b89c523f9d..7870a535dac6 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -903,13 +903,17 @@ int tcp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, | |||
903 | iov++; | 903 | iov++; |
904 | 904 | ||
905 | while (seglen > 0) { | 905 | while (seglen > 0) { |
906 | int copy; | 906 | int copy = 0; |
907 | int max = size_goal; | ||
907 | 908 | ||
908 | skb = tcp_write_queue_tail(sk); | 909 | skb = tcp_write_queue_tail(sk); |
910 | if (tcp_send_head(sk)) { | ||
911 | if (skb->ip_summed == CHECKSUM_NONE) | ||
912 | max = mss_now; | ||
913 | copy = max - skb->len; | ||
914 | } | ||
909 | 915 | ||
910 | if (!tcp_send_head(sk) || | 916 | if (copy <= 0) { |
911 | (copy = size_goal - skb->len) <= 0) { | ||
912 | |||
913 | new_segment: | 917 | new_segment: |
914 | /* Allocate new segment. If the interface is SG, | 918 | /* Allocate new segment. If the interface is SG, |
915 | * allocate skb fitting to single page. | 919 | * allocate skb fitting to single page. |
@@ -930,6 +934,7 @@ new_segment: | |||
930 | 934 | ||
931 | skb_entail(sk, skb); | 935 | skb_entail(sk, skb); |
932 | copy = size_goal; | 936 | copy = size_goal; |
937 | max = size_goal; | ||
933 | } | 938 | } |
934 | 939 | ||
935 | /* Try to append data to the end of skb. */ | 940 | /* Try to append data to the end of skb. */ |
@@ -1028,7 +1033,7 @@ new_segment: | |||
1028 | if ((seglen -= copy) == 0 && iovlen == 0) | 1033 | if ((seglen -= copy) == 0 && iovlen == 0) |
1029 | goto out; | 1034 | goto out; |
1030 | 1035 | ||
1031 | if (skb->len < size_goal || (flags & MSG_OOB)) | 1036 | if (skb->len < max || (flags & MSG_OOB)) |
1032 | continue; | 1037 | continue; |
1033 | 1038 | ||
1034 | if (forced_push(tp)) { | 1039 | if (forced_push(tp)) { |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 43bbba7926ee..f8d67ccc64f3 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -128,7 +128,8 @@ tcp_timewait_state_process(struct inet_timewait_sock *tw, struct sk_buff *skb, | |||
128 | goto kill_with_rst; | 128 | goto kill_with_rst; |
129 | 129 | ||
130 | /* Dup ACK? */ | 130 | /* Dup ACK? */ |
131 | if (!after(TCP_SKB_CB(skb)->end_seq, tcptw->tw_rcv_nxt) || | 131 | if (!th->ack || |
132 | !after(TCP_SKB_CB(skb)->end_seq, tcptw->tw_rcv_nxt) || | ||
132 | TCP_SKB_CB(skb)->end_seq == TCP_SKB_CB(skb)->seq) { | 133 | TCP_SKB_CB(skb)->end_seq == TCP_SKB_CB(skb)->seq) { |
133 | inet_twsk_put(tw); | 134 | inet_twsk_put(tw); |
134 | return TCP_TW_SUCCESS; | 135 | return TCP_TW_SUCCESS; |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 416fc4c2e7eb..5bdf08d312d9 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -725,7 +725,8 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) | |||
725 | static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, | 725 | static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb, |
726 | unsigned int mss_now) | 726 | unsigned int mss_now) |
727 | { | 727 | { |
728 | if (skb->len <= mss_now || !sk_can_gso(sk)) { | 728 | if (skb->len <= mss_now || !sk_can_gso(sk) || |
729 | skb->ip_summed == CHECKSUM_NONE) { | ||
729 | /* Avoid the costly divide in the normal | 730 | /* Avoid the costly divide in the normal |
730 | * non-TSO case. | 731 | * non-TSO case. |
731 | */ | 732 | */ |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 8c1e86afbbf5..3883b4036a74 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -3362,7 +3362,10 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, | |||
3362 | valid = ifa->valid_lft; | 3362 | valid = ifa->valid_lft; |
3363 | if (preferred != INFINITY_LIFE_TIME) { | 3363 | if (preferred != INFINITY_LIFE_TIME) { |
3364 | long tval = (jiffies - ifa->tstamp)/HZ; | 3364 | long tval = (jiffies - ifa->tstamp)/HZ; |
3365 | preferred -= tval; | 3365 | if (preferred > tval) |
3366 | preferred -= tval; | ||
3367 | else | ||
3368 | preferred = 0; | ||
3366 | if (valid != INFINITY_LIFE_TIME) | 3369 | if (valid != INFINITY_LIFE_TIME) |
3367 | valid -= tval; | 3370 | valid -= tval; |
3368 | } | 3371 | } |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 85b3d0036afd..caa0278d30a9 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -1284,6 +1284,8 @@ static void __exit inet6_exit(void) | |||
1284 | proto_unregister(&udplitev6_prot); | 1284 | proto_unregister(&udplitev6_prot); |
1285 | proto_unregister(&udpv6_prot); | 1285 | proto_unregister(&udpv6_prot); |
1286 | proto_unregister(&tcpv6_prot); | 1286 | proto_unregister(&tcpv6_prot); |
1287 | |||
1288 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | ||
1287 | } | 1289 | } |
1288 | module_exit(inet6_exit); | 1290 | module_exit(inet6_exit); |
1289 | 1291 | ||
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index c3a07d75b5f5..6d6a4277c677 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
@@ -139,6 +139,9 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
139 | 139 | ||
140 | rcu_read_unlock(); | 140 | rcu_read_unlock(); |
141 | 141 | ||
142 | /* Must drop socket now because of tproxy. */ | ||
143 | skb_orphan(skb); | ||
144 | |||
142 | return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL, | 145 | return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL, |
143 | ip6_rcv_finish); | 146 | ip6_rcv_finish); |
144 | err: | 147 | err: |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index fc712e60705d..11cf45bce38a 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -494,7 +494,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) | |||
494 | * should it be using the interface and enqueuing | 494 | * should it be using the interface and enqueuing |
495 | * frames at this very time on another CPU. | 495 | * frames at this very time on another CPU. |
496 | */ | 496 | */ |
497 | synchronize_rcu(); | 497 | rcu_barrier(); /* Wait for RX path and call_rcu()'s */ |
498 | skb_queue_purge(&sdata->u.mesh.skb_queue); | 498 | skb_queue_purge(&sdata->u.mesh.skb_queue); |
499 | } | 499 | } |
500 | 500 | ||
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index afde8f991646..2032dfe25ca8 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c | |||
@@ -617,8 +617,10 @@ err1: | |||
617 | void nf_conntrack_expect_fini(struct net *net) | 617 | void nf_conntrack_expect_fini(struct net *net) |
618 | { | 618 | { |
619 | exp_proc_remove(net); | 619 | exp_proc_remove(net); |
620 | if (net_eq(net, &init_net)) | 620 | if (net_eq(net, &init_net)) { |
621 | rcu_barrier(); /* Wait for call_rcu() before destroy */ | ||
621 | kmem_cache_destroy(nf_ct_expect_cachep); | 622 | kmem_cache_destroy(nf_ct_expect_cachep); |
623 | } | ||
622 | nf_ct_free_hashtable(net->ct.expect_hash, net->ct.expect_vmalloc, | 624 | nf_ct_free_hashtable(net->ct.expect_hash, net->ct.expect_vmalloc, |
623 | nf_ct_expect_hsize); | 625 | nf_ct_expect_hsize); |
624 | } | 626 | } |
diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c index 4b2c769d555f..fef95be334bd 100644 --- a/net/netfilter/nf_conntrack_extend.c +++ b/net/netfilter/nf_conntrack_extend.c | |||
@@ -186,6 +186,6 @@ void nf_ct_extend_unregister(struct nf_ct_ext_type *type) | |||
186 | rcu_assign_pointer(nf_ct_ext_types[type->id], NULL); | 186 | rcu_assign_pointer(nf_ct_ext_types[type->id], NULL); |
187 | update_alloc_size(type); | 187 | update_alloc_size(type); |
188 | mutex_unlock(&nf_ct_ext_type_mutex); | 188 | mutex_unlock(&nf_ct_ext_type_mutex); |
189 | synchronize_rcu(); | 189 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ |
190 | } | 190 | } |
191 | EXPORT_SYMBOL_GPL(nf_ct_extend_unregister); | 191 | EXPORT_SYMBOL_GPL(nf_ct_extend_unregister); |
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index 33fc0a443f3d..97a82ba75376 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
@@ -720,8 +720,8 @@ static bool tcp_in_window(const struct nf_conn *ct, | |||
720 | /* Caller must linearize skb at tcp header. */ | 720 | /* Caller must linearize skb at tcp header. */ |
721 | void nf_conntrack_tcp_update(const struct sk_buff *skb, | 721 | void nf_conntrack_tcp_update(const struct sk_buff *skb, |
722 | unsigned int dataoff, | 722 | unsigned int dataoff, |
723 | struct nf_conn *ct, | 723 | struct nf_conn *ct, int dir, |
724 | int dir) | 724 | s16 offset) |
725 | { | 725 | { |
726 | const struct tcphdr *tcph = (const void *)skb->data + dataoff; | 726 | const struct tcphdr *tcph = (const void *)skb->data + dataoff; |
727 | const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[dir]; | 727 | const struct ip_ct_tcp_state *sender = &ct->proto.tcp.seen[dir]; |
@@ -734,7 +734,7 @@ void nf_conntrack_tcp_update(const struct sk_buff *skb, | |||
734 | /* | 734 | /* |
735 | * We have to worry for the ack in the reply packet only... | 735 | * We have to worry for the ack in the reply packet only... |
736 | */ | 736 | */ |
737 | if (after(end, ct->proto.tcp.seen[dir].td_end)) | 737 | if (ct->proto.tcp.seen[dir].td_end + offset == end) |
738 | ct->proto.tcp.seen[dir].td_end = end; | 738 | ct->proto.tcp.seen[dir].td_end = end; |
739 | ct->proto.tcp.last_end = end; | 739 | ct->proto.tcp.last_end = end; |
740 | spin_unlock_bh(&ct->lock); | 740 | spin_unlock_bh(&ct->lock); |
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c index 0b7139f3dd78..fc581800698e 100644 --- a/net/netfilter/xt_conntrack.c +++ b/net/netfilter/xt_conntrack.c | |||
@@ -129,7 +129,7 @@ conntrack_addrcmp(const union nf_inet_addr *kaddr, | |||
129 | 129 | ||
130 | static inline bool | 130 | static inline bool |
131 | conntrack_mt_origsrc(const struct nf_conn *ct, | 131 | conntrack_mt_origsrc(const struct nf_conn *ct, |
132 | const struct xt_conntrack_mtinfo1 *info, | 132 | const struct xt_conntrack_mtinfo2 *info, |
133 | u_int8_t family) | 133 | u_int8_t family) |
134 | { | 134 | { |
135 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, | 135 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, |
@@ -138,7 +138,7 @@ conntrack_mt_origsrc(const struct nf_conn *ct, | |||
138 | 138 | ||
139 | static inline bool | 139 | static inline bool |
140 | conntrack_mt_origdst(const struct nf_conn *ct, | 140 | conntrack_mt_origdst(const struct nf_conn *ct, |
141 | const struct xt_conntrack_mtinfo1 *info, | 141 | const struct xt_conntrack_mtinfo2 *info, |
142 | u_int8_t family) | 142 | u_int8_t family) |
143 | { | 143 | { |
144 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3, | 144 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3, |
@@ -147,7 +147,7 @@ conntrack_mt_origdst(const struct nf_conn *ct, | |||
147 | 147 | ||
148 | static inline bool | 148 | static inline bool |
149 | conntrack_mt_replsrc(const struct nf_conn *ct, | 149 | conntrack_mt_replsrc(const struct nf_conn *ct, |
150 | const struct xt_conntrack_mtinfo1 *info, | 150 | const struct xt_conntrack_mtinfo2 *info, |
151 | u_int8_t family) | 151 | u_int8_t family) |
152 | { | 152 | { |
153 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3, | 153 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3, |
@@ -156,7 +156,7 @@ conntrack_mt_replsrc(const struct nf_conn *ct, | |||
156 | 156 | ||
157 | static inline bool | 157 | static inline bool |
158 | conntrack_mt_repldst(const struct nf_conn *ct, | 158 | conntrack_mt_repldst(const struct nf_conn *ct, |
159 | const struct xt_conntrack_mtinfo1 *info, | 159 | const struct xt_conntrack_mtinfo2 *info, |
160 | u_int8_t family) | 160 | u_int8_t family) |
161 | { | 161 | { |
162 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3, | 162 | return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3, |
@@ -164,7 +164,7 @@ conntrack_mt_repldst(const struct nf_conn *ct, | |||
164 | } | 164 | } |
165 | 165 | ||
166 | static inline bool | 166 | static inline bool |
167 | ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info, | 167 | ct_proto_port_check(const struct xt_conntrack_mtinfo2 *info, |
168 | const struct nf_conn *ct) | 168 | const struct nf_conn *ct) |
169 | { | 169 | { |
170 | const struct nf_conntrack_tuple *tuple; | 170 | const struct nf_conntrack_tuple *tuple; |
@@ -204,7 +204,7 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info, | |||
204 | static bool | 204 | static bool |
205 | conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) | 205 | conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
206 | { | 206 | { |
207 | const struct xt_conntrack_mtinfo1 *info = par->matchinfo; | 207 | const struct xt_conntrack_mtinfo2 *info = par->matchinfo; |
208 | enum ip_conntrack_info ctinfo; | 208 | enum ip_conntrack_info ctinfo; |
209 | const struct nf_conn *ct; | 209 | const struct nf_conn *ct; |
210 | unsigned int statebit; | 210 | unsigned int statebit; |
@@ -278,6 +278,16 @@ conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
278 | return true; | 278 | return true; |
279 | } | 279 | } |
280 | 280 | ||
281 | static bool | ||
282 | conntrack_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par) | ||
283 | { | ||
284 | const struct xt_conntrack_mtinfo2 *const *info = par->matchinfo; | ||
285 | struct xt_match_param newpar = *par; | ||
286 | |||
287 | newpar.matchinfo = *info; | ||
288 | return conntrack_mt(skb, &newpar); | ||
289 | } | ||
290 | |||
281 | static bool conntrack_mt_check(const struct xt_mtchk_param *par) | 291 | static bool conntrack_mt_check(const struct xt_mtchk_param *par) |
282 | { | 292 | { |
283 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { | 293 | if (nf_ct_l3proto_try_module_get(par->family) < 0) { |
@@ -288,11 +298,45 @@ static bool conntrack_mt_check(const struct xt_mtchk_param *par) | |||
288 | return true; | 298 | return true; |
289 | } | 299 | } |
290 | 300 | ||
301 | static bool conntrack_mt_check_v1(const struct xt_mtchk_param *par) | ||
302 | { | ||
303 | struct xt_conntrack_mtinfo1 *info = par->matchinfo; | ||
304 | struct xt_conntrack_mtinfo2 *up; | ||
305 | int ret = conntrack_mt_check(par); | ||
306 | |||
307 | if (ret < 0) | ||
308 | return ret; | ||
309 | |||
310 | up = kmalloc(sizeof(*up), GFP_KERNEL); | ||
311 | if (up == NULL) { | ||
312 | nf_ct_l3proto_module_put(par->family); | ||
313 | return -ENOMEM; | ||
314 | } | ||
315 | |||
316 | /* | ||
317 | * The strategy here is to minimize the overhead of v1 matching, | ||
318 | * by prebuilding a v2 struct and putting the pointer into the | ||
319 | * v1 dataspace. | ||
320 | */ | ||
321 | memcpy(up, info, offsetof(typeof(*info), state_mask)); | ||
322 | up->state_mask = info->state_mask; | ||
323 | up->status_mask = info->status_mask; | ||
324 | *(void **)info = up; | ||
325 | return true; | ||
326 | } | ||
327 | |||
291 | static void conntrack_mt_destroy(const struct xt_mtdtor_param *par) | 328 | static void conntrack_mt_destroy(const struct xt_mtdtor_param *par) |
292 | { | 329 | { |
293 | nf_ct_l3proto_module_put(par->family); | 330 | nf_ct_l3proto_module_put(par->family); |
294 | } | 331 | } |
295 | 332 | ||
333 | static void conntrack_mt_destroy_v1(const struct xt_mtdtor_param *par) | ||
334 | { | ||
335 | struct xt_conntrack_mtinfo2 **info = par->matchinfo; | ||
336 | kfree(*info); | ||
337 | conntrack_mt_destroy(par); | ||
338 | } | ||
339 | |||
296 | #ifdef CONFIG_COMPAT | 340 | #ifdef CONFIG_COMPAT |
297 | struct compat_xt_conntrack_info | 341 | struct compat_xt_conntrack_info |
298 | { | 342 | { |
@@ -363,6 +407,16 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = { | |||
363 | .revision = 1, | 407 | .revision = 1, |
364 | .family = NFPROTO_UNSPEC, | 408 | .family = NFPROTO_UNSPEC, |
365 | .matchsize = sizeof(struct xt_conntrack_mtinfo1), | 409 | .matchsize = sizeof(struct xt_conntrack_mtinfo1), |
410 | .match = conntrack_mt_v1, | ||
411 | .checkentry = conntrack_mt_check_v1, | ||
412 | .destroy = conntrack_mt_destroy_v1, | ||
413 | .me = THIS_MODULE, | ||
414 | }, | ||
415 | { | ||
416 | .name = "conntrack", | ||
417 | .revision = 2, | ||
418 | .family = NFPROTO_UNSPEC, | ||
419 | .matchsize = sizeof(struct xt_conntrack_mtinfo2), | ||
366 | .match = conntrack_mt, | 420 | .match = conntrack_mt, |
367 | .checkentry = conntrack_mt_check, | 421 | .checkentry = conntrack_mt_check, |
368 | .destroy = conntrack_mt_destroy, | 422 | .destroy = conntrack_mt_destroy, |
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c index 80a322d77909..b0d6ddd82a9d 100644 --- a/net/phonet/pn_dev.c +++ b/net/phonet/pn_dev.c | |||
@@ -69,10 +69,27 @@ static struct phonet_device *__phonet_get(struct net_device *dev) | |||
69 | return NULL; | 69 | return NULL; |
70 | } | 70 | } |
71 | 71 | ||
72 | static void __phonet_device_free(struct phonet_device *pnd) | 72 | static void phonet_device_destroy(struct net_device *dev) |
73 | { | 73 | { |
74 | list_del(&pnd->list); | 74 | struct phonet_device_list *pndevs = phonet_device_list(dev_net(dev)); |
75 | kfree(pnd); | 75 | struct phonet_device *pnd; |
76 | |||
77 | ASSERT_RTNL(); | ||
78 | |||
79 | spin_lock_bh(&pndevs->lock); | ||
80 | pnd = __phonet_get(dev); | ||
81 | if (pnd) | ||
82 | list_del(&pnd->list); | ||
83 | spin_unlock_bh(&pndevs->lock); | ||
84 | |||
85 | if (pnd) { | ||
86 | u8 addr; | ||
87 | |||
88 | for (addr = find_first_bit(pnd->addrs, 64); addr < 64; | ||
89 | addr = find_next_bit(pnd->addrs, 64, 1+addr)) | ||
90 | phonet_address_notify(RTM_DELADDR, dev, addr); | ||
91 | kfree(pnd); | ||
92 | } | ||
76 | } | 93 | } |
77 | 94 | ||
78 | struct net_device *phonet_device_get(struct net *net) | 95 | struct net_device *phonet_device_get(struct net *net) |
@@ -126,8 +143,10 @@ int phonet_address_del(struct net_device *dev, u8 addr) | |||
126 | pnd = __phonet_get(dev); | 143 | pnd = __phonet_get(dev); |
127 | if (!pnd || !test_and_clear_bit(addr >> 2, pnd->addrs)) | 144 | if (!pnd || !test_and_clear_bit(addr >> 2, pnd->addrs)) |
128 | err = -EADDRNOTAVAIL; | 145 | err = -EADDRNOTAVAIL; |
129 | else if (bitmap_empty(pnd->addrs, 64)) | 146 | else if (bitmap_empty(pnd->addrs, 64)) { |
130 | __phonet_device_free(pnd); | 147 | list_del(&pnd->list); |
148 | kfree(pnd); | ||
149 | } | ||
131 | spin_unlock_bh(&pndevs->lock); | 150 | spin_unlock_bh(&pndevs->lock); |
132 | return err; | 151 | return err; |
133 | } | 152 | } |
@@ -181,18 +200,8 @@ static int phonet_device_notify(struct notifier_block *me, unsigned long what, | |||
181 | { | 200 | { |
182 | struct net_device *dev = arg; | 201 | struct net_device *dev = arg; |
183 | 202 | ||
184 | if (what == NETDEV_UNREGISTER) { | 203 | if (what == NETDEV_UNREGISTER) |
185 | struct phonet_device_list *pndevs; | 204 | phonet_device_destroy(dev); |
186 | struct phonet_device *pnd; | ||
187 | |||
188 | /* Destroy phonet-specific device data */ | ||
189 | pndevs = phonet_device_list(dev_net(dev)); | ||
190 | spin_lock_bh(&pndevs->lock); | ||
191 | pnd = __phonet_get(dev); | ||
192 | if (pnd) | ||
193 | __phonet_device_free(pnd); | ||
194 | spin_unlock_bh(&pndevs->lock); | ||
195 | } | ||
196 | return 0; | 205 | return 0; |
197 | 206 | ||
198 | } | 207 | } |
@@ -218,11 +227,12 @@ static int phonet_init_net(struct net *net) | |||
218 | static void phonet_exit_net(struct net *net) | 227 | static void phonet_exit_net(struct net *net) |
219 | { | 228 | { |
220 | struct phonet_net *pnn = net_generic(net, phonet_net_id); | 229 | struct phonet_net *pnn = net_generic(net, phonet_net_id); |
221 | struct phonet_device *pnd, *n; | 230 | struct net_device *dev; |
222 | |||
223 | list_for_each_entry_safe(pnd, n, &pnn->pndevs.list, list) | ||
224 | __phonet_device_free(pnd); | ||
225 | 231 | ||
232 | rtnl_lock(); | ||
233 | for_each_netdev(net, dev) | ||
234 | phonet_device_destroy(dev); | ||
235 | rtnl_unlock(); | ||
226 | kfree(pnn); | 236 | kfree(pnn); |
227 | } | 237 | } |
228 | 238 | ||
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c index cec4e5951681..f8b4cee434c2 100644 --- a/net/phonet/pn_netlink.c +++ b/net/phonet/pn_netlink.c | |||
@@ -32,7 +32,7 @@ | |||
32 | static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr, | 32 | static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr, |
33 | u32 pid, u32 seq, int event); | 33 | u32 pid, u32 seq, int event); |
34 | 34 | ||
35 | static void rtmsg_notify(int event, struct net_device *dev, u8 addr) | 35 | void phonet_address_notify(int event, struct net_device *dev, u8 addr) |
36 | { | 36 | { |
37 | struct sk_buff *skb; | 37 | struct sk_buff *skb; |
38 | int err = -ENOBUFS; | 38 | int err = -ENOBUFS; |
@@ -94,7 +94,7 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr) | |||
94 | else | 94 | else |
95 | err = phonet_address_del(dev, pnaddr); | 95 | err = phonet_address_del(dev, pnaddr); |
96 | if (!err) | 96 | if (!err) |
97 | rtmsg_notify(nlh->nlmsg_type, dev, pnaddr); | 97 | phonet_address_notify(nlh->nlmsg_type, dev, pnaddr); |
98 | return err; | 98 | return err; |
99 | } | 99 | } |
100 | 100 | ||
diff --git a/net/sctp/output.c b/net/sctp/output.c index b76411444515..b94c21190566 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -407,7 +407,7 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
407 | } | 407 | } |
408 | dst = dst_clone(tp->dst); | 408 | dst = dst_clone(tp->dst); |
409 | skb_dst_set(nskb, dst); | 409 | skb_dst_set(nskb, dst); |
410 | if (dst) | 410 | if (!dst) |
411 | goto no_route; | 411 | goto no_route; |
412 | 412 | ||
413 | /* Build the SCTP header. */ | 413 | /* Build the SCTP header. */ |
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index 843629f55763..adaa81982f74 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c | |||
@@ -66,6 +66,7 @@ cleanup_sunrpc(void) | |||
66 | #ifdef CONFIG_PROC_FS | 66 | #ifdef CONFIG_PROC_FS |
67 | rpc_proc_exit(); | 67 | rpc_proc_exit(); |
68 | #endif | 68 | #endif |
69 | rcu_barrier(); /* Wait for completion of call_rcu()'s */ | ||
69 | } | 70 | } |
70 | MODULE_LICENSE("GPL"); | 71 | MODULE_LICENSE("GPL"); |
71 | module_init(init_sunrpc); | 72 | module_init(init_sunrpc); |
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index d31ccb487730..faf54c6bf96b 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c | |||
@@ -292,8 +292,8 @@ static struct xfrm_algo_desc ealg_list[] = { | |||
292 | } | 292 | } |
293 | }, | 293 | }, |
294 | { | 294 | { |
295 | .name = "cbc(cast128)", | 295 | .name = "cbc(cast5)", |
296 | .compat = "cast128", | 296 | .compat = "cast5", |
297 | 297 | ||
298 | .uinfo = { | 298 | .uinfo = { |
299 | .encr = { | 299 | .encr = { |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 5f1f86565f16..f2f7c638083e 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -668,22 +668,10 @@ static struct xfrm_state *__xfrm_state_lookup(struct net *net, xfrm_address_t *d | |||
668 | hlist_for_each_entry(x, entry, net->xfrm.state_byspi+h, byspi) { | 668 | hlist_for_each_entry(x, entry, net->xfrm.state_byspi+h, byspi) { |
669 | if (x->props.family != family || | 669 | if (x->props.family != family || |
670 | x->id.spi != spi || | 670 | x->id.spi != spi || |
671 | x->id.proto != proto) | 671 | x->id.proto != proto || |
672 | xfrm_addr_cmp(&x->id.daddr, daddr, family)) | ||
672 | continue; | 673 | continue; |
673 | 674 | ||
674 | switch (family) { | ||
675 | case AF_INET: | ||
676 | if (x->id.daddr.a4 != daddr->a4) | ||
677 | continue; | ||
678 | break; | ||
679 | case AF_INET6: | ||
680 | if (!ipv6_addr_equal((struct in6_addr *)daddr, | ||
681 | (struct in6_addr *) | ||
682 | x->id.daddr.a6)) | ||
683 | continue; | ||
684 | break; | ||
685 | } | ||
686 | |||
687 | xfrm_state_hold(x); | 675 | xfrm_state_hold(x); |
688 | return x; | 676 | return x; |
689 | } | 677 | } |
@@ -699,26 +687,11 @@ static struct xfrm_state *__xfrm_state_lookup_byaddr(struct net *net, xfrm_addre | |||
699 | 687 | ||
700 | hlist_for_each_entry(x, entry, net->xfrm.state_bysrc+h, bysrc) { | 688 | hlist_for_each_entry(x, entry, net->xfrm.state_bysrc+h, bysrc) { |
701 | if (x->props.family != family || | 689 | if (x->props.family != family || |
702 | x->id.proto != proto) | 690 | x->id.proto != proto || |
691 | xfrm_addr_cmp(&x->id.daddr, daddr, family) || | ||
692 | xfrm_addr_cmp(&x->props.saddr, saddr, family)) | ||
703 | continue; | 693 | continue; |
704 | 694 | ||
705 | switch (family) { | ||
706 | case AF_INET: | ||
707 | if (x->id.daddr.a4 != daddr->a4 || | ||
708 | x->props.saddr.a4 != saddr->a4) | ||
709 | continue; | ||
710 | break; | ||
711 | case AF_INET6: | ||
712 | if (!ipv6_addr_equal((struct in6_addr *)daddr, | ||
713 | (struct in6_addr *) | ||
714 | x->id.daddr.a6) || | ||
715 | !ipv6_addr_equal((struct in6_addr *)saddr, | ||
716 | (struct in6_addr *) | ||
717 | x->props.saddr.a6)) | ||
718 | continue; | ||
719 | break; | ||
720 | } | ||
721 | |||
722 | xfrm_state_hold(x); | 695 | xfrm_state_hold(x); |
723 | return x; | 696 | return x; |
724 | } | 697 | } |
@@ -1001,25 +974,11 @@ static struct xfrm_state *__find_acq_core(struct net *net, unsigned short family | |||
1001 | x->props.family != family || | 974 | x->props.family != family || |
1002 | x->km.state != XFRM_STATE_ACQ || | 975 | x->km.state != XFRM_STATE_ACQ || |
1003 | x->id.spi != 0 || | 976 | x->id.spi != 0 || |
1004 | x->id.proto != proto) | 977 | x->id.proto != proto || |
978 | xfrm_addr_cmp(&x->id.daddr, daddr, family) || | ||
979 | xfrm_addr_cmp(&x->props.saddr, saddr, family)) | ||
1005 | continue; | 980 | continue; |
1006 | 981 | ||
1007 | switch (family) { | ||
1008 | case AF_INET: | ||
1009 | if (x->id.daddr.a4 != daddr->a4 || | ||
1010 | x->props.saddr.a4 != saddr->a4) | ||
1011 | continue; | ||
1012 | break; | ||
1013 | case AF_INET6: | ||
1014 | if (!ipv6_addr_equal((struct in6_addr *)x->id.daddr.a6, | ||
1015 | (struct in6_addr *)daddr) || | ||
1016 | !ipv6_addr_equal((struct in6_addr *) | ||
1017 | x->props.saddr.a6, | ||
1018 | (struct in6_addr *)saddr)) | ||
1019 | continue; | ||
1020 | break; | ||
1021 | } | ||
1022 | |||
1023 | xfrm_state_hold(x); | 982 | xfrm_state_hold(x); |
1024 | return x; | 983 | return x; |
1025 | } | 984 | } |