diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/Kconfig | 1 | ||||
-rw-r--r-- | net/ipv4/fib_trie.c | 7 | ||||
-rw-r--r-- | net/ipv4/inet_diag.c | 21 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 1 | ||||
-rw-r--r-- | net/ipv4/ip_input.c | 5 | ||||
-rw-r--r-- | net/ipv4/ipconfig.c | 4 | ||||
-rw-r--r-- | net/ipv4/netfilter/nf_defrag_ipv4.c | 2 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 12 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 12 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 13 | ||||
-rw-r--r-- | net/ipv4/udp.c | 32 |
11 files changed, 70 insertions, 40 deletions
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index c22920525e5d..775824720b6b 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -353,6 +353,7 @@ config INET_ESP | |||
353 | select CRYPTO_CBC | 353 | select CRYPTO_CBC |
354 | select CRYPTO_SHA1 | 354 | select CRYPTO_SHA1 |
355 | select CRYPTO_DES | 355 | select CRYPTO_DES |
356 | select CRYPTO_ECHAINIV | ||
356 | ---help--- | 357 | ---help--- |
357 | Support for IPsec ESP. | 358 | Support for IPsec ESP. |
358 | 359 | ||
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 7aea0ccb6be6..d07fc076bea0 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -1394,9 +1394,10 @@ found: | |||
1394 | struct fib_info *fi = fa->fa_info; | 1394 | struct fib_info *fi = fa->fa_info; |
1395 | int nhsel, err; | 1395 | int nhsel, err; |
1396 | 1396 | ||
1397 | if ((index >= (1ul << fa->fa_slen)) && | 1397 | if ((BITS_PER_LONG > KEYLENGTH) || (fa->fa_slen < KEYLENGTH)) { |
1398 | ((BITS_PER_LONG > KEYLENGTH) || (fa->fa_slen != KEYLENGTH))) | 1398 | if (index >= (1ul << fa->fa_slen)) |
1399 | continue; | 1399 | continue; |
1400 | } | ||
1400 | if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos) | 1401 | if (fa->fa_tos && fa->fa_tos != flp->flowi4_tos) |
1401 | continue; | 1402 | continue; |
1402 | if (fi->fib_dead) | 1403 | if (fi->fib_dead) |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 8bb8e7ad8548..6029157a19ed 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
@@ -361,13 +361,20 @@ struct sock *inet_diag_find_one_icsk(struct net *net, | |||
361 | req->id.idiag_dport, req->id.idiag_src[0], | 361 | req->id.idiag_dport, req->id.idiag_src[0], |
362 | req->id.idiag_sport, req->id.idiag_if); | 362 | req->id.idiag_sport, req->id.idiag_if); |
363 | #if IS_ENABLED(CONFIG_IPV6) | 363 | #if IS_ENABLED(CONFIG_IPV6) |
364 | else if (req->sdiag_family == AF_INET6) | 364 | else if (req->sdiag_family == AF_INET6) { |
365 | sk = inet6_lookup(net, hashinfo, | 365 | if (ipv6_addr_v4mapped((struct in6_addr *)req->id.idiag_dst) && |
366 | (struct in6_addr *)req->id.idiag_dst, | 366 | ipv6_addr_v4mapped((struct in6_addr *)req->id.idiag_src)) |
367 | req->id.idiag_dport, | 367 | sk = inet_lookup(net, hashinfo, req->id.idiag_dst[3], |
368 | (struct in6_addr *)req->id.idiag_src, | 368 | req->id.idiag_dport, req->id.idiag_src[3], |
369 | req->id.idiag_sport, | 369 | req->id.idiag_sport, req->id.idiag_if); |
370 | req->id.idiag_if); | 370 | else |
371 | sk = inet6_lookup(net, hashinfo, | ||
372 | (struct in6_addr *)req->id.idiag_dst, | ||
373 | req->id.idiag_dport, | ||
374 | (struct in6_addr *)req->id.idiag_src, | ||
375 | req->id.idiag_sport, | ||
376 | req->id.idiag_if); | ||
377 | } | ||
371 | #endif | 378 | #endif |
372 | else | 379 | else |
373 | return ERR_PTR(-EINVAL); | 380 | return ERR_PTR(-EINVAL); |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 3f00810b7288..187c6fcc3027 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -661,6 +661,7 @@ int ip_defrag(struct net *net, struct sk_buff *skb, u32 user) | |||
661 | struct ipq *qp; | 661 | struct ipq *qp; |
662 | 662 | ||
663 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS); | 663 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS); |
664 | skb_orphan(skb); | ||
664 | 665 | ||
665 | /* Lookup (or create) queue header */ | 666 | /* Lookup (or create) queue header */ |
666 | qp = ip_find(net, ip_hdr(skb), user, vif); | 667 | qp = ip_find(net, ip_hdr(skb), user, vif); |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index b1209b63381f..d77eb0c3b684 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -316,7 +316,10 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
316 | const struct iphdr *iph = ip_hdr(skb); | 316 | const struct iphdr *iph = ip_hdr(skb); |
317 | struct rtable *rt; | 317 | struct rtable *rt; |
318 | 318 | ||
319 | if (sysctl_ip_early_demux && !skb_dst(skb) && !skb->sk) { | 319 | if (sysctl_ip_early_demux && |
320 | !skb_dst(skb) && | ||
321 | !skb->sk && | ||
322 | !ip_is_fragment(iph)) { | ||
320 | const struct net_protocol *ipprot; | 323 | const struct net_protocol *ipprot; |
321 | int protocol = iph->protocol; | 324 | int protocol = iph->protocol; |
322 | 325 | ||
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 67f7c9de0b16..2ed9dd2b5f2f 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -143,7 +143,11 @@ static char dhcp_client_identifier[253] __initdata; | |||
143 | 143 | ||
144 | /* Persistent data: */ | 144 | /* Persistent data: */ |
145 | 145 | ||
146 | #ifdef IPCONFIG_DYNAMIC | ||
146 | static int ic_proto_used; /* Protocol used, if any */ | 147 | static int ic_proto_used; /* Protocol used, if any */ |
148 | #else | ||
149 | #define ic_proto_used 0 | ||
150 | #endif | ||
147 | static __be32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */ | 151 | static __be32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */ |
148 | static u8 ic_domain[64]; /* DNS (not NIS) domain name */ | 152 | static u8 ic_domain[64]; /* DNS (not NIS) domain name */ |
149 | 153 | ||
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c index 6fb869f646bf..a04dee536b8e 100644 --- a/net/ipv4/netfilter/nf_defrag_ipv4.c +++ b/net/ipv4/netfilter/nf_defrag_ipv4.c | |||
@@ -27,8 +27,6 @@ static int nf_ct_ipv4_gather_frags(struct net *net, struct sk_buff *skb, | |||
27 | { | 27 | { |
28 | int err; | 28 | int err; |
29 | 29 | ||
30 | skb_orphan(skb); | ||
31 | |||
32 | local_bh_disable(); | 30 | local_bh_disable(); |
33 | err = ip_defrag(net, skb, user); | 31 | err = ip_defrag(net, skb, user); |
34 | local_bh_enable(); | 32 | local_bh_enable(); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index fd17eec93525..19746b3fcbbe 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -279,6 +279,7 @@ | |||
279 | 279 | ||
280 | #include <asm/uaccess.h> | 280 | #include <asm/uaccess.h> |
281 | #include <asm/ioctls.h> | 281 | #include <asm/ioctls.h> |
282 | #include <asm/unaligned.h> | ||
282 | #include <net/busy_poll.h> | 283 | #include <net/busy_poll.h> |
283 | 284 | ||
284 | int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT; | 285 | int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT; |
@@ -2638,6 +2639,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) | |||
2638 | const struct inet_connection_sock *icsk = inet_csk(sk); | 2639 | const struct inet_connection_sock *icsk = inet_csk(sk); |
2639 | u32 now = tcp_time_stamp; | 2640 | u32 now = tcp_time_stamp; |
2640 | unsigned int start; | 2641 | unsigned int start; |
2642 | u64 rate64; | ||
2641 | u32 rate; | 2643 | u32 rate; |
2642 | 2644 | ||
2643 | memset(info, 0, sizeof(*info)); | 2645 | memset(info, 0, sizeof(*info)); |
@@ -2703,15 +2705,17 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) | |||
2703 | info->tcpi_total_retrans = tp->total_retrans; | 2705 | info->tcpi_total_retrans = tp->total_retrans; |
2704 | 2706 | ||
2705 | rate = READ_ONCE(sk->sk_pacing_rate); | 2707 | rate = READ_ONCE(sk->sk_pacing_rate); |
2706 | info->tcpi_pacing_rate = rate != ~0U ? rate : ~0ULL; | 2708 | rate64 = rate != ~0U ? rate : ~0ULL; |
2709 | put_unaligned(rate64, &info->tcpi_pacing_rate); | ||
2707 | 2710 | ||
2708 | rate = READ_ONCE(sk->sk_max_pacing_rate); | 2711 | rate = READ_ONCE(sk->sk_max_pacing_rate); |
2709 | info->tcpi_max_pacing_rate = rate != ~0U ? rate : ~0ULL; | 2712 | rate64 = rate != ~0U ? rate : ~0ULL; |
2713 | put_unaligned(rate64, &info->tcpi_max_pacing_rate); | ||
2710 | 2714 | ||
2711 | do { | 2715 | do { |
2712 | start = u64_stats_fetch_begin_irq(&tp->syncp); | 2716 | start = u64_stats_fetch_begin_irq(&tp->syncp); |
2713 | info->tcpi_bytes_acked = tp->bytes_acked; | 2717 | put_unaligned(tp->bytes_acked, &info->tcpi_bytes_acked); |
2714 | info->tcpi_bytes_received = tp->bytes_received; | 2718 | put_unaligned(tp->bytes_received, &info->tcpi_bytes_received); |
2715 | } while (u64_stats_fetch_retry_irq(&tp->syncp, start)); | 2719 | } while (u64_stats_fetch_retry_irq(&tp->syncp, start)); |
2716 | info->tcpi_segs_out = tp->segs_out; | 2720 | info->tcpi_segs_out = tp->segs_out; |
2717 | info->tcpi_segs_in = tp->segs_in; | 2721 | info->tcpi_segs_in = tp->segs_in; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 0003d409fec5..1c2a73406261 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -2164,8 +2164,7 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head) | |||
2164 | { | 2164 | { |
2165 | struct tcp_sock *tp = tcp_sk(sk); | 2165 | struct tcp_sock *tp = tcp_sk(sk); |
2166 | struct sk_buff *skb; | 2166 | struct sk_buff *skb; |
2167 | int cnt, oldcnt; | 2167 | int cnt, oldcnt, lost; |
2168 | int err; | ||
2169 | unsigned int mss; | 2168 | unsigned int mss; |
2170 | /* Use SACK to deduce losses of new sequences sent during recovery */ | 2169 | /* Use SACK to deduce losses of new sequences sent during recovery */ |
2171 | const u32 loss_high = tcp_is_sack(tp) ? tp->snd_nxt : tp->high_seq; | 2170 | const u32 loss_high = tcp_is_sack(tp) ? tp->snd_nxt : tp->high_seq; |
@@ -2205,9 +2204,10 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int mark_head) | |||
2205 | break; | 2204 | break; |
2206 | 2205 | ||
2207 | mss = tcp_skb_mss(skb); | 2206 | mss = tcp_skb_mss(skb); |
2208 | err = tcp_fragment(sk, skb, (packets - oldcnt) * mss, | 2207 | /* If needed, chop off the prefix to mark as lost. */ |
2209 | mss, GFP_ATOMIC); | 2208 | lost = (packets - oldcnt) * mss; |
2210 | if (err < 0) | 2209 | if (lost < skb->len && |
2210 | tcp_fragment(sk, skb, lost, mss, GFP_ATOMIC) < 0) | ||
2211 | break; | 2211 | break; |
2212 | cnt = packets; | 2212 | cnt = packets; |
2213 | } | 2213 | } |
@@ -2366,8 +2366,6 @@ static void tcp_undo_cwnd_reduction(struct sock *sk, bool unmark_loss) | |||
2366 | tp->snd_ssthresh = tp->prior_ssthresh; | 2366 | tp->snd_ssthresh = tp->prior_ssthresh; |
2367 | tcp_ecn_withdraw_cwr(tp); | 2367 | tcp_ecn_withdraw_cwr(tp); |
2368 | } | 2368 | } |
2369 | } else { | ||
2370 | tp->snd_cwnd = max(tp->snd_cwnd, tp->snd_ssthresh); | ||
2371 | } | 2369 | } |
2372 | tp->snd_cwnd_stamp = tcp_time_stamp; | 2370 | tp->snd_cwnd_stamp = tcp_time_stamp; |
2373 | tp->undo_marker = 0; | 2371 | tp->undo_marker = 0; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 5ced3e4013e3..a4d523709ab3 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -707,7 +707,8 @@ release_sk1: | |||
707 | outside socket context is ugly, certainly. What can I do? | 707 | outside socket context is ugly, certainly. What can I do? |
708 | */ | 708 | */ |
709 | 709 | ||
710 | static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, | 710 | static void tcp_v4_send_ack(struct net *net, |
711 | struct sk_buff *skb, u32 seq, u32 ack, | ||
711 | u32 win, u32 tsval, u32 tsecr, int oif, | 712 | u32 win, u32 tsval, u32 tsecr, int oif, |
712 | struct tcp_md5sig_key *key, | 713 | struct tcp_md5sig_key *key, |
713 | int reply_flags, u8 tos) | 714 | int reply_flags, u8 tos) |
@@ -722,7 +723,6 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, | |||
722 | ]; | 723 | ]; |
723 | } rep; | 724 | } rep; |
724 | struct ip_reply_arg arg; | 725 | struct ip_reply_arg arg; |
725 | struct net *net = dev_net(skb_dst(skb)->dev); | ||
726 | 726 | ||
727 | memset(&rep.th, 0, sizeof(struct tcphdr)); | 727 | memset(&rep.th, 0, sizeof(struct tcphdr)); |
728 | memset(&arg, 0, sizeof(arg)); | 728 | memset(&arg, 0, sizeof(arg)); |
@@ -784,7 +784,8 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) | |||
784 | struct inet_timewait_sock *tw = inet_twsk(sk); | 784 | struct inet_timewait_sock *tw = inet_twsk(sk); |
785 | struct tcp_timewait_sock *tcptw = tcp_twsk(sk); | 785 | struct tcp_timewait_sock *tcptw = tcp_twsk(sk); |
786 | 786 | ||
787 | tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, | 787 | tcp_v4_send_ack(sock_net(sk), skb, |
788 | tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, | ||
788 | tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, | 789 | tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, |
789 | tcp_time_stamp + tcptw->tw_ts_offset, | 790 | tcp_time_stamp + tcptw->tw_ts_offset, |
790 | tcptw->tw_ts_recent, | 791 | tcptw->tw_ts_recent, |
@@ -803,8 +804,10 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, | |||
803 | /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV | 804 | /* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV |
804 | * sk->sk_state == TCP_SYN_RECV -> for Fast Open. | 805 | * sk->sk_state == TCP_SYN_RECV -> for Fast Open. |
805 | */ | 806 | */ |
806 | tcp_v4_send_ack(skb, (sk->sk_state == TCP_LISTEN) ? | 807 | u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 : |
807 | tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt, | 808 | tcp_sk(sk)->snd_nxt; |
809 | |||
810 | tcp_v4_send_ack(sock_net(sk), skb, seq, | ||
808 | tcp_rsk(req)->rcv_nxt, req->rsk_rcv_wnd, | 811 | tcp_rsk(req)->rcv_nxt, req->rsk_rcv_wnd, |
809 | tcp_time_stamp, | 812 | tcp_time_stamp, |
810 | req->ts_recent, | 813 | req->ts_recent, |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index dc45b538e237..be0b21852b13 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -499,6 +499,7 @@ static struct sock *udp4_lib_lookup2(struct net *net, | |||
499 | struct sock *sk, *result; | 499 | struct sock *sk, *result; |
500 | struct hlist_nulls_node *node; | 500 | struct hlist_nulls_node *node; |
501 | int score, badness, matches = 0, reuseport = 0; | 501 | int score, badness, matches = 0, reuseport = 0; |
502 | bool select_ok = true; | ||
502 | u32 hash = 0; | 503 | u32 hash = 0; |
503 | 504 | ||
504 | begin: | 505 | begin: |
@@ -512,14 +513,18 @@ begin: | |||
512 | badness = score; | 513 | badness = score; |
513 | reuseport = sk->sk_reuseport; | 514 | reuseport = sk->sk_reuseport; |
514 | if (reuseport) { | 515 | if (reuseport) { |
515 | struct sock *sk2; | ||
516 | hash = udp_ehashfn(net, daddr, hnum, | 516 | hash = udp_ehashfn(net, daddr, hnum, |
517 | saddr, sport); | 517 | saddr, sport); |
518 | sk2 = reuseport_select_sock(sk, hash, skb, | 518 | if (select_ok) { |
519 | sizeof(struct udphdr)); | 519 | struct sock *sk2; |
520 | if (sk2) { | 520 | |
521 | result = sk2; | 521 | sk2 = reuseport_select_sock(sk, hash, skb, |
522 | goto found; | 522 | sizeof(struct udphdr)); |
523 | if (sk2) { | ||
524 | result = sk2; | ||
525 | select_ok = false; | ||
526 | goto found; | ||
527 | } | ||
523 | } | 528 | } |
524 | matches = 1; | 529 | matches = 1; |
525 | } | 530 | } |
@@ -563,6 +568,7 @@ struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr, | |||
563 | unsigned int hash2, slot2, slot = udp_hashfn(net, hnum, udptable->mask); | 568 | unsigned int hash2, slot2, slot = udp_hashfn(net, hnum, udptable->mask); |
564 | struct udp_hslot *hslot2, *hslot = &udptable->hash[slot]; | 569 | struct udp_hslot *hslot2, *hslot = &udptable->hash[slot]; |
565 | int score, badness, matches = 0, reuseport = 0; | 570 | int score, badness, matches = 0, reuseport = 0; |
571 | bool select_ok = true; | ||
566 | u32 hash = 0; | 572 | u32 hash = 0; |
567 | 573 | ||
568 | rcu_read_lock(); | 574 | rcu_read_lock(); |
@@ -601,14 +607,18 @@ begin: | |||
601 | badness = score; | 607 | badness = score; |
602 | reuseport = sk->sk_reuseport; | 608 | reuseport = sk->sk_reuseport; |
603 | if (reuseport) { | 609 | if (reuseport) { |
604 | struct sock *sk2; | ||
605 | hash = udp_ehashfn(net, daddr, hnum, | 610 | hash = udp_ehashfn(net, daddr, hnum, |
606 | saddr, sport); | 611 | saddr, sport); |
607 | sk2 = reuseport_select_sock(sk, hash, skb, | 612 | if (select_ok) { |
613 | struct sock *sk2; | ||
614 | |||
615 | sk2 = reuseport_select_sock(sk, hash, skb, | ||
608 | sizeof(struct udphdr)); | 616 | sizeof(struct udphdr)); |
609 | if (sk2) { | 617 | if (sk2) { |
610 | result = sk2; | 618 | result = sk2; |
611 | goto found; | 619 | select_ok = false; |
620 | goto found; | ||
621 | } | ||
612 | } | 622 | } |
613 | matches = 1; | 623 | matches = 1; |
614 | } | 624 | } |