1313#include <linux/kernel.h>
1414#include <linux/skbuff.h>
1515#include <linux/rtnetlink.h>
16+ #include <net/geneve.h>
1617#include <net/netlink.h>
1718#include <net/pkt_sched.h>
1819#include <net/dst.h>
@@ -57,6 +58,135 @@ static int tunnel_key_act(struct sk_buff *skb, const struct tc_action *a,
5758 return action ;
5859}
5960
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+
60190static const struct nla_policy tunnel_key_policy [TCA_TUNNEL_KEY_MAX + 1 ] = {
61191 [TCA_TUNNEL_KEY_PARMS ] = { .len = sizeof (struct tc_tunnel_key ) },
62192 [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] = {
66196 [TCA_TUNNEL_KEY_ENC_KEY_ID ] = { .type = NLA_U32 },
67197 [TCA_TUNNEL_KEY_ENC_DST_PORT ] = {.type = NLA_U16 },
68198 [TCA_TUNNEL_KEY_NO_CSUM ] = { .type = NLA_U8 },
199+ [TCA_TUNNEL_KEY_ENC_OPTS ] = { .type = NLA_NESTED },
69200};
70201
71202static 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,
81212 struct tcf_tunnel_key * t ;
82213 bool exists = false;
83214 __be16 dst_port = 0 ;
215+ int opts_len = 0 ;
84216 __be64 key_id ;
85217 __be16 flags ;
86218 int ret = 0 ;
@@ -128,6 +260,15 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
128260 if (tb [TCA_TUNNEL_KEY_ENC_DST_PORT ])
129261 dst_port = nla_get_be16 (tb [TCA_TUNNEL_KEY_ENC_DST_PORT ]);
130262
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+
131272 if (tb [TCA_TUNNEL_KEY_ENC_IPV4_SRC ] &&
132273 tb [TCA_TUNNEL_KEY_ENC_IPV4_DST ]) {
133274 __be32 saddr ;
@@ -138,7 +279,7 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
138279
139280 metadata = __ip_tun_set_dst (saddr , daddr , 0 , 0 ,
140281 dst_port , flags ,
141- key_id , 0 );
282+ key_id , opts_len );
142283 } else if (tb [TCA_TUNNEL_KEY_ENC_IPV6_SRC ] &&
143284 tb [TCA_TUNNEL_KEY_ENC_IPV6_DST ]) {
144285 struct in6_addr saddr ;
@@ -162,6 +303,14 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla,
162303 goto err_out ;
163304 }
164305
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+
165314 metadata -> u .tun_info .mode |= IP_TUNNEL_INFO_TX ;
166315 break ;
167316 default :
@@ -234,6 +383,61 @@ static void tunnel_key_release(struct tc_action *a)
234383 }
235384}
236385
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+
237441static int tunnel_key_dump_addresses (struct sk_buff * skb ,
238442 const struct ip_tunnel_info * info )
239443{
@@ -284,16 +488,18 @@ static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
284488 goto nla_put_failure ;
285489
286490 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 ;
289494 __be32 key_id = tunnel_id_to_key32 (key -> tun_id );
290495
291496 if (nla_put_be32 (skb , TCA_TUNNEL_KEY_ENC_KEY_ID , key_id ) ||
292497 tunnel_key_dump_addresses (skb ,
293498 & params -> tcft_enc_metadata -> u .tun_info ) ||
294499 nla_put_be16 (skb , TCA_TUNNEL_KEY_ENC_DST_PORT , key -> tp_dst ) ||
295500 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 ))
297503 goto nla_put_failure ;
298504 }
299505
0 commit comments