This patch adds a helper function BPF_FUNC_tcp_sock and it is currently available for cg_skb and sched_(cls|act): struct bpf_tcp_sock *bpf_tcp_sock(struct bpf_sock *sk); int cg_skb_foo(struct __sk_buff *skb) { struct bpf_tcp_sock *tp; struct bpf_sock *sk; __u32 snd_cwnd; sk = skb->sk; if (!sk) return 1; tp = bpf_tcp_sock(sk); if (!tp) return 1; snd_cwnd = tp->snd_cwnd; /* ... */ return 1; } A 'struct bpf_tcp_sock' is also added to the uapi bpf.h to provide read-only access. bpf_tcp_sock has all the existing tcp_sock's fields that has already been exposed by the bpf_sock_ops. i.e. no new tcp_sock's fields are exposed in bpf.h. This helper returns a pointer to the tcp_sock. If it is not a tcp_sock or it cannot be traced back to a tcp_sock by sk_to_full_sk(), it returns NULL. Hence, the caller needs to check for NULL before accessing it. The current use case is to expose members from tcp_sock to allow a cg_skb_bpf_prog to provide per cgroup traffic policing/shaping.
Showing the changes to include/uapi/linux (1 of 4 files). Show all
Unified · Split
| @@ -2337,6 +2337,15 @@ union bpf_attr { · 2336 unmodified lines | |||
| 2337 | * Return | 2337 | * Return |
| 2338 | * A **struct bpf_sock** pointer on success, or NULL in | 2338 | * A **struct bpf_sock** pointer on success, or NULL in |
| 2339 | * case of failure. | 2339 | * case of failure. |
| 2340 | * | ||
| 2341 | * struct bpf_tcp_sock *bpf_tcp_sock(struct bpf_sock *sk) | ||
| 2342 | * Description | ||
| 2343 | * This helper gets a **struct bpf_tcp_sock** pointer from a | ||
| 2344 | * **struct bpf_sock** pointer. | ||
| 2345 | * | ||
| 2346 | * Return | ||
| 2347 | * A **struct bpf_tcp_sock** pointer on success, or NULL in | ||
| 2348 | * case of failure. | ||
| 2340 | */ | 2349 | */ |
| 2341 | #define __BPF_FUNC_MAPPER(FN) \ | 2350 | #define __BPF_FUNC_MAPPER(FN) \ |
| 2342 | FN(unspec), \ | 2351 | FN(unspec), \ |
| @@ -2434,7 +2443,8 @@ union bpf_attr { · 91 unmodified lines | |||
| 2434 | FN(rc_pointer_rel), \ | 2443 | FN(rc_pointer_rel), \ |
| 2435 | FN(spin_lock), \ | 2444 | FN(spin_lock), \ |
| 2436 | FN(spin_unlock), \ | 2445 | FN(spin_unlock), \ |
| 2437 | FN(sk_fullsock), | 2446 | FN(sk_fullsock), \ |
| 2447 | FN(tcp_sock), | ||
| 2438 | 2448 | ||
| 2439 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper | 2449 | /* integer value in 'imm' field of BPF_CALL instruction selects which helper |
| 2440 | * function eBPF program intends to call | 2450 | * function eBPF program intends to call |
| @@ -2616,6 +2626,45 @@ struct bpf_sock { · 175 unmodified lines | |||
| 2616 | __u32 state; | 2626 | __u32 state; |
| 2617 | }; | 2627 | }; |
| 2618 | 2628 | ||
| 2629 | struct bpf_tcp_sock { | ||
| 2630 | __u32 snd_cwnd; /* Sending congestion window */ | ||
| 2631 | __u32 srtt_us; /* smoothed round trip time << 3 in usecs */ | ||
| 2632 | __u32 rtt_min; | ||
| 2633 | __u32 snd_ssthresh; /* Slow start size threshold */ | ||
| 2634 | __u32 rcv_nxt; /* What we want to receive next */ | ||
| 2635 | __u32 snd_nxt; /* Next sequence we send */ | ||
| 2636 | __u32 snd_una; /* First byte we want an ack for */ | ||
| 2637 | __u32 mss_cache; /* Cached effective mss, not including SACKS */ | ||
| 2638 | __u32 ecn_flags; /* ECN status bits. */ | ||
| 2639 | __u32 rate_delivered; /* saved rate sample: packets delivered */ | ||
| 2640 | __u32 rate_interval_us; /* saved rate sample: time elapsed */ | ||
| 2641 | __u32 packets_out; /* Packets which are "in flight" */ | ||
| 2642 | __u32 retrans_out; /* Retransmitted packets out */ | ||
| 2643 | __u32 total_retrans; /* Total retransmits for entire connection */ | ||
| 2644 | __u32 segs_in; /* RFC4898 tcpEStatsPerfSegsIn | ||
| 2645 | * total number of segments in. | ||
| 2646 | */ | ||
| 2647 | __u32 data_segs_in; /* RFC4898 tcpEStatsPerfDataSegsIn | ||
| 2648 | * total number of data segments in. | ||
| 2649 | */ | ||
| 2650 | __u32 segs_out; /* RFC4898 tcpEStatsPerfSegsOut | ||
| 2651 | * The total number of segments sent. | ||
| 2652 | */ | ||
| 2653 | __u32 data_segs_out; /* RFC4898 tcpEStatsPerfDataSegsOut | ||
| 2654 | * total number of data segments sent. | ||
| 2655 | */ | ||
| 2656 | __u32 lost_out; /* Lost packets */ | ||
| 2657 | __u32 sacked_out; /* SACK'd packets */ | ||
| 2658 | __u64 bytes_received; /* RFC4898 tcpEStatsAppHCThruOctetsReceived | ||
| 2659 | * sum(delta(rcv_nxt)), or how many bytes | ||
| 2660 | * were acked. | ||
| 2661 | */ | ||
| 2662 | __u64 bytes_acked; /* RFC4898 tcpEStatsAppHCThruOctetsAcked | ||
| 2663 | * sum(delta(snd_una)), or how many bytes | ||
| 2664 | * were acked. | ||
| 2665 | */ | ||
| 2666 | }; | ||
| 2667 | |||
| 2619 | struct bpf_sock_tuple { | 2668 | struct bpf_sock_tuple { |
| 2620 | union { | 2669 | union { |
| 2621 | struct { | 2670 | struct { |