aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-12-02 13:09:07 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-12-02 13:09:07 -0500
commit5fc92de3c7106d17f85c245383ba072d810d6bb0 (patch)
tree1e27a49e82ca9736144cc73ad5544a7ddf906644 /net/ipv4
parentb0d8d2292160bb63de1972361ebed100c64b5b37 (diff)
parent833846e8fa0c51fb3e47bca8adfdd7b10643b737 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking updates from David Miller: "Here is a pile of bug fixes that accumulated while I was in Europe" 1) In fixing kernel leaks to userspace during copying of socket addresses, we broke a case that used to work, namely the user providing a buffer larger than the in-kernel generic socket address structure. This broke Ruby amongst other things. Fix from Dan Carpenter. 2) Fix regression added by byte queue limit support in 8139cp driver, from Yang Yingliang. 3) The addition of MSG_SENDPAGE_NOTLAST buggered up a few sendpage implementations, they should just treat it the same as MSG_MORE. Fix from Richard Weinberger and Shawn Landden. 4) Handle icmpv4 errors received on ipv6 SIT tunnels correctly, from Oussama Ghorbel. In particular we should send an ICMPv6 unreachable in such situations. 5) Fix some regressions in the recent genetlink fixes, in particular get the pmcraid driver to use the new safer interfaces correctly. From Johannes Berg. 6) macvtap was converted to use a per-cpu set of statistics, but some code was still bumping tx_dropped elsewhere. From Jason Wang. 7) Fix build failure of xen-netback due to missing include on some architectures, from Andy Whitecroft. 8) macvtap double counts received packets in statistics, fix from Vlad Yasevich. 9) Fix various cases of using *_STATS_BH() when *_STATS() is more appropriate. From Eric Dumazet and Hannes Frederic Sowa. 10) Pktgen ipsec mode doesn't update the ipv4 header length and checksum properly after encapsulation. Fix from Fan Du. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (61 commits) net/mlx4_en: Remove selftest TX queues empty condition {pktgen, xfrm} Update IPv4 header total len and checksum after tranformation virtio_net: make all RX paths handle erors consistently virtio_net: fix error handling for mergeable buffers virtio_net: Fixed a trivial typo (fitler --> filter) netem: fix gemodel loss generator netem: fix loss 4 state model netem: missing break in ge loss generator net/hsr: Support iproute print_opt ('ip -details ...') net/hsr: Very small fix of comment style. MAINTAINERS: Added net/hsr/ maintainer ipv6: fix possible seqlock deadlock in ip6_finish_output2 ixgbe: Make ixgbe_identify_qsfp_module_generic static ixgbe: turn NETIF_F_HW_L2FW_DOFFLOAD off by default ixgbe: ixgbe_fwd_ring_down needs to be static e1000: fix possible reset_task running after adapter down e1000: fix lockdep warning in e1000_reset_task e1000: prevent oops when adapter is being closed and reset simultaneously igb: Fixed Wake On LAN support inet: fix possible seqlock deadlocks ...
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ip_sockglue.c3
-rw-r--r--net/ipv4/ping.c7
-rw-r--r--net/ipv4/protocol.c8
-rw-r--r--net/ipv4/raw.c2
-rw-r--r--net/ipv4/tcp_ipv4.c2
-rw-r--r--net/ipv4/tcp_memcontrol.c2
-rw-r--r--net/ipv4/tcp_offload.c31
-rw-r--r--net/ipv4/udp.c7
8 files changed, 28 insertions, 34 deletions
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 3f858266fa7e..ddf32a6bc415 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -386,7 +386,7 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf
386/* 386/*
387 * Handle MSG_ERRQUEUE 387 * Handle MSG_ERRQUEUE
388 */ 388 */
389int ip_recv_error(struct sock *sk, struct msghdr *msg, int len) 389int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
390{ 390{
391 struct sock_exterr_skb *serr; 391 struct sock_exterr_skb *serr;
392 struct sk_buff *skb, *skb2; 392 struct sk_buff *skb, *skb2;
@@ -423,6 +423,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
423 serr->addr_offset); 423 serr->addr_offset);
424 sin->sin_port = serr->port; 424 sin->sin_port = serr->port;
425 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); 425 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
426 *addr_len = sizeof(*sin);
426 } 427 }
427 428
428 memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); 429 memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index 876c6ca2d8f9..242e7f4ed6f4 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -772,7 +772,7 @@ int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
772 err = PTR_ERR(rt); 772 err = PTR_ERR(rt);
773 rt = NULL; 773 rt = NULL;
774 if (err == -ENETUNREACH) 774 if (err == -ENETUNREACH)
775 IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); 775 IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
776 goto out; 776 goto out;
777 } 777 }
778 778
@@ -841,10 +841,11 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
841 841
842 if (flags & MSG_ERRQUEUE) { 842 if (flags & MSG_ERRQUEUE) {
843 if (family == AF_INET) { 843 if (family == AF_INET) {
844 return ip_recv_error(sk, msg, len); 844 return ip_recv_error(sk, msg, len, addr_len);
845#if IS_ENABLED(CONFIG_IPV6) 845#if IS_ENABLED(CONFIG_IPV6)
846 } else if (family == AF_INET6) { 846 } else if (family == AF_INET6) {
847 return pingv6_ops.ipv6_recv_error(sk, msg, len); 847 return pingv6_ops.ipv6_recv_error(sk, msg, len,
848 addr_len);
848#endif 849#endif
849 } 850 }
850 } 851 }
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c
index ce848461acbb..46d6a1c923a8 100644
--- a/net/ipv4/protocol.c
+++ b/net/ipv4/protocol.c
@@ -31,10 +31,6 @@
31const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly; 31const struct net_protocol __rcu *inet_protos[MAX_INET_PROTOS] __read_mostly;
32const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS] __read_mostly; 32const struct net_offload __rcu *inet_offloads[MAX_INET_PROTOS] __read_mostly;
33 33
34/*
35 * Add a protocol handler to the hash tables
36 */
37
38int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol) 34int inet_add_protocol(const struct net_protocol *prot, unsigned char protocol)
39{ 35{
40 if (!prot->netns_ok) { 36 if (!prot->netns_ok) {
@@ -55,10 +51,6 @@ int inet_add_offload(const struct net_offload *prot, unsigned char protocol)
55} 51}
56EXPORT_SYMBOL(inet_add_offload); 52EXPORT_SYMBOL(inet_add_offload);
57 53
58/*
59 * Remove a protocol from the hash tables.
60 */
61
62int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol) 54int inet_del_protocol(const struct net_protocol *prot, unsigned char protocol)
63{ 55{
64 int ret; 56 int ret;
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 5cb8ddb505ee..23c3e5b5bb53 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -697,7 +697,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
697 goto out; 697 goto out;
698 698
699 if (flags & MSG_ERRQUEUE) { 699 if (flags & MSG_ERRQUEUE) {
700 err = ip_recv_error(sk, msg, len); 700 err = ip_recv_error(sk, msg, len, addr_len);
701 goto out; 701 goto out;
702 } 702 }
703 703
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 59a6f8b90cd9..067213924751 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -177,7 +177,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
177 if (IS_ERR(rt)) { 177 if (IS_ERR(rt)) {
178 err = PTR_ERR(rt); 178 err = PTR_ERR(rt);
179 if (err == -ENETUNREACH) 179 if (err == -ENETUNREACH)
180 IP_INC_STATS_BH(sock_net(sk), IPSTATS_MIB_OUTNOROUTES); 180 IP_INC_STATS(sock_net(sk), IPSTATS_MIB_OUTNOROUTES);
181 return err; 181 return err;
182 } 182 }
183 183
diff --git a/net/ipv4/tcp_memcontrol.c b/net/ipv4/tcp_memcontrol.c
index 03e9154f7e68..269a89ecd2f4 100644
--- a/net/ipv4/tcp_memcontrol.c
+++ b/net/ipv4/tcp_memcontrol.c
@@ -60,7 +60,6 @@ EXPORT_SYMBOL(tcp_destroy_cgroup);
60static int tcp_update_limit(struct mem_cgroup *memcg, u64 val) 60static int tcp_update_limit(struct mem_cgroup *memcg, u64 val)
61{ 61{
62 struct cg_proto *cg_proto; 62 struct cg_proto *cg_proto;
63 u64 old_lim;
64 int i; 63 int i;
65 int ret; 64 int ret;
66 65
@@ -71,7 +70,6 @@ static int tcp_update_limit(struct mem_cgroup *memcg, u64 val)
71 if (val > RES_COUNTER_MAX) 70 if (val > RES_COUNTER_MAX)
72 val = RES_COUNTER_MAX; 71 val = RES_COUNTER_MAX;
73 72
74 old_lim = res_counter_read_u64(&cg_proto->memory_allocated, RES_LIMIT);
75 ret = res_counter_set_limit(&cg_proto->memory_allocated, val); 73 ret = res_counter_set_limit(&cg_proto->memory_allocated, val);
76 if (ret) 74 if (ret)
77 return ret; 75 return ret;
diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
index a2b68a108eae..05606353c7e7 100644
--- a/net/ipv4/tcp_offload.c
+++ b/net/ipv4/tcp_offload.c
@@ -274,33 +274,32 @@ static struct sk_buff **tcp4_gro_receive(struct sk_buff **head, struct sk_buff *
274{ 274{
275 const struct iphdr *iph = skb_gro_network_header(skb); 275 const struct iphdr *iph = skb_gro_network_header(skb);
276 __wsum wsum; 276 __wsum wsum;
277 __sum16 sum; 277
278 /* Don't bother verifying checksum if we're going to flush anyway. */
279 if (NAPI_GRO_CB(skb)->flush)
280 goto skip_csum;
281
282 wsum = skb->csum;
278 283
279 switch (skb->ip_summed) { 284 switch (skb->ip_summed) {
285 case CHECKSUM_NONE:
286 wsum = skb_checksum(skb, skb_gro_offset(skb), skb_gro_len(skb),
287 0);
288
289 /* fall through */
290
280 case CHECKSUM_COMPLETE: 291 case CHECKSUM_COMPLETE:
281 if (!tcp_v4_check(skb_gro_len(skb), iph->saddr, iph->daddr, 292 if (!tcp_v4_check(skb_gro_len(skb), iph->saddr, iph->daddr,
282 skb->csum)) { 293 wsum)) {
283 skb->ip_summed = CHECKSUM_UNNECESSARY; 294 skb->ip_summed = CHECKSUM_UNNECESSARY;
284 break; 295 break;
285 } 296 }
286flush: 297
287 NAPI_GRO_CB(skb)->flush = 1; 298 NAPI_GRO_CB(skb)->flush = 1;
288 return NULL; 299 return NULL;
289
290 case CHECKSUM_NONE:
291 wsum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
292 skb_gro_len(skb), IPPROTO_TCP, 0);
293 sum = csum_fold(skb_checksum(skb,
294 skb_gro_offset(skb),
295 skb_gro_len(skb),
296 wsum));
297 if (sum)
298 goto flush;
299
300 skb->ip_summed = CHECKSUM_UNNECESSARY;
301 break;
302 } 300 }
303 301
302skip_csum:
304 return tcp_gro_receive(head, skb); 303 return tcp_gro_receive(head, skb);
305} 304}
306 305
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 5944d7d668dd..44f6a20fa29d 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -999,7 +999,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
999 err = PTR_ERR(rt); 999 err = PTR_ERR(rt);
1000 rt = NULL; 1000 rt = NULL;
1001 if (err == -ENETUNREACH) 1001 if (err == -ENETUNREACH)
1002 IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); 1002 IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES);
1003 goto out; 1003 goto out;
1004 } 1004 }
1005 1005
@@ -1098,6 +1098,9 @@ int udp_sendpage(struct sock *sk, struct page *page, int offset,
1098 struct udp_sock *up = udp_sk(sk); 1098 struct udp_sock *up = udp_sk(sk);
1099 int ret; 1099 int ret;
1100 1100
1101 if (flags & MSG_SENDPAGE_NOTLAST)
1102 flags |= MSG_MORE;
1103
1101 if (!up->pending) { 1104 if (!up->pending) {
1102 struct msghdr msg = { .msg_flags = flags|MSG_MORE }; 1105 struct msghdr msg = { .msg_flags = flags|MSG_MORE };
1103 1106
@@ -1236,7 +1239,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
1236 bool slow; 1239 bool slow;
1237 1240
1238 if (flags & MSG_ERRQUEUE) 1241 if (flags & MSG_ERRQUEUE)
1239 return ip_recv_error(sk, msg, len); 1242 return ip_recv_error(sk, msg, len, addr_len);
1240 1243
1241try_again: 1244try_again:
1242 skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0), 1245 skb = __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),