diff options
author | David S. Miller <davem@davemloft.net> | 2014-07-16 17:09:34 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-07-16 17:09:34 -0400 |
commit | 1a98c69af1ecd97bfd1f4e4539924a9192434e36 (patch) | |
tree | a243defcf921ea174f8e43fce11d06830a6a9c36 /net/ipv4 | |
parent | 7a575f6b907ea5d207d2b5010293c189616eae34 (diff) | |
parent | b6603fe574af289dbe9eb9fb4c540bca04f5a053 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/gre_demux.c | 1 | ||||
-rw-r--r-- | net/ipv4/icmp.c | 2 | ||||
-rw-r--r-- | net/ipv4/igmp.c | 10 | ||||
-rw-r--r-- | net/ipv4/ip_tunnel.c | 12 | ||||
-rw-r--r-- | net/ipv4/route.c | 15 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 3 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 8 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 6 | ||||
-rw-r--r-- | net/ipv4/udp.c | 5 |
9 files changed, 37 insertions, 25 deletions
diff --git a/net/ipv4/gre_demux.c b/net/ipv4/gre_demux.c index 4e9619bca732..0485bf7f8f03 100644 --- a/net/ipv4/gre_demux.c +++ b/net/ipv4/gre_demux.c | |||
@@ -68,6 +68,7 @@ void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi, | |||
68 | 68 | ||
69 | skb_push(skb, hdr_len); | 69 | skb_push(skb, hdr_len); |
70 | 70 | ||
71 | skb_reset_transport_header(skb); | ||
71 | greh = (struct gre_base_hdr *)skb->data; | 72 | greh = (struct gre_base_hdr *)skb->data; |
72 | greh->flags = tnl_flags_to_gre_flags(tpi->flags); | 73 | greh->flags = tnl_flags_to_gre_flags(tpi->flags); |
73 | greh->protocol = tpi->proto; | 74 | greh->protocol = tpi->proto; |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 79c3d947a481..42b7bcf8045b 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -739,8 +739,6 @@ static void icmp_unreach(struct sk_buff *skb) | |||
739 | /* fall through */ | 739 | /* fall through */ |
740 | case 0: | 740 | case 0: |
741 | info = ntohs(icmph->un.frag.mtu); | 741 | info = ntohs(icmph->un.frag.mtu); |
742 | if (!info) | ||
743 | goto out; | ||
744 | } | 742 | } |
745 | break; | 743 | break; |
746 | case ICMP_SR_FAILED: | 744 | case ICMP_SR_FAILED: |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 6748d420f714..db710b059bab 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -1944,6 +1944,10 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) | |||
1944 | 1944 | ||
1945 | rtnl_lock(); | 1945 | rtnl_lock(); |
1946 | in_dev = ip_mc_find_dev(net, imr); | 1946 | in_dev = ip_mc_find_dev(net, imr); |
1947 | if (!in_dev) { | ||
1948 | ret = -ENODEV; | ||
1949 | goto out; | ||
1950 | } | ||
1947 | ifindex = imr->imr_ifindex; | 1951 | ifindex = imr->imr_ifindex; |
1948 | for (imlp = &inet->mc_list; | 1952 | for (imlp = &inet->mc_list; |
1949 | (iml = rtnl_dereference(*imlp)) != NULL; | 1953 | (iml = rtnl_dereference(*imlp)) != NULL; |
@@ -1961,16 +1965,14 @@ int ip_mc_leave_group(struct sock *sk, struct ip_mreqn *imr) | |||
1961 | 1965 | ||
1962 | *imlp = iml->next_rcu; | 1966 | *imlp = iml->next_rcu; |
1963 | 1967 | ||
1964 | if (in_dev) | 1968 | ip_mc_dec_group(in_dev, group); |
1965 | ip_mc_dec_group(in_dev, group); | ||
1966 | rtnl_unlock(); | 1969 | rtnl_unlock(); |
1967 | /* decrease mem now to avoid the memleak warning */ | 1970 | /* decrease mem now to avoid the memleak warning */ |
1968 | atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); | 1971 | atomic_sub(sizeof(*iml), &sk->sk_omem_alloc); |
1969 | kfree_rcu(iml, rcu); | 1972 | kfree_rcu(iml, rcu); |
1970 | return 0; | 1973 | return 0; |
1971 | } | 1974 | } |
1972 | if (!in_dev) | 1975 | out: |
1973 | ret = -ENODEV; | ||
1974 | rtnl_unlock(); | 1976 | rtnl_unlock(); |
1975 | return ret; | 1977 | return ret; |
1976 | } | 1978 | } |
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 0157a7af20a8..dd8c8c765799 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
@@ -169,6 +169,7 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, | |||
169 | 169 | ||
170 | hlist_for_each_entry_rcu(t, head, hash_node) { | 170 | hlist_for_each_entry_rcu(t, head, hash_node) { |
171 | if (remote != t->parms.iph.daddr || | 171 | if (remote != t->parms.iph.daddr || |
172 | t->parms.iph.saddr != 0 || | ||
172 | !(t->dev->flags & IFF_UP)) | 173 | !(t->dev->flags & IFF_UP)) |
173 | continue; | 174 | continue; |
174 | 175 | ||
@@ -185,10 +186,11 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, | |||
185 | head = &itn->tunnels[hash]; | 186 | head = &itn->tunnels[hash]; |
186 | 187 | ||
187 | hlist_for_each_entry_rcu(t, head, hash_node) { | 188 | hlist_for_each_entry_rcu(t, head, hash_node) { |
188 | if ((local != t->parms.iph.saddr && | 189 | if ((local != t->parms.iph.saddr || t->parms.iph.daddr != 0) && |
189 | (local != t->parms.iph.daddr || | 190 | (local != t->parms.iph.daddr || !ipv4_is_multicast(local))) |
190 | !ipv4_is_multicast(local))) || | 191 | continue; |
191 | !(t->dev->flags & IFF_UP)) | 192 | |
193 | if (!(t->dev->flags & IFF_UP)) | ||
192 | continue; | 194 | continue; |
193 | 195 | ||
194 | if (!ip_tunnel_key_match(&t->parms, flags, key)) | 196 | if (!ip_tunnel_key_match(&t->parms, flags, key)) |
@@ -205,6 +207,8 @@ struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, | |||
205 | 207 | ||
206 | hlist_for_each_entry_rcu(t, head, hash_node) { | 208 | hlist_for_each_entry_rcu(t, head, hash_node) { |
207 | if (t->parms.i_key != key || | 209 | if (t->parms.i_key != key || |
210 | t->parms.iph.saddr != 0 || | ||
211 | t->parms.iph.daddr != 0 || | ||
208 | !(t->dev->flags & IFF_UP)) | 212 | !(t->dev->flags & IFF_UP)) |
209 | continue; | 213 | continue; |
210 | 214 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 082239ffe34a..3162ea923ded 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1010,7 +1010,7 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) | |||
1010 | const struct iphdr *iph = (const struct iphdr *) skb->data; | 1010 | const struct iphdr *iph = (const struct iphdr *) skb->data; |
1011 | struct flowi4 fl4; | 1011 | struct flowi4 fl4; |
1012 | struct rtable *rt; | 1012 | struct rtable *rt; |
1013 | struct dst_entry *dst; | 1013 | struct dst_entry *odst = NULL; |
1014 | bool new = false; | 1014 | bool new = false; |
1015 | 1015 | ||
1016 | bh_lock_sock(sk); | 1016 | bh_lock_sock(sk); |
@@ -1018,16 +1018,17 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) | |||
1018 | if (!ip_sk_accept_pmtu(sk)) | 1018 | if (!ip_sk_accept_pmtu(sk)) |
1019 | goto out; | 1019 | goto out; |
1020 | 1020 | ||
1021 | rt = (struct rtable *) __sk_dst_get(sk); | 1021 | odst = sk_dst_get(sk); |
1022 | 1022 | ||
1023 | if (sock_owned_by_user(sk) || !rt) { | 1023 | if (sock_owned_by_user(sk) || !odst) { |
1024 | __ipv4_sk_update_pmtu(skb, sk, mtu); | 1024 | __ipv4_sk_update_pmtu(skb, sk, mtu); |
1025 | goto out; | 1025 | goto out; |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0); | 1028 | __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0); |
1029 | 1029 | ||
1030 | if (!__sk_dst_check(sk, 0)) { | 1030 | rt = (struct rtable *)odst; |
1031 | if (odst->obsolete && odst->ops->check(odst, 0) == NULL) { | ||
1031 | rt = ip_route_output_flow(sock_net(sk), &fl4, sk); | 1032 | rt = ip_route_output_flow(sock_net(sk), &fl4, sk); |
1032 | if (IS_ERR(rt)) | 1033 | if (IS_ERR(rt)) |
1033 | goto out; | 1034 | goto out; |
@@ -1037,8 +1038,7 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) | |||
1037 | 1038 | ||
1038 | __ip_rt_update_pmtu((struct rtable *) rt->dst.path, &fl4, mtu); | 1039 | __ip_rt_update_pmtu((struct rtable *) rt->dst.path, &fl4, mtu); |
1039 | 1040 | ||
1040 | dst = dst_check(&rt->dst, 0); | 1041 | if (!dst_check(&rt->dst, 0)) { |
1041 | if (!dst) { | ||
1042 | if (new) | 1042 | if (new) |
1043 | dst_release(&rt->dst); | 1043 | dst_release(&rt->dst); |
1044 | 1044 | ||
@@ -1050,10 +1050,11 @@ void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) | |||
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | if (new) | 1052 | if (new) |
1053 | __sk_dst_set(sk, &rt->dst); | 1053 | sk_dst_set(sk, &rt->dst); |
1054 | 1054 | ||
1055 | out: | 1055 | out: |
1056 | bh_unlock_sock(sk); | 1056 | bh_unlock_sock(sk); |
1057 | dst_release(odst); | ||
1057 | } | 1058 | } |
1058 | EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu); | 1059 | EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu); |
1059 | 1060 | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index eb1dde37e678..9d2118e5fbc7 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1108,7 +1108,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1108 | if (unlikely(tp->repair)) { | 1108 | if (unlikely(tp->repair)) { |
1109 | if (tp->repair_queue == TCP_RECV_QUEUE) { | 1109 | if (tp->repair_queue == TCP_RECV_QUEUE) { |
1110 | copied = tcp_send_rcvq(sk, msg, size); | 1110 | copied = tcp_send_rcvq(sk, msg, size); |
1111 | goto out; | 1111 | goto out_nopush; |
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | err = -EINVAL; | 1114 | err = -EINVAL; |
@@ -1282,6 +1282,7 @@ wait_for_memory: | |||
1282 | out: | 1282 | out: |
1283 | if (copied) | 1283 | if (copied) |
1284 | tcp_push(sk, flags, mss_now, tp->nonagle, size_goal); | 1284 | tcp_push(sk, flags, mss_now, tp->nonagle, size_goal); |
1285 | out_nopush: | ||
1285 | release_sock(sk); | 1286 | release_sock(sk); |
1286 | return copied + copied_syn; | 1287 | return copied + copied_syn; |
1287 | 1288 | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2e16afba182c..7832d941dbcd 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -1106,7 +1106,7 @@ static bool tcp_check_dsack(struct sock *sk, const struct sk_buff *ack_skb, | |||
1106 | } | 1106 | } |
1107 | 1107 | ||
1108 | /* D-SACK for already forgotten data... Do dumb counting. */ | 1108 | /* D-SACK for already forgotten data... Do dumb counting. */ |
1109 | if (dup_sack && tp->undo_marker && tp->undo_retrans && | 1109 | if (dup_sack && tp->undo_marker && tp->undo_retrans > 0 && |
1110 | !after(end_seq_0, prior_snd_una) && | 1110 | !after(end_seq_0, prior_snd_una) && |
1111 | after(end_seq_0, tp->undo_marker)) | 1111 | after(end_seq_0, tp->undo_marker)) |
1112 | tp->undo_retrans--; | 1112 | tp->undo_retrans--; |
@@ -1187,7 +1187,7 @@ static u8 tcp_sacktag_one(struct sock *sk, | |||
1187 | 1187 | ||
1188 | /* Account D-SACK for retransmitted packet. */ | 1188 | /* Account D-SACK for retransmitted packet. */ |
1189 | if (dup_sack && (sacked & TCPCB_RETRANS)) { | 1189 | if (dup_sack && (sacked & TCPCB_RETRANS)) { |
1190 | if (tp->undo_marker && tp->undo_retrans && | 1190 | if (tp->undo_marker && tp->undo_retrans > 0 && |
1191 | after(end_seq, tp->undo_marker)) | 1191 | after(end_seq, tp->undo_marker)) |
1192 | tp->undo_retrans--; | 1192 | tp->undo_retrans--; |
1193 | if (sacked & TCPCB_SACKED_ACKED) | 1193 | if (sacked & TCPCB_SACKED_ACKED) |
@@ -1893,7 +1893,7 @@ static void tcp_clear_retrans_partial(struct tcp_sock *tp) | |||
1893 | tp->lost_out = 0; | 1893 | tp->lost_out = 0; |
1894 | 1894 | ||
1895 | tp->undo_marker = 0; | 1895 | tp->undo_marker = 0; |
1896 | tp->undo_retrans = 0; | 1896 | tp->undo_retrans = -1; |
1897 | } | 1897 | } |
1898 | 1898 | ||
1899 | void tcp_clear_retrans(struct tcp_sock *tp) | 1899 | void tcp_clear_retrans(struct tcp_sock *tp) |
@@ -2664,7 +2664,7 @@ static void tcp_enter_recovery(struct sock *sk, bool ece_ack) | |||
2664 | 2664 | ||
2665 | tp->prior_ssthresh = 0; | 2665 | tp->prior_ssthresh = 0; |
2666 | tp->undo_marker = tp->snd_una; | 2666 | tp->undo_marker = tp->snd_una; |
2667 | tp->undo_retrans = tp->retrans_out; | 2667 | tp->undo_retrans = tp->retrans_out ? : -1; |
2668 | 2668 | ||
2669 | if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) { | 2669 | if (inet_csk(sk)->icsk_ca_state < TCP_CA_CWR) { |
2670 | if (!ece_ack) | 2670 | if (!ece_ack) |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 306dd5dead7d..8fcfc91964ec 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2526,8 +2526,6 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
2526 | if (!tp->retrans_stamp) | 2526 | if (!tp->retrans_stamp) |
2527 | tp->retrans_stamp = TCP_SKB_CB(skb)->when; | 2527 | tp->retrans_stamp = TCP_SKB_CB(skb)->when; |
2528 | 2528 | ||
2529 | tp->undo_retrans += tcp_skb_pcount(skb); | ||
2530 | |||
2531 | /* snd_nxt is stored to detect loss of retransmitted segment, | 2529 | /* snd_nxt is stored to detect loss of retransmitted segment, |
2532 | * see tcp_input.c tcp_sacktag_write_queue(). | 2530 | * see tcp_input.c tcp_sacktag_write_queue(). |
2533 | */ | 2531 | */ |
@@ -2535,6 +2533,10 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
2535 | } else if (err != -EBUSY) { | 2533 | } else if (err != -EBUSY) { |
2536 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRETRANSFAIL); | 2534 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRETRANSFAIL); |
2537 | } | 2535 | } |
2536 | |||
2537 | if (tp->undo_retrans < 0) | ||
2538 | tp->undo_retrans = 0; | ||
2539 | tp->undo_retrans += tcp_skb_pcount(skb); | ||
2538 | return err; | 2540 | return err; |
2539 | } | 2541 | } |
2540 | 2542 | ||
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index f6dfe525584f..668af516f094 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1587,8 +1587,11 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) | |||
1587 | goto csum_error; | 1587 | goto csum_error; |
1588 | 1588 | ||
1589 | 1589 | ||
1590 | if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf)) | 1590 | if (sk_rcvqueues_full(sk, skb, sk->sk_rcvbuf)) { |
1591 | UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS, | ||
1592 | is_udplite); | ||
1591 | goto drop; | 1593 | goto drop; |
1594 | } | ||
1592 | 1595 | ||
1593 | rc = 0; | 1596 | rc = 0; |
1594 | 1597 | ||