diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/af_inet.c | 11 | ||||
-rw-r--r-- | net/ipv4/fib_rules.c | 4 | ||||
-rw-r--r-- | net/ipv4/igmp.c | 11 | ||||
-rw-r--r-- | net/ipv4/ip_vti.c | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/nft_masq_ipv4.c | 1 | ||||
-rw-r--r-- | net/ipv4/ping.c | 14 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 4 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 5 |
9 files changed, 33 insertions, 20 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 8b7fe5b03906..e67da4e6c324 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -1386,6 +1386,17 @@ out: | |||
1386 | return pp; | 1386 | return pp; |
1387 | } | 1387 | } |
1388 | 1388 | ||
1389 | int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) | ||
1390 | { | ||
1391 | if (sk->sk_family == AF_INET) | ||
1392 | return ip_recv_error(sk, msg, len, addr_len); | ||
1393 | #if IS_ENABLED(CONFIG_IPV6) | ||
1394 | if (sk->sk_family == AF_INET6) | ||
1395 | return pingv6_ops.ipv6_recv_error(sk, msg, len, addr_len); | ||
1396 | #endif | ||
1397 | return -EINVAL; | ||
1398 | } | ||
1399 | |||
1389 | static int inet_gro_complete(struct sk_buff *skb, int nhoff) | 1400 | static int inet_gro_complete(struct sk_buff *skb, int nhoff) |
1390 | { | 1401 | { |
1391 | __be16 newlen = htons(skb->len - nhoff); | 1402 | __be16 newlen = htons(skb->len - nhoff); |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index f2e15738534d..8f7bd56955b0 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -62,6 +62,10 @@ int __fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res) | |||
62 | else | 62 | else |
63 | res->tclassid = 0; | 63 | res->tclassid = 0; |
64 | #endif | 64 | #endif |
65 | |||
66 | if (err == -ESRCH) | ||
67 | err = -ENETUNREACH; | ||
68 | |||
65 | return err; | 69 | return err; |
66 | } | 70 | } |
67 | EXPORT_SYMBOL_GPL(__fib_lookup); | 71 | EXPORT_SYMBOL_GPL(__fib_lookup); |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index fb70e3ecc3e4..bb15d0e03d4f 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -318,9 +318,7 @@ igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted) | |||
318 | return scount; | 318 | return scount; |
319 | } | 319 | } |
320 | 320 | ||
321 | #define igmp_skb_size(skb) (*(unsigned int *)((skb)->cb)) | 321 | static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu) |
322 | |||
323 | static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | ||
324 | { | 322 | { |
325 | struct sk_buff *skb; | 323 | struct sk_buff *skb; |
326 | struct rtable *rt; | 324 | struct rtable *rt; |
@@ -330,6 +328,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | |||
330 | struct flowi4 fl4; | 328 | struct flowi4 fl4; |
331 | int hlen = LL_RESERVED_SPACE(dev); | 329 | int hlen = LL_RESERVED_SPACE(dev); |
332 | int tlen = dev->needed_tailroom; | 330 | int tlen = dev->needed_tailroom; |
331 | unsigned int size = mtu; | ||
333 | 332 | ||
334 | while (1) { | 333 | while (1) { |
335 | skb = alloc_skb(size + hlen + tlen, | 334 | skb = alloc_skb(size + hlen + tlen, |
@@ -341,7 +340,6 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | |||
341 | return NULL; | 340 | return NULL; |
342 | } | 341 | } |
343 | skb->priority = TC_PRIO_CONTROL; | 342 | skb->priority = TC_PRIO_CONTROL; |
344 | igmp_skb_size(skb) = size; | ||
345 | 343 | ||
346 | rt = ip_route_output_ports(net, &fl4, NULL, IGMPV3_ALL_MCR, 0, | 344 | rt = ip_route_output_ports(net, &fl4, NULL, IGMPV3_ALL_MCR, 0, |
347 | 0, 0, | 345 | 0, 0, |
@@ -354,6 +352,8 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, int size) | |||
354 | skb_dst_set(skb, &rt->dst); | 352 | skb_dst_set(skb, &rt->dst); |
355 | skb->dev = dev; | 353 | skb->dev = dev; |
356 | 354 | ||
355 | skb->reserved_tailroom = skb_end_offset(skb) - | ||
356 | min(mtu, skb_end_offset(skb)); | ||
357 | skb_reserve(skb, hlen); | 357 | skb_reserve(skb, hlen); |
358 | 358 | ||
359 | skb_reset_network_header(skb); | 359 | skb_reset_network_header(skb); |
@@ -423,8 +423,7 @@ static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc, | |||
423 | return skb; | 423 | return skb; |
424 | } | 424 | } |
425 | 425 | ||
426 | #define AVAILABLE(skb) ((skb) ? ((skb)->dev ? igmp_skb_size(skb) - (skb)->len : \ | 426 | #define AVAILABLE(skb) ((skb) ? skb_availroom(skb) : 0) |
427 | skb_tailroom(skb)) : 0) | ||
428 | 427 | ||
429 | static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, | 428 | static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, |
430 | int type, int gdeleted, int sdeleted) | 429 | int type, int gdeleted, int sdeleted) |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 3e861011e4a3..1a7e979e80ba 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -528,6 +528,7 @@ static struct rtnl_link_ops vti_link_ops __read_mostly = { | |||
528 | .validate = vti_tunnel_validate, | 528 | .validate = vti_tunnel_validate, |
529 | .newlink = vti_newlink, | 529 | .newlink = vti_newlink, |
530 | .changelink = vti_changelink, | 530 | .changelink = vti_changelink, |
531 | .dellink = ip_tunnel_dellink, | ||
531 | .get_size = vti_get_size, | 532 | .get_size = vti_get_size, |
532 | .fill_info = vti_fill_info, | 533 | .fill_info = vti_fill_info, |
533 | }; | 534 | }; |
diff --git a/net/ipv4/netfilter/nft_masq_ipv4.c b/net/ipv4/netfilter/nft_masq_ipv4.c index c1023c445920..665de06561cd 100644 --- a/net/ipv4/netfilter/nft_masq_ipv4.c +++ b/net/ipv4/netfilter/nft_masq_ipv4.c | |||
@@ -24,6 +24,7 @@ static void nft_masq_ipv4_eval(const struct nft_expr *expr, | |||
24 | struct nf_nat_range range; | 24 | struct nf_nat_range range; |
25 | unsigned int verdict; | 25 | unsigned int verdict; |
26 | 26 | ||
27 | memset(&range, 0, sizeof(range)); | ||
27 | range.flags = priv->flags; | 28 | range.flags = priv->flags; |
28 | 29 | ||
29 | verdict = nf_nat_masquerade_ipv4(pkt->skb, pkt->ops->hooknum, | 30 | verdict = nf_nat_masquerade_ipv4(pkt->skb, pkt->ops->hooknum, |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index 57f7c9804139..5d740cccf69e 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
@@ -217,6 +217,8 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident) | |||
217 | &ipv6_hdr(skb)->daddr)) | 217 | &ipv6_hdr(skb)->daddr)) |
218 | continue; | 218 | continue; |
219 | #endif | 219 | #endif |
220 | } else { | ||
221 | continue; | ||
220 | } | 222 | } |
221 | 223 | ||
222 | if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) | 224 | if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != dif) |
@@ -853,16 +855,8 @@ int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
853 | if (flags & MSG_OOB) | 855 | if (flags & MSG_OOB) |
854 | goto out; | 856 | goto out; |
855 | 857 | ||
856 | if (flags & MSG_ERRQUEUE) { | 858 | if (flags & MSG_ERRQUEUE) |
857 | if (family == AF_INET) { | 859 | return inet_recv_error(sk, msg, len, addr_len); |
858 | return ip_recv_error(sk, msg, len, addr_len); | ||
859 | #if IS_ENABLED(CONFIG_IPV6) | ||
860 | } else if (family == AF_INET6) { | ||
861 | return pingv6_ops.ipv6_recv_error(sk, msg, len, | ||
862 | addr_len); | ||
863 | #endif | ||
864 | } | ||
865 | } | ||
866 | 860 | ||
867 | skb = skb_recv_datagram(sk, flags, noblock, &err); | 861 | skb = skb_recv_datagram(sk, flags, noblock, &err); |
868 | if (!skb) | 862 | if (!skb) |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 39ec0c379545..38c2bcb8dd5d 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -1598,7 +1598,7 @@ int tcp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
1598 | u32 urg_hole = 0; | 1598 | u32 urg_hole = 0; |
1599 | 1599 | ||
1600 | if (unlikely(flags & MSG_ERRQUEUE)) | 1600 | if (unlikely(flags & MSG_ERRQUEUE)) |
1601 | return ip_recv_error(sk, msg, len, addr_len); | 1601 | return inet_recv_error(sk, msg, len, addr_len); |
1602 | 1602 | ||
1603 | if (sk_can_busy_loop(sk) && skb_queue_empty(&sk->sk_receive_queue) && | 1603 | if (sk_can_busy_loop(sk) && skb_queue_empty(&sk->sk_receive_queue) && |
1604 | (sk->sk_state == TCP_ESTABLISHED)) | 1604 | (sk->sk_state == TCP_ESTABLISHED)) |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 88fa2d160685..d107ee246a1d 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -5231,7 +5231,7 @@ slow_path: | |||
5231 | if (len < (th->doff << 2) || tcp_checksum_complete_user(sk, skb)) | 5231 | if (len < (th->doff << 2) || tcp_checksum_complete_user(sk, skb)) |
5232 | goto csum_error; | 5232 | goto csum_error; |
5233 | 5233 | ||
5234 | if (!th->ack && !th->rst) | 5234 | if (!th->ack && !th->rst && !th->syn) |
5235 | goto discard; | 5235 | goto discard; |
5236 | 5236 | ||
5237 | /* | 5237 | /* |
@@ -5650,7 +5650,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
5650 | goto discard; | 5650 | goto discard; |
5651 | } | 5651 | } |
5652 | 5652 | ||
5653 | if (!th->ack && !th->rst) | 5653 | if (!th->ack && !th->rst && !th->syn) |
5654 | goto discard; | 5654 | goto discard; |
5655 | 5655 | ||
5656 | if (!tcp_validate_incoming(sk, skb, th, 0)) | 5656 | if (!tcp_validate_incoming(sk, skb, th, 0)) |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 9c7d7621466b..147be2024290 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -598,7 +598,10 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb) | |||
598 | if (th->rst) | 598 | if (th->rst) |
599 | return; | 599 | return; |
600 | 600 | ||
601 | if (skb_rtable(skb)->rt_type != RTN_LOCAL) | 601 | /* If sk not NULL, it means we did a successful lookup and incoming |
602 | * route had to be correct. prequeue might have dropped our dst. | ||
603 | */ | ||
604 | if (!sk && skb_rtable(skb)->rt_type != RTN_LOCAL) | ||
602 | return; | 605 | return; |
603 | 606 | ||
604 | /* Swap the send and the receive. */ | 607 | /* Swap the send and the receive. */ |