8
8
#define EINVAL 22
9
9
#define ENOENT 2
10
10
11
+ extern unsigned long CONFIG_HZ __kconfig ;
12
+
11
13
int test_einval_bpf_tuple = 0 ;
12
14
int test_einval_reserved = 0 ;
13
15
int test_einval_netns_id = 0 ;
@@ -16,6 +18,11 @@ int test_eproto_l4proto = 0;
16
18
int test_enonet_netns_id = 0 ;
17
19
int test_enoent_lookup = 0 ;
18
20
int test_eafnosupport = 0 ;
21
+ int test_alloc_entry = - EINVAL ;
22
+ int test_insert_entry = - EAFNOSUPPORT ;
23
+ int test_succ_lookup = - ENOENT ;
24
+ u32 test_delta_timeout = 0 ;
25
+ u32 test_status = 0 ;
19
26
20
27
struct nf_conn ;
21
28
@@ -26,31 +33,44 @@ struct bpf_ct_opts___local {
26
33
u8 reserved [3 ];
27
34
} __attribute__((preserve_access_index ));
28
35
36
+ struct nf_conn * bpf_xdp_ct_alloc (struct xdp_md * , struct bpf_sock_tuple * , u32 ,
37
+ struct bpf_ct_opts___local * , u32 ) __ksym ;
29
38
struct nf_conn * bpf_xdp_ct_lookup (struct xdp_md * , struct bpf_sock_tuple * , u32 ,
30
39
struct bpf_ct_opts___local * , u32 ) __ksym ;
40
+ struct nf_conn * bpf_skb_ct_alloc (struct __sk_buff * , struct bpf_sock_tuple * , u32 ,
41
+ struct bpf_ct_opts___local * , u32 ) __ksym ;
31
42
struct nf_conn * bpf_skb_ct_lookup (struct __sk_buff * , struct bpf_sock_tuple * , u32 ,
32
43
struct bpf_ct_opts___local * , u32 ) __ksym ;
44
+ struct nf_conn * bpf_ct_insert_entry (struct nf_conn * ) __ksym ;
33
45
void bpf_ct_release (struct nf_conn * ) __ksym ;
46
+ void bpf_ct_set_timeout (struct nf_conn * , u32 ) __ksym ;
47
+ int bpf_ct_change_timeout (struct nf_conn * , u32 ) __ksym ;
48
+ int bpf_ct_set_status (struct nf_conn * , u32 ) __ksym ;
49
+ int bpf_ct_change_status (struct nf_conn * , u32 ) __ksym ;
34
50
35
51
static __always_inline void
36
- nf_ct_test (struct nf_conn * (* func )(void * , struct bpf_sock_tuple * , u32 ,
37
- struct bpf_ct_opts___local * , u32 ),
52
+ nf_ct_test (struct nf_conn * (* lookup_fn )(void * , struct bpf_sock_tuple * , u32 ,
53
+ struct bpf_ct_opts___local * , u32 ),
54
+ struct nf_conn * (* alloc_fn )(void * , struct bpf_sock_tuple * , u32 ,
55
+ struct bpf_ct_opts___local * , u32 ),
38
56
void * ctx )
39
57
{
40
58
struct bpf_ct_opts___local opts_def = { .l4proto = IPPROTO_TCP , .netns_id = -1 };
41
59
struct bpf_sock_tuple bpf_tuple ;
42
60
struct nf_conn * ct ;
61
+ int err ;
43
62
44
63
__builtin_memset (& bpf_tuple , 0 , sizeof (bpf_tuple .ipv4 ));
45
64
46
- ct = func (ctx , NULL , 0 , & opts_def , sizeof (opts_def ));
65
+ ct = lookup_fn (ctx , NULL , 0 , & opts_def , sizeof (opts_def ));
47
66
if (ct )
48
67
bpf_ct_release (ct );
49
68
else
50
69
test_einval_bpf_tuple = opts_def .error ;
51
70
52
71
opts_def .reserved [0 ] = 1 ;
53
- ct = func (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ), & opts_def , sizeof (opts_def ));
72
+ ct = lookup_fn (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ), & opts_def ,
73
+ sizeof (opts_def ));
54
74
opts_def .reserved [0 ] = 0 ;
55
75
opts_def .l4proto = IPPROTO_TCP ;
56
76
if (ct )
@@ -59,59 +79,100 @@ nf_ct_test(struct nf_conn *(*func)(void *, struct bpf_sock_tuple *, u32,
59
79
test_einval_reserved = opts_def .error ;
60
80
61
81
opts_def .netns_id = -2 ;
62
- ct = func (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ), & opts_def , sizeof (opts_def ));
82
+ ct = lookup_fn (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ), & opts_def ,
83
+ sizeof (opts_def ));
63
84
opts_def .netns_id = -1 ;
64
85
if (ct )
65
86
bpf_ct_release (ct );
66
87
else
67
88
test_einval_netns_id = opts_def .error ;
68
89
69
- ct = func (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ), & opts_def , sizeof (opts_def ) - 1 );
90
+ ct = lookup_fn (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ), & opts_def ,
91
+ sizeof (opts_def ) - 1 );
70
92
if (ct )
71
93
bpf_ct_release (ct );
72
94
else
73
95
test_einval_len_opts = opts_def .error ;
74
96
75
97
opts_def .l4proto = IPPROTO_ICMP ;
76
- ct = func (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ), & opts_def , sizeof (opts_def ));
98
+ ct = lookup_fn (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ), & opts_def ,
99
+ sizeof (opts_def ));
77
100
opts_def .l4proto = IPPROTO_TCP ;
78
101
if (ct )
79
102
bpf_ct_release (ct );
80
103
else
81
104
test_eproto_l4proto = opts_def .error ;
82
105
83
106
opts_def .netns_id = 0xf00f ;
84
- ct = func (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ), & opts_def , sizeof (opts_def ));
107
+ ct = lookup_fn (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ), & opts_def ,
108
+ sizeof (opts_def ));
85
109
opts_def .netns_id = -1 ;
86
110
if (ct )
87
111
bpf_ct_release (ct );
88
112
else
89
113
test_enonet_netns_id = opts_def .error ;
90
114
91
- ct = func (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ), & opts_def , sizeof (opts_def ));
115
+ ct = lookup_fn (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ), & opts_def ,
116
+ sizeof (opts_def ));
92
117
if (ct )
93
118
bpf_ct_release (ct );
94
119
else
95
120
test_enoent_lookup = opts_def .error ;
96
121
97
- ct = func (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ) - 1 , & opts_def , sizeof (opts_def ));
122
+ ct = lookup_fn (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ) - 1 , & opts_def ,
123
+ sizeof (opts_def ));
98
124
if (ct )
99
125
bpf_ct_release (ct );
100
126
else
101
127
test_eafnosupport = opts_def .error ;
128
+
129
+ bpf_tuple .ipv4 .saddr = bpf_get_prandom_u32 (); /* src IP */
130
+ bpf_tuple .ipv4 .daddr = bpf_get_prandom_u32 (); /* dst IP */
131
+ bpf_tuple .ipv4 .sport = bpf_get_prandom_u32 (); /* src port */
132
+ bpf_tuple .ipv4 .dport = bpf_get_prandom_u32 (); /* dst port */
133
+
134
+ ct = alloc_fn (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ), & opts_def ,
135
+ sizeof (opts_def ));
136
+ if (ct ) {
137
+ struct nf_conn * ct_ins ;
138
+
139
+ bpf_ct_set_timeout (ct , 10000 );
140
+ bpf_ct_set_status (ct , IPS_CONFIRMED );
141
+
142
+ ct_ins = bpf_ct_insert_entry (ct );
143
+ if (ct_ins ) {
144
+ struct nf_conn * ct_lk ;
145
+
146
+ ct_lk = lookup_fn (ctx , & bpf_tuple , sizeof (bpf_tuple .ipv4 ),
147
+ & opts_def , sizeof (opts_def ));
148
+ if (ct_lk ) {
149
+ /* update ct entry timeout */
150
+ bpf_ct_change_timeout (ct_lk , 10000 );
151
+ test_delta_timeout = ct_lk -> timeout - bpf_jiffies64 ();
152
+ test_delta_timeout /= CONFIG_HZ ;
153
+ test_status = IPS_SEEN_REPLY ;
154
+ bpf_ct_change_status (ct_lk , IPS_SEEN_REPLY );
155
+ bpf_ct_release (ct_lk );
156
+ test_succ_lookup = 0 ;
157
+ }
158
+ bpf_ct_release (ct_ins );
159
+ test_insert_entry = 0 ;
160
+ }
161
+ test_alloc_entry = 0 ;
162
+ }
102
163
}
103
164
104
165
SEC ("xdp" )
105
166
int nf_xdp_ct_test (struct xdp_md * ctx )
106
167
{
107
- nf_ct_test ((void * )bpf_xdp_ct_lookup , ctx );
168
+ nf_ct_test ((void * )bpf_xdp_ct_lookup , ( void * ) bpf_xdp_ct_alloc , ctx );
108
169
return 0 ;
109
170
}
110
171
111
172
SEC ("tc" )
112
173
int nf_skb_ct_test (struct __sk_buff * ctx )
113
174
{
114
- nf_ct_test ((void * )bpf_skb_ct_lookup , ctx );
175
+ nf_ct_test ((void * )bpf_skb_ct_lookup , ( void * ) bpf_skb_ct_alloc , ctx );
115
176
return 0 ;
116
177
}
117
178
0 commit comments