1 // SPDX-License-Identifier: GPL-2.0
4 #include <netinet/in.h>
6 #include <linux/if_ether.h>
7 #include <linux/if_packet.h>
9 #include <linux/ipv6.h>
10 #include <linux/types.h>
11 #include <linux/socket.h>
12 #include <linux/tcp.h>
13 #include "bpf_helpers.h"
14 #include "bpf_endian.h"
15 #include "test_tcpbpf.h"
18 __uint(type
, BPF_MAP_TYPE_ARRAY
);
19 __uint(max_entries
, 4);
21 __type(value
, struct tcpbpf_globals
);
22 } global_map
SEC(".maps");
25 __uint(type
, BPF_MAP_TYPE_ARRAY
);
26 __uint(max_entries
, 2);
29 } sockopt_results
SEC(".maps");
31 static inline void update_event_map(int event
)
34 struct tcpbpf_globals g
, *gp
;
36 gp
= bpf_map_lookup_elem(&global_map
, &key
);
38 struct tcpbpf_globals g
= {0};
40 g
.event_map
|= (1 << event
);
41 bpf_map_update_elem(&global_map
, &key
, &g
,
45 g
.event_map
|= (1 << event
);
46 bpf_map_update_elem(&global_map
, &key
, &g
,
51 int _version
SEC("version") = 1;
54 int bpf_testcb(struct bpf_sock_ops
*skops
)
56 char header
[sizeof(struct ipv6hdr
) + sizeof(struct tcphdr
)];
70 case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB
:
71 /* Test failure to set largest cb flag (assumes not defined) */
72 bad_call_rv
= bpf_sock_ops_cb_flags_set(skops
, 0x80);
74 good_call_rv
= bpf_sock_ops_cb_flags_set(skops
,
75 BPF_SOCK_OPS_STATE_CB_FLAG
);
79 struct tcpbpf_globals g
, *gp
;
81 gp
= bpf_map_lookup_elem(&global_map
, &key
);
85 g
.bad_cb_test_rv
= bad_call_rv
;
86 g
.good_cb_test_rv
= good_call_rv
;
87 bpf_map_update_elem(&global_map
, &key
, &g
,
91 case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB
:
92 skops
->sk_txhash
= 0x12345f;
94 rv
= bpf_setsockopt(skops
, SOL_IPV6
, IPV6_TCLASS
, &v
,
96 if (skops
->family
== AF_INET6
) {
97 v
= bpf_getsockopt(skops
, IPPROTO_TCP
, TCP_SAVED_SYN
,
98 header
, (sizeof(struct ipv6hdr
) +
99 sizeof(struct tcphdr
)));
101 int offset
= sizeof(struct ipv6hdr
);
103 thdr
= (struct tcphdr
*)(header
+ offset
);
107 bpf_map_update_elem(&sockopt_results
, &key
, &v
,
112 case BPF_SOCK_OPS_RTO_CB
:
114 case BPF_SOCK_OPS_RETRANS_CB
:
116 case BPF_SOCK_OPS_STATE_CB
:
117 if (skops
->args
[1] == BPF_TCP_CLOSE
) {
119 struct tcpbpf_globals g
, *gp
;
121 gp
= bpf_map_lookup_elem(&global_map
, &key
);
125 if (skops
->args
[0] == BPF_TCP_LISTEN
) {
128 g
.total_retrans
= skops
->total_retrans
;
129 g
.data_segs_in
= skops
->data_segs_in
;
130 g
.data_segs_out
= skops
->data_segs_out
;
131 g
.bytes_received
= skops
->bytes_received
;
132 g
.bytes_acked
= skops
->bytes_acked
;
134 bpf_map_update_elem(&global_map
, &key
, &g
,
138 case BPF_SOCK_OPS_TCP_LISTEN_CB
:
139 bpf_sock_ops_cb_flags_set(skops
, BPF_SOCK_OPS_STATE_CB_FLAG
);
140 v
= bpf_setsockopt(skops
, IPPROTO_TCP
, TCP_SAVE_SYN
,
141 &save_syn
, sizeof(save_syn
));
142 /* Update global map w/ result of setsock opt */
145 bpf_map_update_elem(&sockopt_results
, &key
, &v
, BPF_ANY
);
153 char _license
[] SEC("license") = "GPL";