| @@ -438,6 +438,7 @@ struct tcp_out_options { · 437 unmodified lines |
| 438 | u8 ws; /* window scale, 0 to disable */ | 438 | u8 ws; /* window scale, 0 to disable */ |
| 439 | u8 num_sack_blocks; /* number of SACK blocks to include */ | 439 | u8 num_sack_blocks; /* number of SACK blocks to include */ |
| 440 | u8 hash_size; /* bytes in hash_location */ | 440 | u8 hash_size; /* bytes in hash_location */ |
| | 441 | u8 bpf_opt_len; /* length of BPF hdr option */ |
| 441 | __u8 *hash_location; /* temporary pointer, overloaded */ | 442 | __u8 *hash_location; /* temporary pointer, overloaded */ |
| 442 | __u32 tsval, tsecr; /* need to include OPTION_TS */ | 443 | __u32 tsval, tsecr; /* need to include OPTION_TS */ |
| 443 | struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ | 444 | struct tcp_fastopen_cookie *fastopen_cookie; /* Fast open cookie */ |
| @@ -452,6 +453,59 @@ static void mptcp_options_write(__be32 *ptr, struct tcp_out_options *opts) · 8 unmodified lines |
| 452 | #endif | 453 | #endif |
| 453 | } | 454 | } |
| 454 | | 455 | |
| | 456 | #ifdef CONFIG_CGROUP_BPF |
| | 457 | /* req, syn_skb and synack_type are used when writing synack */ |
| | 458 | static void bpf_skops_hdr_opt_len(struct sock *sk, struct sk_buff *skb, |
| | 459 | struct request_sock *req, |
| | 460 | struct sk_buff *syn_skb, |
| | 461 | enum tcp_synack_type synack_type, |
| | 462 | struct tcp_out_options *opts, |
| | 463 | unsigned int *remaining) |
| | 464 | { |
| | 465 | if (likely(!BPF_SOCK_OPS_TEST_FLAG(tcp_sk(sk), |
| | 466 | BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG)) || |
| | 467 | !*remaining) |
| | 468 | return; |
| | 469 | |
| | 470 | /* The bpf running context preparation and the actual bpf prog |
| | 471 | * calling will be implemented in a later PATCH together with |
| | 472 | * other bpf pieces. |
| | 473 | */ |
| | 474 | } |
| | 475 | |
| | 476 | static void bpf_skops_write_hdr_opt(struct sock *sk, struct sk_buff *skb, |
| | 477 | struct request_sock *req, |
| | 478 | struct sk_buff *syn_skb, |
| | 479 | enum tcp_synack_type synack_type, |
| | 480 | struct tcp_out_options *opts) |
| | 481 | { |
| | 482 | if (likely(!opts->bpf_opt_len)) |
| | 483 | return; |
| | 484 | |
| | 485 | /* The bpf running context preparation and the actual bpf prog |
| | 486 | * calling will be implemented in a later PATCH together with |
| | 487 | * other bpf pieces. |
| | 488 | */ |
| | 489 | } |
| | 490 | #else |
| | 491 | static void bpf_skops_hdr_opt_len(struct sock *sk, struct sk_buff *skb, |
| | 492 | struct request_sock *req, |
| | 493 | struct sk_buff *syn_skb, |
| | 494 | enum tcp_synack_type synack_type, |
| | 495 | struct tcp_out_options *opts, |
| | 496 | unsigned int *remaining) |
| | 497 | { |
| | 498 | } |
| | 499 | |
| | 500 | static void bpf_skops_write_hdr_opt(struct sock *sk, struct sk_buff *skb, |
| | 501 | struct request_sock *req, |
| | 502 | struct sk_buff *syn_skb, |
| | 503 | enum tcp_synack_type synack_type, |
| | 504 | struct tcp_out_options *opts) |
| | 505 | { |
| | 506 | } |
| | 507 | #endif |
| | 508 | |
| 455 | /* Write previously computed TCP options to the packet. | 509 | /* Write previously computed TCP options to the packet. |
| 456 | * | 510 | * |
| 457 | * Beware: Something in the Internet is very sensitive to the ordering of | 511 | * Beware: Something in the Internet is very sensitive to the ordering of |
| @@ -691,6 +745,8 @@ static unsigned int tcp_syn_options(struct sock *sk, struct sk_buff *skb, · 233 unmodified lines |
| 691 | } | 745 | } |
| 692 | } | 746 | } |
| 693 | | 747 | |
| | 748 | bpf_skops_hdr_opt_len(sk, skb, NULL, NULL, 0, opts, &remaining); |
| | 749 | |
| 694 | return MAX_TCP_OPTION_SPACE - remaining; | 750 | return MAX_TCP_OPTION_SPACE - remaining; |
| 695 | } | 751 | } |
| 696 | | 752 | |
| @@ -701,7 +757,8 @@ static unsigned int tcp_synack_options(const struct sock *sk, · 4 unmodified lines |
| 701 | struct tcp_out_options *opts, | 757 | struct tcp_out_options *opts, |
| 702 | const struct tcp_md5sig_key *md5, | 758 | const struct tcp_md5sig_key *md5, |
| 703 | struct tcp_fastopen_cookie *foc, | 759 | struct tcp_fastopen_cookie *foc, |
| 704 | enum tcp_synack_type synack_type) | 760 | enum tcp_synack_type synack_type, |
| | 761 | struct sk_buff *syn_skb) |
| 705 | { | 762 | { |
| 706 | struct inet_request_sock *ireq = inet_rsk(req); | 763 | struct inet_request_sock *ireq = inet_rsk(req); |
| 707 | unsigned int remaining = MAX_TCP_OPTION_SPACE; | 764 | unsigned int remaining = MAX_TCP_OPTION_SPACE; |
| @@ -758,6 +815,9 @@ static unsigned int tcp_synack_options(const struct sock *sk, · 50 unmodified lines |
| 758 | | 815 | |
| 759 | smc_set_option_cond(tcp_sk(sk), ireq, opts, &remaining); | 816 | smc_set_option_cond(tcp_sk(sk), ireq, opts, &remaining); |
| 760 | | 817 | |
| | 818 | bpf_skops_hdr_opt_len((struct sock *)sk, skb, req, syn_skb, |
| | 819 | synack_type, opts, &remaining); |
| | 820 | |
| 761 | return MAX_TCP_OPTION_SPACE - remaining; | 821 | return MAX_TCP_OPTION_SPACE - remaining; |
| 762 | } | 822 | } |
| 763 | | 823 | |
| @@ -826,6 +886,15 @@ static unsigned int tcp_established_options(struct sock *sk, struct sk_buff *skb · 62 unmodified lines |
| 826 | opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; | 886 | opts->num_sack_blocks * TCPOLEN_SACK_PERBLOCK; |
| 827 | } | 887 | } |
| 828 | | 888 | |
| | 889 | if (unlikely(BPF_SOCK_OPS_TEST_FLAG(tp, |
| | 890 | BPF_SOCK_OPS_WRITE_HDR_OPT_CB_FLAG))) { |
| | 891 | unsigned int remaining = MAX_TCP_OPTION_SPACE - size; |
| | 892 | |
| | 893 | bpf_skops_hdr_opt_len(sk, skb, NULL, NULL, 0, opts, &remaining); |
| | 894 | |
| | 895 | size = MAX_TCP_OPTION_SPACE - remaining; |
| | 896 | } |
| | 897 | |
| 829 | return size; | 898 | return size; |
| 830 | } | 899 | } |
| 831 | | 900 | |
| @@ -1213,6 +1282,9 @@ static int __tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, · 381 unmodified lines |
| 1213 | } | 1282 | } |
| 1214 | #endif | 1283 | #endif |
| 1215 | | 1284 | |
| | 1285 | /* BPF prog is the last one writing header option */ |
| | 1286 | bpf_skops_write_hdr_opt(sk, skb, NULL, NULL, 0, &opts); |
| | 1287 | |
| 1216 | INDIRECT_CALL_INET(icsk->icsk_af_ops->send_check, | 1288 | INDIRECT_CALL_INET(icsk->icsk_af_ops->send_check, |
| 1217 | tcp_v6_send_check, tcp_v4_send_check, | 1289 | tcp_v6_send_check, tcp_v4_send_check, |
| 1218 | sk, skb); | 1290 | sk, skb); |
| @@ -3336,20 +3408,20 @@ int tcp_send_synack(struct sock *sk) · 2117 unmodified lines |
| 3336 | } | 3408 | } |
| 3337 | | 3409 | |
| 3338 | /** | 3410 | /** |
| 3339 | * tcp_make_synack - Prepare a SYN-ACK. | 3411 | * tcp_make_synack - Allocate one skb and build a SYNACK packet. |
| 3340 | * sk: listener socket | 3412 | * @sk: listener socket |
| 3341 | * dst: dst entry attached to the SYNACK | 3413 | * @dst: dst entry attached to the SYNACK. It is consumed and caller |
| 3342 | * req: request_sock pointer | 3414 | * should not use it again. |
| 3343 | * foc: cookie for tcp fast open | 3415 | * @req: request_sock pointer |
| 3344 | * synack_type: Type of synback to prepare | 3416 | * @foc: cookie for tcp fast open |
| 3345 | * | 3417 | * @synack_type: Type of synack to prepare |
| 3346 | * Allocate one skb and build a SYNACK packet. | 3418 | * @syn_skb: SYN packet just received. It could be NULL for rtx case. |
| 3347 | * @dst is consumed : Caller should not use it again. | | |
| 3348 | */ | 3419 | */ |
| 3349 | struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, | 3420 | struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, |
| 3350 | struct request_sock *req, | 3421 | struct request_sock *req, |
| 3351 | struct tcp_fastopen_cookie *foc, | 3422 | struct tcp_fastopen_cookie *foc, |
| 3352 | enum tcp_synack_type synack_type) | 3423 | enum tcp_synack_type synack_type, |
| | 3424 | struct sk_buff *syn_skb) |
| 3353 | { | 3425 | { |
| 3354 | struct inet_request_sock *ireq = inet_rsk(req); | 3426 | struct inet_request_sock *ireq = inet_rsk(req); |
| 3355 | const struct tcp_sock *tp = tcp_sk(sk); | 3427 | const struct tcp_sock *tp = tcp_sk(sk); |
| @@ -3408,8 +3480,11 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, · 52 unmodified lines |
| 3408 | md5 = tcp_rsk(req)->af_specific->req_md5_lookup(sk, req_to_sk(req)); | 3480 | md5 = tcp_rsk(req)->af_specific->req_md5_lookup(sk, req_to_sk(req)); |
| 3409 | #endif | 3481 | #endif |
| 3410 | skb_set_hash(skb, tcp_rsk(req)->txhash, PKT_HASH_TYPE_L4); | 3482 | skb_set_hash(skb, tcp_rsk(req)->txhash, PKT_HASH_TYPE_L4); |
| | 3483 | /* bpf program will be interested in the tcp_flags */ |
| | 3484 | TCP_SKB_CB(skb)->tcp_flags = TCPHDR_SYN | TCPHDR_ACK; |
| 3411 | tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, md5, | 3485 | tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, md5, |
| 3412 | foc, synack_type) + sizeof(*th); | 3486 | foc, synack_type, |
| | 3487 | syn_skb) + sizeof(*th); |
| 3413 | | 3488 | |
| 3414 | skb_push(skb, tcp_header_size); | 3489 | skb_push(skb, tcp_header_size); |
| 3415 | skb_reset_transport_header(skb); | 3490 | skb_reset_transport_header(skb); |
| @@ -3441,6 +3516,9 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, · 25 unmodified lines |
| 3441 | rcu_read_unlock(); | 3516 | rcu_read_unlock(); |
| 3442 | #endif | 3517 | #endif |
| 3443 | | 3518 | |
| | 3519 | bpf_skops_write_hdr_opt((struct sock *)sk, skb, req, syn_skb, |
| | 3520 | synack_type, &opts); |
| | 3521 | |
| 3444 | skb->skb_mstamp_ns = now; | 3522 | skb->skb_mstamp_ns = now; |
| 3445 | tcp_add_tx_delay(skb, tp); | 3523 | tcp_add_tx_delay(skb, tp); |
| 3446 | | 3524 | |
| @@ -3936,7 +4014,8 @@ int tcp_rtx_synack(const struct sock *sk, struct request_sock *req) · 489 unmodified lines |
| 3936 | int res; | 4014 | int res; |
| 3937 | | 4015 | |
| 3938 | tcp_rsk(req)->txhash = net_tx_rndhash(); | 4016 | tcp_rsk(req)->txhash = net_tx_rndhash(); |
| 3939 | res = af_ops->send_synack(sk, NULL, &fl, req, NULL, TCP_SYNACK_NORMAL); | 4017 | res = af_ops->send_synack(sk, NULL, &fl, req, NULL, TCP_SYNACK_NORMAL, |
| | 4018 | NULL); |
| 3940 | if (!res) { | 4019 | if (!res) { |
| 3941 | __TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS); | 4020 | __TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS); |
| 3942 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSYNRETRANS); | 4021 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPSYNRETRANS); |