aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-07-16 17:09:34 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-16 17:09:34 -0400
commit1a98c69af1ecd97bfd1f4e4539924a9192434e36 (patch)
treea243defcf921ea174f8e43fce11d06830a6a9c36 /net/ipv4
parent7a575f6b907ea5d207d2b5010293c189616eae34 (diff)
parentb6603fe574af289dbe9eb9fb4c540bca04f5a053 (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.c1
-rw-r--r--net/ipv4/icmp.c2
-rw-r--r--net/ipv4/igmp.c10
-rw-r--r--net/ipv4/ip_tunnel.c12
-rw-r--r--net/ipv4/route.c15
-rw-r--r--net/ipv4/tcp.c3
-rw-r--r--net/ipv4/tcp_input.c8
-rw-r--r--net/ipv4/tcp_output.c6
-rw-r--r--net/ipv4/udp.c5
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) 1975out:
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
1055out: 1055out:
1056 bh_unlock_sock(sk); 1056 bh_unlock_sock(sk);
1057 dst_release(odst);
1057} 1058}
1058EXPORT_SYMBOL_GPL(ipv4_sk_update_pmtu); 1059EXPORT_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:
1282out: 1282out:
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);
1285out_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
1899void tcp_clear_retrans(struct tcp_sock *tp) 1899void 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