Skip to content

Commit cadd648

Browse files
author
Alexei Starovoitov
committed
Merge branch 'Add support to set window_clamp from bpf setsockops'
Prankur gupta says: ==================== This patch contains support to set tcp window_field field from bpf setsockops. v2: Used TCP_WINDOW_CLAMP setsockopt logic for bpf_setsockopt (review comment addressed) v3: Created a common function for duplicated code (review comment addressed) v4: Removing logic to pass struct sock and struct tcp_sock together (review comment addressed) ==================== Acked-by: Martin KaFai Lau <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
2 parents 2faa732 + 55144f3 commit cadd648

File tree

7 files changed

+60
-9
lines changed

7 files changed

+60
-9
lines changed

include/net/tcp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ void tcp_syn_ack_timeout(const struct request_sock *req);
406406
int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int nonblock,
407407
int flags, int *addr_len);
408408
int tcp_set_rcvlowat(struct sock *sk, int val);
409+
int tcp_set_window_clamp(struct sock *sk, int val);
409410
void tcp_data_ready(struct sock *sk);
410411
#ifdef CONFIG_MMU
411412
int tcp_mmap(struct file *file, struct socket *sock,

net/core/filter.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4910,6 +4910,9 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname,
49104910
tp->notsent_lowat = val;
49114911
sk->sk_write_space(sk);
49124912
break;
4913+
case TCP_WINDOW_CLAMP:
4914+
ret = tcp_set_window_clamp(sk, val);
4915+
break;
49134916
default:
49144917
ret = -EINVAL;
49154918
}

net/ipv4/tcp.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3022,6 +3022,21 @@ int tcp_sock_set_keepcnt(struct sock *sk, int val)
30223022
}
30233023
EXPORT_SYMBOL(tcp_sock_set_keepcnt);
30243024

3025+
int tcp_set_window_clamp(struct sock *sk, int val)
3026+
{
3027+
struct tcp_sock *tp = tcp_sk(sk);
3028+
3029+
if (!val) {
3030+
if (sk->sk_state != TCP_CLOSE)
3031+
return -EINVAL;
3032+
tp->window_clamp = 0;
3033+
} else {
3034+
tp->window_clamp = val < SOCK_MIN_RCVBUF / 2 ?
3035+
SOCK_MIN_RCVBUF / 2 : val;
3036+
}
3037+
return 0;
3038+
}
3039+
30253040
/*
30263041
* Socket option code for TCP.
30273042
*/
@@ -3235,15 +3250,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, int optname,
32353250
break;
32363251

32373252
case TCP_WINDOW_CLAMP:
3238-
if (!val) {
3239-
if (sk->sk_state != TCP_CLOSE) {
3240-
err = -EINVAL;
3241-
break;
3242-
}
3243-
tp->window_clamp = 0;
3244-
} else
3245-
tp->window_clamp = val < SOCK_MIN_RCVBUF / 2 ?
3246-
SOCK_MIN_RCVBUF / 2 : val;
3253+
err = tcp_set_window_clamp(sk, val);
32473254
break;
32483255

32493256
case TCP_QUICKACK:

tools/testing/selftests/bpf/bpf_tcp_helpers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ struct tcp_sock {
5656
__u32 rcv_nxt;
5757
__u32 snd_nxt;
5858
__u32 snd_una;
59+
__u32 window_clamp;
5960
__u8 ecn_flags;
6061
__u32 delivered;
6162
__u32 delivered_ce;

tools/testing/selftests/bpf/prog_tests/tcpbpf_user.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ static void verify_result(struct tcpbpf_globals *result)
4242

4343
/* check getsockopt for SAVED_SYN */
4444
ASSERT_EQ(result->tcp_saved_syn, 1, "tcp_saved_syn");
45+
46+
/* check getsockopt for window_clamp */
47+
ASSERT_EQ(result->window_clamp_client, 9216, "window_clamp_client");
48+
ASSERT_EQ(result->window_clamp_server, 9216, "window_clamp_server");
4549
}
4650

4751
static void run_test(struct tcpbpf_globals *result)

tools/testing/selftests/bpf/progs/test_tcpbpf_kern.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,41 @@
1212
#include <linux/tcp.h>
1313
#include <bpf/bpf_helpers.h>
1414
#include <bpf/bpf_endian.h>
15+
#include "bpf_tcp_helpers.h"
1516
#include "test_tcpbpf.h"
1617

1718
struct tcpbpf_globals global = {};
1819
int _version SEC("version") = 1;
1920

21+
/**
22+
* SOL_TCP is defined in <netinet/tcp.h> while
23+
* TCP_SAVED_SYN is defined in already included <linux/tcp.h>
24+
*/
25+
#ifndef SOL_TCP
26+
#define SOL_TCP 6
27+
#endif
28+
29+
static __always_inline int get_tp_window_clamp(struct bpf_sock_ops *skops)
30+
{
31+
struct bpf_sock *sk;
32+
struct tcp_sock *tp;
33+
34+
sk = skops->sk;
35+
if (!sk)
36+
return -1;
37+
tp = bpf_skc_to_tcp_sock(sk);
38+
if (!tp)
39+
return -1;
40+
return tp->window_clamp;
41+
}
42+
2043
SEC("sockops")
2144
int bpf_testcb(struct bpf_sock_ops *skops)
2245
{
2346
char header[sizeof(struct ipv6hdr) + sizeof(struct tcphdr)];
2447
struct bpf_sock_ops *reuse = skops;
2548
struct tcphdr *thdr;
49+
int window_clamp = 9216;
2650
int good_call_rv = 0;
2751
int bad_call_rv = 0;
2852
int save_syn = 1;
@@ -75,6 +99,11 @@ int bpf_testcb(struct bpf_sock_ops *skops)
7599
global.event_map |= (1 << op);
76100

77101
switch (op) {
102+
case BPF_SOCK_OPS_TCP_CONNECT_CB:
103+
rv = bpf_setsockopt(skops, SOL_TCP, TCP_WINDOW_CLAMP,
104+
&window_clamp, sizeof(window_clamp));
105+
global.window_clamp_client = get_tp_window_clamp(skops);
106+
break;
78107
case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
79108
/* Test failure to set largest cb flag (assumes not defined) */
80109
global.bad_cb_test_rv = bpf_sock_ops_cb_flags_set(skops, 0x80);
@@ -100,6 +129,10 @@ int bpf_testcb(struct bpf_sock_ops *skops)
100129
global.tcp_saved_syn = v;
101130
}
102131
}
132+
rv = bpf_setsockopt(skops, SOL_TCP, TCP_WINDOW_CLAMP,
133+
&window_clamp, sizeof(window_clamp));
134+
135+
global.window_clamp_server = get_tp_window_clamp(skops);
103136
break;
104137
case BPF_SOCK_OPS_RTO_CB:
105138
break;

tools/testing/selftests/bpf/test_tcpbpf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,7 @@ struct tcpbpf_globals {
1616
__u32 num_close_events;
1717
__u32 tcp_save_syn;
1818
__u32 tcp_saved_syn;
19+
__u32 window_clamp_client;
20+
__u32 window_clamp_server;
1921
};
2022
#endif

0 commit comments

Comments
 (0)