| .. | .. |
|---|
| 329 | 329 | int m; |
|---|
| 330 | 330 | |
|---|
| 331 | 331 | sk_dst_confirm(sk); |
|---|
| 332 | | - if (net->ipv4.sysctl_tcp_nometrics_save || !dst) |
|---|
| 332 | + if (READ_ONCE(net->ipv4.sysctl_tcp_nometrics_save) || !dst) |
|---|
| 333 | 333 | return; |
|---|
| 334 | 334 | |
|---|
| 335 | 335 | rcu_read_lock(); |
|---|
| .. | .. |
|---|
| 385 | 385 | |
|---|
| 386 | 386 | if (tcp_in_initial_slowstart(tp)) { |
|---|
| 387 | 387 | /* Slow start still did not finish. */ |
|---|
| 388 | | - if (!tcp_metric_locked(tm, TCP_METRIC_SSTHRESH)) { |
|---|
| 388 | + if (!READ_ONCE(net->ipv4.sysctl_tcp_no_ssthresh_metrics_save) && |
|---|
| 389 | + !tcp_metric_locked(tm, TCP_METRIC_SSTHRESH)) { |
|---|
| 389 | 390 | val = tcp_metric_get(tm, TCP_METRIC_SSTHRESH); |
|---|
| 390 | 391 | if (val && (tp->snd_cwnd >> 1) > val) |
|---|
| 391 | 392 | tcp_metric_set(tm, TCP_METRIC_SSTHRESH, |
|---|
| .. | .. |
|---|
| 400 | 401 | } else if (!tcp_in_slow_start(tp) && |
|---|
| 401 | 402 | icsk->icsk_ca_state == TCP_CA_Open) { |
|---|
| 402 | 403 | /* Cong. avoidance phase, cwnd is reliable. */ |
|---|
| 403 | | - if (!tcp_metric_locked(tm, TCP_METRIC_SSTHRESH)) |
|---|
| 404 | + if (!READ_ONCE(net->ipv4.sysctl_tcp_no_ssthresh_metrics_save) && |
|---|
| 405 | + !tcp_metric_locked(tm, TCP_METRIC_SSTHRESH)) |
|---|
| 404 | 406 | tcp_metric_set(tm, TCP_METRIC_SSTHRESH, |
|---|
| 405 | 407 | max(tp->snd_cwnd >> 1, tp->snd_ssthresh)); |
|---|
| 406 | 408 | if (!tcp_metric_locked(tm, TCP_METRIC_CWND)) { |
|---|
| .. | .. |
|---|
| 416 | 418 | tcp_metric_set(tm, TCP_METRIC_CWND, |
|---|
| 417 | 419 | (val + tp->snd_ssthresh) >> 1); |
|---|
| 418 | 420 | } |
|---|
| 419 | | - if (!tcp_metric_locked(tm, TCP_METRIC_SSTHRESH)) { |
|---|
| 421 | + if (!READ_ONCE(net->ipv4.sysctl_tcp_no_ssthresh_metrics_save) && |
|---|
| 422 | + !tcp_metric_locked(tm, TCP_METRIC_SSTHRESH)) { |
|---|
| 420 | 423 | val = tcp_metric_get(tm, TCP_METRIC_SSTHRESH); |
|---|
| 421 | 424 | if (val && tp->snd_ssthresh > val) |
|---|
| 422 | 425 | tcp_metric_set(tm, TCP_METRIC_SSTHRESH, |
|---|
| .. | .. |
|---|
| 425 | 428 | if (!tcp_metric_locked(tm, TCP_METRIC_REORDERING)) { |
|---|
| 426 | 429 | val = tcp_metric_get(tm, TCP_METRIC_REORDERING); |
|---|
| 427 | 430 | if (val < tp->reordering && |
|---|
| 428 | | - tp->reordering != net->ipv4.sysctl_tcp_reordering) |
|---|
| 431 | + tp->reordering != |
|---|
| 432 | + READ_ONCE(net->ipv4.sysctl_tcp_reordering)) |
|---|
| 429 | 433 | tcp_metric_set(tm, TCP_METRIC_REORDERING, |
|---|
| 430 | 434 | tp->reordering); |
|---|
| 431 | 435 | } |
|---|
| .. | .. |
|---|
| 441 | 445 | { |
|---|
| 442 | 446 | struct dst_entry *dst = __sk_dst_get(sk); |
|---|
| 443 | 447 | struct tcp_sock *tp = tcp_sk(sk); |
|---|
| 448 | + struct net *net = sock_net(sk); |
|---|
| 444 | 449 | struct tcp_metrics_block *tm; |
|---|
| 445 | 450 | u32 val, crtt = 0; /* cached RTT scaled by 8 */ |
|---|
| 446 | 451 | |
|---|
| .. | .. |
|---|
| 458 | 463 | if (tcp_metric_locked(tm, TCP_METRIC_CWND)) |
|---|
| 459 | 464 | tp->snd_cwnd_clamp = tcp_metric_get(tm, TCP_METRIC_CWND); |
|---|
| 460 | 465 | |
|---|
| 461 | | - val = tcp_metric_get(tm, TCP_METRIC_SSTHRESH); |
|---|
| 466 | + val = READ_ONCE(net->ipv4.sysctl_tcp_no_ssthresh_metrics_save) ? |
|---|
| 467 | + 0 : tcp_metric_get(tm, TCP_METRIC_SSTHRESH); |
|---|
| 462 | 468 | if (val) { |
|---|
| 463 | 469 | tp->snd_ssthresh = val; |
|---|
| 464 | 470 | if (tp->snd_ssthresh > tp->snd_cwnd_clamp) |
|---|
| .. | .. |
|---|
| 512 | 518 | |
|---|
| 513 | 519 | inet_csk(sk)->icsk_rto = TCP_TIMEOUT_FALLBACK; |
|---|
| 514 | 520 | } |
|---|
| 515 | | - /* Cut cwnd down to 1 per RFC5681 if SYN or SYN-ACK has been |
|---|
| 516 | | - * retransmitted. In light of RFC6298 more aggressive 1sec |
|---|
| 517 | | - * initRTO, we only reset cwnd when more than 1 SYN/SYN-ACK |
|---|
| 518 | | - * retransmission has occurred. |
|---|
| 519 | | - */ |
|---|
| 520 | | - if (tp->total_retrans > 1) |
|---|
| 521 | | - tp->snd_cwnd = 1; |
|---|
| 522 | | - else |
|---|
| 523 | | - tp->snd_cwnd = tcp_init_cwnd(tp, dst); |
|---|
| 524 | | - tp->snd_cwnd_stamp = tcp_jiffies32; |
|---|
| 525 | 521 | } |
|---|
| 526 | 522 | |
|---|
| 527 | 523 | bool tcp_peer_is_proven(struct request_sock *req, struct dst_entry *dst) |
|---|
| .. | .. |
|---|
| 658 | 654 | { |
|---|
| 659 | 655 | int n = 0; |
|---|
| 660 | 656 | |
|---|
| 661 | | - nest = nla_nest_start(msg, TCP_METRICS_ATTR_VALS); |
|---|
| 657 | + nest = nla_nest_start_noflag(msg, TCP_METRICS_ATTR_VALS); |
|---|
| 662 | 658 | if (!nest) |
|---|
| 663 | 659 | goto nla_put_failure; |
|---|
| 664 | 660 | for (i = 0; i < TCP_METRIC_MAX_KERNEL + 1; i++) { |
|---|
| .. | .. |
|---|
| 948 | 944 | return 0; |
|---|
| 949 | 945 | } |
|---|
| 950 | 946 | |
|---|
| 951 | | -static const struct genl_ops tcp_metrics_nl_ops[] = { |
|---|
| 947 | +static const struct genl_small_ops tcp_metrics_nl_ops[] = { |
|---|
| 952 | 948 | { |
|---|
| 953 | 949 | .cmd = TCP_METRICS_CMD_GET, |
|---|
| 950 | + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
|---|
| 954 | 951 | .doit = tcp_metrics_nl_cmd_get, |
|---|
| 955 | 952 | .dumpit = tcp_metrics_nl_dump, |
|---|
| 956 | | - .policy = tcp_metrics_nl_policy, |
|---|
| 957 | 953 | }, |
|---|
| 958 | 954 | { |
|---|
| 959 | 955 | .cmd = TCP_METRICS_CMD_DEL, |
|---|
| 956 | + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
|---|
| 960 | 957 | .doit = tcp_metrics_nl_cmd_del, |
|---|
| 961 | | - .policy = tcp_metrics_nl_policy, |
|---|
| 962 | 958 | .flags = GENL_ADMIN_PERM, |
|---|
| 963 | 959 | }, |
|---|
| 964 | 960 | }; |
|---|
| .. | .. |
|---|
| 968 | 964 | .name = TCP_METRICS_GENL_NAME, |
|---|
| 969 | 965 | .version = TCP_METRICS_GENL_VERSION, |
|---|
| 970 | 966 | .maxattr = TCP_METRICS_ATTR_MAX, |
|---|
| 967 | + .policy = tcp_metrics_nl_policy, |
|---|
| 971 | 968 | .netnsok = true, |
|---|
| 972 | 969 | .module = THIS_MODULE, |
|---|
| 973 | | - .ops = tcp_metrics_nl_ops, |
|---|
| 974 | | - .n_ops = ARRAY_SIZE(tcp_metrics_nl_ops), |
|---|
| 970 | + .small_ops = tcp_metrics_nl_ops, |
|---|
| 971 | + .n_small_ops = ARRAY_SIZE(tcp_metrics_nl_ops), |
|---|
| 975 | 972 | }; |
|---|
| 976 | 973 | |
|---|
| 977 | 974 | static unsigned int tcpmhash_entries; |
|---|
| .. | .. |
|---|
| 1000 | 997 | |
|---|
| 1001 | 998 | slots = tcpmhash_entries; |
|---|
| 1002 | 999 | if (!slots) { |
|---|
| 1003 | | - if (totalram_pages >= 128 * 1024) |
|---|
| 1000 | + if (totalram_pages() >= 128 * 1024) |
|---|
| 1004 | 1001 | slots = 16 * 1024; |
|---|
| 1005 | 1002 | else |
|---|
| 1006 | 1003 | slots = 8 * 1024; |
|---|