diff options
Diffstat (limited to 'net')
30 files changed, 213 insertions, 146 deletions
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index a2a1814c7a8d..8c2588e4edc0 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
| @@ -735,12 +735,14 @@ static int parse_opts(char *params, struct p9_fd_opts *opts) | |||
| 735 | if (!*p) | 735 | if (!*p) |
| 736 | continue; | 736 | continue; |
| 737 | token = match_token(p, tokens, args); | 737 | token = match_token(p, tokens, args); |
| 738 | r = match_int(&args[0], &option); | 738 | if (token != Opt_err) { |
| 739 | if (r < 0) { | 739 | r = match_int(&args[0], &option); |
| 740 | P9_DPRINTK(P9_DEBUG_ERROR, | 740 | if (r < 0) { |
| 741 | "integer field, but no integer?\n"); | 741 | P9_DPRINTK(P9_DEBUG_ERROR, |
| 742 | ret = r; | 742 | "integer field, but no integer?\n"); |
| 743 | continue; | 743 | ret = r; |
| 744 | continue; | ||
| 745 | } | ||
| 744 | } | 746 | } |
| 745 | switch (token) { | 747 | switch (token) { |
| 746 | case Opt_port: | 748 | case Opt_port: |
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/dsa/mv88e6xxx.c b/net/dsa/mv88e6xxx.c index 4e4d8b5ad03d..efe661a9def4 100644 --- a/net/dsa/mv88e6xxx.c +++ b/net/dsa/mv88e6xxx.c | |||
| @@ -418,7 +418,7 @@ static int mv88e6xxx_stats_wait(struct dsa_switch *ds) | |||
| 418 | int i; | 418 | int i; |
| 419 | 419 | ||
| 420 | for (i = 0; i < 10; i++) { | 420 | for (i = 0; i < 10; i++) { |
| 421 | ret = REG_READ(REG_GLOBAL2, 0x1d); | 421 | ret = REG_READ(REG_GLOBAL, 0x1d); |
| 422 | if ((ret & 0x8000) == 0) | 422 | if ((ret & 0x8000) == 0) |
| 423 | return 0; | 423 | return 0; |
| 424 | } | 424 | } |
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/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 60d918c96a4f..0071ee6f441f 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
| @@ -136,7 +136,8 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 136 | case IPPROTO_TCP: | 136 | case IPPROTO_TCP: |
| 137 | case IPPROTO_SCTP: | 137 | case IPPROTO_SCTP: |
| 138 | case IPPROTO_DCCP: | 138 | case IPPROTO_DCCP: |
| 139 | if (pskb_may_pull(skb, xprth + 4 - skb->data)) { | 139 | if (xprth + 4 < skb->data || |
| 140 | pskb_may_pull(skb, xprth + 4 - skb->data)) { | ||
| 140 | __be16 *ports = (__be16 *)xprth; | 141 | __be16 *ports = (__be16 *)xprth; |
| 141 | 142 | ||
| 142 | fl->fl_ip_sport = ports[!!reverse]; | 143 | fl->fl_ip_sport = ports[!!reverse]; |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 8c1e86afbbf5..43b3c9f89c12 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -1916,8 +1916,32 @@ ok: | |||
| 1916 | update_lft = 1; | 1916 | update_lft = 1; |
| 1917 | else if (stored_lft <= MIN_VALID_LIFETIME) { | 1917 | else if (stored_lft <= MIN_VALID_LIFETIME) { |
| 1918 | /* valid_lft <= stored_lft is always true */ | 1918 | /* valid_lft <= stored_lft is always true */ |
| 1919 | /* XXX: IPsec */ | 1919 | /* |
| 1920 | update_lft = 0; | 1920 | * RFC 4862 Section 5.5.3e: |
| 1921 | * "Note that the preferred lifetime of | ||
| 1922 | * the corresponding address is always | ||
| 1923 | * reset to the Preferred Lifetime in | ||
| 1924 | * the received Prefix Information | ||
| 1925 | * option, regardless of whether the | ||
| 1926 | * valid lifetime is also reset or | ||
| 1927 | * ignored." | ||
| 1928 | * | ||
| 1929 | * So if the preferred lifetime in | ||
| 1930 | * this advertisement is different | ||
| 1931 | * than what we have stored, but the | ||
| 1932 | * valid lifetime is invalid, just | ||
| 1933 | * reset prefered_lft. | ||
| 1934 | * | ||
| 1935 | * We must set the valid lifetime | ||
| 1936 | * to the stored lifetime since we'll | ||
| 1937 | * be updating the timestamp below, | ||
| 1938 | * else we'll set it back to the | ||
| 1939 | * minumum. | ||
| 1940 | */ | ||
| 1941 | if (prefered_lft != ifp->prefered_lft) { | ||
| 1942 | valid_lft = stored_lft; | ||
| 1943 | update_lft = 1; | ||
| 1944 | } | ||
| 1921 | } else { | 1945 | } else { |
| 1922 | valid_lft = MIN_VALID_LIFETIME; | 1946 | valid_lft = MIN_VALID_LIFETIME; |
| 1923 | if (valid_lft < prefered_lft) | 1947 | if (valid_lft < prefered_lft) |
| @@ -3085,7 +3109,7 @@ restart: | |||
| 3085 | spin_unlock(&ifp->lock); | 3109 | spin_unlock(&ifp->lock); |
| 3086 | continue; | 3110 | continue; |
| 3087 | } else if (age >= ifp->prefered_lft) { | 3111 | } else if (age >= ifp->prefered_lft) { |
| 3088 | /* jiffies - ifp->tsamp > age >= ifp->prefered_lft */ | 3112 | /* jiffies - ifp->tstamp > age >= ifp->prefered_lft */ |
| 3089 | int deprecate = 0; | 3113 | int deprecate = 0; |
| 3090 | 3114 | ||
| 3091 | if (!(ifp->flags&IFA_F_DEPRECATED)) { | 3115 | if (!(ifp->flags&IFA_F_DEPRECATED)) { |
| @@ -3362,7 +3386,10 @@ static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, | |||
| 3362 | valid = ifa->valid_lft; | 3386 | valid = ifa->valid_lft; |
| 3363 | if (preferred != INFINITY_LIFE_TIME) { | 3387 | if (preferred != INFINITY_LIFE_TIME) { |
| 3364 | long tval = (jiffies - ifa->tstamp)/HZ; | 3388 | long tval = (jiffies - ifa->tstamp)/HZ; |
| 3365 | preferred -= tval; | 3389 | if (preferred > tval) |
| 3390 | preferred -= tval; | ||
| 3391 | else | ||
| 3392 | preferred = 0; | ||
| 3366 | if (valid != INFINITY_LIFE_TIME) | 3393 | if (valid != INFINITY_LIFE_TIME) |
| 3367 | valid -= tval; | 3394 | valid -= tval; |
| 3368 | } | 3395 | } |
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/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index b4b16a43f277..3a3c677bc0f2 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
| @@ -157,7 +157,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 157 | ipv6_addr_copy(&fl->fl6_dst, reverse ? &hdr->saddr : &hdr->daddr); | 157 | ipv6_addr_copy(&fl->fl6_dst, reverse ? &hdr->saddr : &hdr->daddr); |
| 158 | ipv6_addr_copy(&fl->fl6_src, reverse ? &hdr->daddr : &hdr->saddr); | 158 | ipv6_addr_copy(&fl->fl6_src, reverse ? &hdr->daddr : &hdr->saddr); |
| 159 | 159 | ||
| 160 | while (pskb_may_pull(skb, nh + offset + 1 - skb->data)) { | 160 | while (nh + offset + 1 < skb->data || |
| 161 | pskb_may_pull(skb, nh + offset + 1 - skb->data)) { | ||
| 161 | nh = skb_network_header(skb); | 162 | nh = skb_network_header(skb); |
| 162 | exthdr = (struct ipv6_opt_hdr *)(nh + offset); | 163 | exthdr = (struct ipv6_opt_hdr *)(nh + offset); |
| 163 | 164 | ||
| @@ -177,7 +178,8 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 177 | case IPPROTO_TCP: | 178 | case IPPROTO_TCP: |
| 178 | case IPPROTO_SCTP: | 179 | case IPPROTO_SCTP: |
| 179 | case IPPROTO_DCCP: | 180 | case IPPROTO_DCCP: |
| 180 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 4 - skb->data)) { | 181 | if (!onlyproto && (nh + offset + 4 < skb->data || |
| 182 | pskb_may_pull(skb, nh + offset + 4 - skb->data))) { | ||
| 181 | __be16 *ports = (__be16 *)exthdr; | 183 | __be16 *ports = (__be16 *)exthdr; |
| 182 | 184 | ||
| 183 | fl->fl_ip_sport = ports[!!reverse]; | 185 | fl->fl_ip_sport = ports[!!reverse]; |
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/sctp/socket.c b/net/sctp/socket.c index 35ba035970a2..971890dbfea0 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -6652,21 +6652,6 @@ static void sctp_wait_for_close(struct sock *sk, long timeout) | |||
| 6652 | finish_wait(sk->sk_sleep, &wait); | 6652 | finish_wait(sk->sk_sleep, &wait); |
| 6653 | } | 6653 | } |
| 6654 | 6654 | ||
| 6655 | static void sctp_sock_rfree_frag(struct sk_buff *skb) | ||
| 6656 | { | ||
| 6657 | struct sk_buff *frag; | ||
| 6658 | |||
| 6659 | if (!skb->data_len) | ||
| 6660 | goto done; | ||
| 6661 | |||
| 6662 | /* Don't forget the fragments. */ | ||
| 6663 | skb_walk_frags(skb, frag) | ||
| 6664 | sctp_sock_rfree_frag(frag); | ||
| 6665 | |||
| 6666 | done: | ||
| 6667 | sctp_sock_rfree(skb); | ||
| 6668 | } | ||
| 6669 | |||
| 6670 | static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) | 6655 | static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk) |
| 6671 | { | 6656 | { |
| 6672 | struct sk_buff *frag; | 6657 | struct sk_buff *frag; |
| @@ -6776,7 +6761,6 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
| 6776 | sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { | 6761 | sctp_skb_for_each(skb, &oldsk->sk_receive_queue, tmp) { |
| 6777 | event = sctp_skb2event(skb); | 6762 | event = sctp_skb2event(skb); |
| 6778 | if (event->asoc == assoc) { | 6763 | if (event->asoc == assoc) { |
| 6779 | sctp_sock_rfree_frag(skb); | ||
| 6780 | __skb_unlink(skb, &oldsk->sk_receive_queue); | 6764 | __skb_unlink(skb, &oldsk->sk_receive_queue); |
| 6781 | __skb_queue_tail(&newsk->sk_receive_queue, skb); | 6765 | __skb_queue_tail(&newsk->sk_receive_queue, skb); |
| 6782 | sctp_skb_set_owner_r_frag(skb, newsk); | 6766 | sctp_skb_set_owner_r_frag(skb, newsk); |
| @@ -6807,7 +6791,6 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
| 6807 | sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { | 6791 | sctp_skb_for_each(skb, &oldsp->pd_lobby, tmp) { |
| 6808 | event = sctp_skb2event(skb); | 6792 | event = sctp_skb2event(skb); |
| 6809 | if (event->asoc == assoc) { | 6793 | if (event->asoc == assoc) { |
| 6810 | sctp_sock_rfree_frag(skb); | ||
| 6811 | __skb_unlink(skb, &oldsp->pd_lobby); | 6794 | __skb_unlink(skb, &oldsp->pd_lobby); |
| 6812 | __skb_queue_tail(queue, skb); | 6795 | __skb_queue_tail(queue, skb); |
| 6813 | sctp_skb_set_owner_r_frag(skb, newsk); | 6796 | sctp_skb_set_owner_r_frag(skb, newsk); |
| @@ -6822,15 +6805,11 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, | |||
| 6822 | 6805 | ||
| 6823 | } | 6806 | } |
| 6824 | 6807 | ||
| 6825 | sctp_skb_for_each(skb, &assoc->ulpq.reasm, tmp) { | 6808 | sctp_skb_for_each(skb, &assoc->ulpq.reasm, tmp) |
| 6826 | sctp_sock_rfree_frag(skb); | ||
| 6827 | sctp_skb_set_owner_r_frag(skb, newsk); | 6809 | sctp_skb_set_owner_r_frag(skb, newsk); |
| 6828 | } | ||
| 6829 | 6810 | ||
| 6830 | sctp_skb_for_each(skb, &assoc->ulpq.lobby, tmp) { | 6811 | sctp_skb_for_each(skb, &assoc->ulpq.lobby, tmp) |
| 6831 | sctp_sock_rfree_frag(skb); | ||
| 6832 | sctp_skb_set_owner_r_frag(skb, newsk); | 6812 | sctp_skb_set_owner_r_frag(skb, newsk); |
| 6833 | } | ||
| 6834 | 6813 | ||
| 6835 | /* Set the type of socket to indicate that it is peeled off from the | 6814 | /* Set the type of socket to indicate that it is peeled off from the |
| 6836 | * original UDP-style socket or created with the accept() call on a | 6815 | * original UDP-style socket or created with the accept() call on a |
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 | } |
