13
13
#include <linux/kernel.h>
14
14
#include <linux/skbuff.h>
15
15
#include <linux/rtnetlink.h>
16
+ #include <net/geneve.h>
16
17
#include <net/netlink.h>
17
18
#include <net/pkt_sched.h>
18
19
#include <net/dst.h>
@@ -57,6 +58,135 @@ static int tunnel_key_act(struct sk_buff *skb, const struct tc_action *a,
57
58
return action ;
58
59
}
59
60
61
+ static const struct nla_policy
62
+ enc_opts_policy [TCA_TUNNEL_KEY_ENC_OPTS_MAX + 1 ] = {
63
+ [TCA_TUNNEL_KEY_ENC_OPTS_GENEVE ] = { .type = NLA_NESTED },
64
+ };
65
+
66
+ static const struct nla_policy
67
+ geneve_opt_policy [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1 ] = {
68
+ [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS ] = { .type = NLA_U16 },
69
+ [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE ] = { .type = NLA_U8 },
70
+ [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA ] = { .type = NLA_BINARY ,
71
+ .len = 128 },
72
+ };
73
+
74
+ static int
75
+ tunnel_key_copy_geneve_opt (const struct nlattr * nla , void * dst , int dst_len ,
76
+ struct netlink_ext_ack * extack )
77
+ {
78
+ struct nlattr * tb [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1 ];
79
+ int err , data_len , opt_len ;
80
+ u8 * data ;
81
+
82
+ err = nla_parse_nested (tb , TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX ,
83
+ nla , geneve_opt_policy , extack );
84
+ if (err < 0 )
85
+ return err ;
86
+
87
+ if (!tb [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS ] ||
88
+ !tb [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE ] ||
89
+ !tb [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA ]) {
90
+ NL_SET_ERR_MSG (extack , "Missing tunnel key geneve option class, type or data" );
91
+ return - EINVAL ;
92
+ }
93
+
94
+ data = nla_data (tb [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA ]);
95
+ data_len = nla_len (tb [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA ]);
96
+ if (data_len < 4 ) {
97
+ NL_SET_ERR_MSG (extack , "Tunnel key geneve option data is less than 4 bytes long" );
98
+ return - ERANGE ;
99
+ }
100
+ if (data_len % 4 ) {
101
+ NL_SET_ERR_MSG (extack , "Tunnel key geneve option data is not a multiple of 4 bytes long" );
102
+ return - ERANGE ;
103
+ }
104
+
105
+ opt_len = sizeof (struct geneve_opt ) + data_len ;
106
+ if (dst ) {
107
+ struct geneve_opt * opt = dst ;
108
+
109
+ WARN_ON (dst_len < opt_len );
110
+
111
+ opt -> opt_class =
112
+ nla_get_be16 (tb [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS ]);
113
+ opt -> type = nla_get_u8 (tb [TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE ]);
114
+ opt -> length = data_len / 4 ; /* length is in units of 4 bytes */
115
+ opt -> r1 = 0 ;
116
+ opt -> r2 = 0 ;
117
+ opt -> r3 = 0 ;
118
+
119
+ memcpy (opt + 1 , data , data_len );
120
+ }
121
+
122
+ return opt_len ;
123
+ }
124
+
125
+ static int tunnel_key_copy_opts (const struct nlattr * nla , u8 * dst ,
126
+ int dst_len , struct netlink_ext_ack * extack )
127
+ {
128
+ int err , rem , opt_len , len = nla_len (nla ), opts_len = 0 ;
129
+ const struct nlattr * attr , * head = nla_data (nla );
130
+
131
+ err = nla_validate (head , len , TCA_TUNNEL_KEY_ENC_OPTS_MAX ,
132
+ enc_opts_policy , extack );
133
+ if (err )
134
+ return err ;
135
+
136
+ nla_for_each_attr (attr , head , len , rem ) {
137
+ switch (nla_type (attr )) {
138
+ case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE :
139
+ opt_len = tunnel_key_copy_geneve_opt (attr , dst ,
140
+ dst_len , extack );
141
+ if (opt_len < 0 )
142
+ return opt_len ;
143
+ opts_len += opt_len ;
144
+ if (dst ) {
145
+ dst_len -= opt_len ;
146
+ dst += opt_len ;
147
+ }
148
+ break ;
149
+ }
150
+ }
151
+
152
+ if (!opts_len ) {
153
+ NL_SET_ERR_MSG (extack , "Empty list of tunnel options" );
154
+ return - EINVAL ;
155
+ }
156
+
157
+ if (rem > 0 ) {
158
+ NL_SET_ERR_MSG (extack , "Trailing data after parsing tunnel key options attributes" );
159
+ return - EINVAL ;
160
+ }
161
+
162
+ return opts_len ;
163
+ }
164
+
165
+ static int tunnel_key_get_opts_len (struct nlattr * nla ,
166
+ struct netlink_ext_ack * extack )
167
+ {
168
+ return tunnel_key_copy_opts (nla , NULL , 0 , extack );
169
+ }
170
+
171
+ static int tunnel_key_opts_set (struct nlattr * nla , struct ip_tunnel_info * info ,
172
+ int opts_len , struct netlink_ext_ack * extack )
173
+ {
174
+ info -> options_len = opts_len ;
175
+ switch (nla_type (nla_data (nla ))) {
176
+ case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE :
177
+ #if IS_ENABLED (CONFIG_INET )
178
+ info -> key .tun_flags |= TUNNEL_GENEVE_OPT ;
179
+ return tunnel_key_copy_opts (nla , ip_tunnel_info_opts (info ),
180
+ opts_len , extack );
181
+ #else
182
+ return - EAFNOSUPPORT ;
183
+ #endif
184
+ default :
185
+ NL_SET_ERR_MSG (extack , "Cannot set tunnel options for unknown tunnel type" );
186
+ return - EINVAL ;
187
+ }
188
+ }
189
+
60
190
static const struct nla_policy tunnel_key_policy [TCA_TUNNEL_KEY_MAX + 1 ] = {
61
191
[TCA_TUNNEL_KEY_PARMS ] = { .len = sizeof (struct tc_tunnel_key ) },
62
192
[TCA_TUNNEL_KEY_ENC_IPV4_SRC ] = { .type = NLA_U32 },
@@ -66,6 +196,7 @@ static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
66
196
[TCA_TUNNEL_KEY_ENC_KEY_ID ] = { .type = NLA_U32 },
67
197
[TCA_TUNNEL_KEY_ENC_DST_PORT ] = {.type = NLA_U16 },
68
198
[TCA_TUNNEL_KEY_NO_CSUM ] = { .type = NLA_U8 },
199
+ [TCA_TUNNEL_KEY_ENC_OPTS ] = { .type = NLA_NESTED },
69
200
};
70
201
71
202
static int tunnel_key_init (struct net * net , struct nlattr * nla ,
@@ -81,6 +212,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
81
212
struct tcf_tunnel_key * t ;
82
213
bool exists = false;
83
214
__be16 dst_port = 0 ;
215
+ int opts_len = 0 ;
84
216
__be64 key_id ;
85
217
__be16 flags ;
86
218
int ret = 0 ;
@@ -128,6 +260,15 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
128
260
if (tb [TCA_TUNNEL_KEY_ENC_DST_PORT ])
129
261
dst_port = nla_get_be16 (tb [TCA_TUNNEL_KEY_ENC_DST_PORT ]);
130
262
263
+ if (tb [TCA_TUNNEL_KEY_ENC_OPTS ]) {
264
+ opts_len = tunnel_key_get_opts_len (tb [TCA_TUNNEL_KEY_ENC_OPTS ],
265
+ extack );
266
+ if (opts_len < 0 ) {
267
+ ret = opts_len ;
268
+ goto err_out ;
269
+ }
270
+ }
271
+
131
272
if (tb [TCA_TUNNEL_KEY_ENC_IPV4_SRC ] &&
132
273
tb [TCA_TUNNEL_KEY_ENC_IPV4_DST ]) {
133
274
__be32 saddr ;
@@ -138,7 +279,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
138
279
139
280
metadata = __ip_tun_set_dst (saddr , daddr , 0 , 0 ,
140
281
dst_port , flags ,
141
- key_id , 0 );
282
+ key_id , opts_len );
142
283
} else if (tb [TCA_TUNNEL_KEY_ENC_IPV6_SRC ] &&
143
284
tb [TCA_TUNNEL_KEY_ENC_IPV6_DST ]) {
144
285
struct in6_addr saddr ;
@@ -162,6 +303,14 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
162
303
goto err_out ;
163
304
}
164
305
306
+ if (opts_len ) {
307
+ ret = tunnel_key_opts_set (tb [TCA_TUNNEL_KEY_ENC_OPTS ],
308
+ & metadata -> u .tun_info ,
309
+ opts_len , extack );
310
+ if (ret < 0 )
311
+ goto err_out ;
312
+ }
313
+
165
314
metadata -> u .tun_info .mode |= IP_TUNNEL_INFO_TX ;
166
315
break ;
167
316
default :
@@ -234,6 +383,61 @@ static void tunnel_key_release(struct tc_action *a)
234
383
}
235
384
}
236
385
386
+ static int tunnel_key_geneve_opts_dump (struct sk_buff * skb ,
387
+ const struct ip_tunnel_info * info )
388
+ {
389
+ int len = info -> options_len ;
390
+ u8 * src = (u8 * )(info + 1 );
391
+ struct nlattr * start ;
392
+
393
+ start = nla_nest_start (skb , TCA_TUNNEL_KEY_ENC_OPTS_GENEVE );
394
+ if (!start )
395
+ return - EMSGSIZE ;
396
+
397
+ while (len > 0 ) {
398
+ struct geneve_opt * opt = (struct geneve_opt * )src ;
399
+
400
+ if (nla_put_be16 (skb , TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS ,
401
+ opt -> opt_class ) ||
402
+ nla_put_u8 (skb , TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE ,
403
+ opt -> type ) ||
404
+ nla_put (skb , TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA ,
405
+ opt -> length * 4 , opt + 1 ))
406
+ return - EMSGSIZE ;
407
+
408
+ len -= sizeof (struct geneve_opt ) + opt -> length * 4 ;
409
+ src += sizeof (struct geneve_opt ) + opt -> length * 4 ;
410
+ }
411
+
412
+ nla_nest_end (skb , start );
413
+ return 0 ;
414
+ }
415
+
416
+ static int tunnel_key_opts_dump (struct sk_buff * skb ,
417
+ const struct ip_tunnel_info * info )
418
+ {
419
+ struct nlattr * start ;
420
+ int err ;
421
+
422
+ if (!info -> options_len )
423
+ return 0 ;
424
+
425
+ start = nla_nest_start (skb , TCA_TUNNEL_KEY_ENC_OPTS );
426
+ if (!start )
427
+ return - EMSGSIZE ;
428
+
429
+ if (info -> key .tun_flags & TUNNEL_GENEVE_OPT ) {
430
+ err = tunnel_key_geneve_opts_dump (skb , info );
431
+ if (err )
432
+ return err ;
433
+ } else {
434
+ return - EINVAL ;
435
+ }
436
+
437
+ nla_nest_end (skb , start );
438
+ return 0 ;
439
+ }
440
+
237
441
static int tunnel_key_dump_addresses (struct sk_buff * skb ,
238
442
const struct ip_tunnel_info * info )
239
443
{
@@ -284,16 +488,18 @@ static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
284
488
goto nla_put_failure ;
285
489
286
490
if (params -> tcft_action == TCA_TUNNEL_KEY_ACT_SET ) {
287
- struct ip_tunnel_key * key =
288
- & params -> tcft_enc_metadata -> u .tun_info .key ;
491
+ struct ip_tunnel_info * info =
492
+ & params -> tcft_enc_metadata -> u .tun_info ;
493
+ struct ip_tunnel_key * key = & info -> key ;
289
494
__be32 key_id = tunnel_id_to_key32 (key -> tun_id );
290
495
291
496
if (nla_put_be32 (skb , TCA_TUNNEL_KEY_ENC_KEY_ID , key_id ) ||
292
497
tunnel_key_dump_addresses (skb ,
293
498
& params -> tcft_enc_metadata -> u .tun_info ) ||
294
499
nla_put_be16 (skb , TCA_TUNNEL_KEY_ENC_DST_PORT , key -> tp_dst ) ||
295
500
nla_put_u8 (skb , TCA_TUNNEL_KEY_NO_CSUM ,
296
- !(key -> tun_flags & TUNNEL_CSUM )))
501
+ !(key -> tun_flags & TUNNEL_CSUM )) ||
502
+ tunnel_key_opts_dump (skb , info ))
297
503
goto nla_put_failure ;
298
504
}
299
505
0 commit comments