File Index
Files and directories
Sign in
FILE

act_tunnel_key.c

File preview with syntax highlighting.

linux-6.19.14/net/sched/act_tunnel_key.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * Copyright (c) 2016, Amir Vadai <amir@vadai.me>
  4 * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
  5 */
  6
  7#include <linux/module.h>
  8#include <linux/init.h>
  9#include <linux/kernel.h>
 10#include <linux/skbuff.h>
 11#include <linux/rtnetlink.h>
 12#include <net/geneve.h>
 13#include <net/vxlan.h>
 14#include <net/erspan.h>
 15#include <net/netlink.h>
 16#include <net/pkt_sched.h>
 17#include <net/dst.h>
 18#include <net/pkt_cls.h>
 19#include <net/tc_wrapper.h>
 20
 21#include <linux/tc_act/tc_tunnel_key.h>
 22#include <net/tc_act/tc_tunnel_key.h>
 23
 24static struct tc_action_ops act_tunnel_key_ops;
 25
 26TC_INDIRECT_SCOPE int tunnel_key_act(struct sk_buff *skb,
 27				     const struct tc_action *a,
 28				     struct tcf_result *res)
 29{
 30	struct tcf_tunnel_key *t = to_tunnel_key(a);
 31	struct tcf_tunnel_key_params *params;
 32
 33	params = rcu_dereference_bh(t->params);
 34
 35	tcf_lastuse_update(&t->tcf_tm);
 36	tcf_action_update_bstats(&t->common, skb);
 37
 38	switch (params->tcft_action) {
 39	case TCA_TUNNEL_KEY_ACT_RELEASE:
 40		skb_dst_drop(skb);
 41		break;
 42	case TCA_TUNNEL_KEY_ACT_SET:
 43		skb_dst_drop(skb);
 44		skb_dst_set(skb, dst_clone(&params->tcft_enc_metadata->dst));
 45		break;
 46	default:
 47		WARN_ONCE(1, "Bad tunnel_key action %d.\n",
 48			  params->tcft_action);
 49		break;
 50	}
 51
 52	return params->action;
 53}
 54
 55static const struct nla_policy
 56enc_opts_policy[TCA_TUNNEL_KEY_ENC_OPTS_MAX + 1] = {
 57	[TCA_TUNNEL_KEY_ENC_OPTS_UNSPEC]	= {
 58		.strict_start_type = TCA_TUNNEL_KEY_ENC_OPTS_VXLAN },
 59	[TCA_TUNNEL_KEY_ENC_OPTS_GENEVE]	= { .type = NLA_NESTED },
 60	[TCA_TUNNEL_KEY_ENC_OPTS_VXLAN]		= { .type = NLA_NESTED },
 61	[TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN]	= { .type = NLA_NESTED },
 62};
 63
 64static const struct nla_policy
 65geneve_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1] = {
 66	[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS]	   = { .type = NLA_U16 },
 67	[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE]	   = { .type = NLA_U8 },
 68	[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]	   = { .type = NLA_BINARY,
 69						       .len = 127 },
 70};
 71
 72static const struct nla_policy
 73vxlan_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX + 1] = {
 74	[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP]	   = { .type = NLA_U32 },
 75};
 76
 77static const struct nla_policy
 78erspan_opt_policy[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX + 1] = {
 79	[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER]	   = { .type = NLA_U8 },
 80	[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX]	   = { .type = NLA_U32 },
 81	[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR]	   = { .type = NLA_U8 },
 82	[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID]	   = { .type = NLA_U8 },
 83};
 84
 85static int
 86tunnel_key_copy_geneve_opt(const struct nlattr *nla, void *dst, int dst_len,
 87			   struct netlink_ext_ack *extack)
 88{
 89	struct nlattr *tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX + 1];
 90	int err, data_len, opt_len;
 91	u8 *data;
 92
 93	err = nla_parse_nested_deprecated(tb,
 94					  TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX,
 95					  nla, geneve_opt_policy, extack);
 96	if (err < 0)
 97		return err;
 98
 99	if (!tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS] ||
100	    !tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE] ||
101	    !tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]) {
102		NL_SET_ERR_MSG(extack, "Missing tunnel key geneve option class, type or data");
103		return -EINVAL;
104	}
105
106	data = nla_data(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]);
107	data_len = nla_len(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA]);
108	if (data_len < 4) {
109		NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is less than 4 bytes long");
110		return -ERANGE;
111	}
112	if (data_len % 4) {
113		NL_SET_ERR_MSG(extack, "Tunnel key geneve option data is not a multiple of 4 bytes long");
114		return -ERANGE;
115	}
116
117	opt_len = sizeof(struct geneve_opt) + data_len;
118	if (dst) {
119		struct geneve_opt *opt = dst;
120
121		WARN_ON(dst_len < opt_len);
122
123		opt->opt_class =
124			nla_get_be16(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS]);
125		opt->type = nla_get_u8(tb[TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE]);
126		opt->length = data_len / 4; /* length is in units of 4 bytes */
127		opt->r1 = 0;
128		opt->r2 = 0;
129		opt->r3 = 0;
130
131		memcpy(opt + 1, data, data_len);
132	}
133
134	return opt_len;
135}
136
137static int
138tunnel_key_copy_vxlan_opt(const struct nlattr *nla, void *dst, int dst_len,
139			  struct netlink_ext_ack *extack)
140{
141	struct nlattr *tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX + 1];
142	int err;
143
144	err = nla_parse_nested(tb, TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX, nla,
145			       vxlan_opt_policy, extack);
146	if (err < 0)
147		return err;
148
149	if (!tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP]) {
150		NL_SET_ERR_MSG(extack, "Missing tunnel key vxlan option gbp");
151		return -EINVAL;
152	}
153
154	if (dst) {
155		struct vxlan_metadata *md = dst;
156
157		md->gbp = nla_get_u32(tb[TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP]);
158		md->gbp &= VXLAN_GBP_MASK;
159	}
160
161	return sizeof(struct vxlan_metadata);
162}
163
164static int
165tunnel_key_copy_erspan_opt(const struct nlattr *nla, void *dst, int dst_len,
166			   struct netlink_ext_ack *extack)
167{
168	struct nlattr *tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX + 1];
169	int err;
170	u8 ver;
171
172	err = nla_parse_nested(tb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_MAX, nla,
173			       erspan_opt_policy, extack);
174	if (err < 0)
175		return err;
176
177	if (!tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER]) {
178		NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option ver");
179		return -EINVAL;
180	}
181
182	ver = nla_get_u8(tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER]);
183	if (ver == 1) {
184		if (!tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX]) {
185			NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option index");
186			return -EINVAL;
187		}
188	} else if (ver == 2) {
189		if (!tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR] ||
190		    !tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID]) {
191			NL_SET_ERR_MSG(extack, "Missing tunnel key erspan option dir or hwid");
192			return -EINVAL;
193		}
194	} else {
195		NL_SET_ERR_MSG(extack, "Tunnel key erspan option ver is incorrect");
196		return -EINVAL;
197	}
198
199	if (dst) {
200		struct erspan_metadata *md = dst;
201
202		md->version = ver;
203		if (ver == 1) {
204			nla = tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX];
205			md->u.index = nla_get_be32(nla);
206		} else {
207			nla = tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR];
208			md->u.md2.dir = nla_get_u8(nla);
209			nla = tb[TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID];
210			set_hwid(&md->u.md2, nla_get_u8(nla));
211		}
212	}
213
214	return sizeof(struct erspan_metadata);
215}
216
217static int tunnel_key_copy_opts(const struct nlattr *nla, u8 *dst,
218				int dst_len, struct netlink_ext_ack *extack)
219{
220	int err, rem, opt_len, len = nla_len(nla), opts_len = 0, type = 0;
221	const struct nlattr *attr, *head = nla_data(nla);
222
223	err = nla_validate_deprecated(head, len, TCA_TUNNEL_KEY_ENC_OPTS_MAX,
224				      enc_opts_policy, extack);
225	if (err)
226		return err;
227
228	nla_for_each_attr(attr, head, len, rem) {
229		switch (nla_type(attr)) {
230		case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE:
231			if (type && type != IP_TUNNEL_GENEVE_OPT_BIT) {
232				NL_SET_ERR_MSG(extack, "Duplicate type for geneve options");
233				return -EINVAL;
234			}
235			opt_len = tunnel_key_copy_geneve_opt(attr, dst,
236							     dst_len, extack);
237			if (opt_len < 0)
238				return opt_len;
239			opts_len += opt_len;
240			if (opts_len > IP_TUNNEL_OPTS_MAX) {
241				NL_SET_ERR_MSG(extack, "Tunnel options exceeds max size");
242				return -EINVAL;
243			}
244			if (dst) {
245				dst_len -= opt_len;
246				dst += opt_len;
247			}
248			type = IP_TUNNEL_GENEVE_OPT_BIT;
249			break;
250		case TCA_TUNNEL_KEY_ENC_OPTS_VXLAN:
251			if (type) {
252				NL_SET_ERR_MSG(extack, "Duplicate type for vxlan options");
253				return -EINVAL;
254			}
255			opt_len = tunnel_key_copy_vxlan_opt(attr, dst,
256							    dst_len, extack);
257			if (opt_len < 0)
258				return opt_len;
259			opts_len += opt_len;
260			type = IP_TUNNEL_VXLAN_OPT_BIT;
261			break;
262		case TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN:
263			if (type) {
264				NL_SET_ERR_MSG(extack, "Duplicate type for erspan options");
265				return -EINVAL;
266			}
267			opt_len = tunnel_key_copy_erspan_opt(attr, dst,
268							     dst_len, extack);
269			if (opt_len < 0)
270				return opt_len;
271			opts_len += opt_len;
272			type = IP_TUNNEL_ERSPAN_OPT_BIT;
273			break;
274		}
275	}
276
277	if (!opts_len) {
278		NL_SET_ERR_MSG(extack, "Empty list of tunnel options");
279		return -EINVAL;
280	}
281
282	if (rem > 0) {
283		NL_SET_ERR_MSG(extack, "Trailing data after parsing tunnel key options attributes");
284		return -EINVAL;
285	}
286
287	return opts_len;
288}
289
290static int tunnel_key_get_opts_len(struct nlattr *nla,
291				   struct netlink_ext_ack *extack)
292{
293	return tunnel_key_copy_opts(nla, NULL, 0, extack);
294}
295
296static int tunnel_key_opts_set(struct nlattr *nla, struct ip_tunnel_info *info,
297			       int opts_len, struct netlink_ext_ack *extack)
298{
299	info->options_len = opts_len;
300	switch (nla_type(nla_data(nla))) {
301	case TCA_TUNNEL_KEY_ENC_OPTS_GENEVE:
302#if IS_ENABLED(CONFIG_INET)
303		__set_bit(IP_TUNNEL_GENEVE_OPT_BIT, info->key.tun_flags);
304		return tunnel_key_copy_opts(nla, ip_tunnel_info_opts(info),
305					    opts_len, extack);
306#else
307		return -EAFNOSUPPORT;
308#endif
309	case TCA_TUNNEL_KEY_ENC_OPTS_VXLAN:
310#if IS_ENABLED(CONFIG_INET)
311		__set_bit(IP_TUNNEL_VXLAN_OPT_BIT, info->key.tun_flags);
312		return tunnel_key_copy_opts(nla, ip_tunnel_info_opts(info),
313					    opts_len, extack);
314#else
315		return -EAFNOSUPPORT;
316#endif
317	case TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN:
318#if IS_ENABLED(CONFIG_INET)
319		__set_bit(IP_TUNNEL_ERSPAN_OPT_BIT, info->key.tun_flags);
320		return tunnel_key_copy_opts(nla, ip_tunnel_info_opts(info),
321					    opts_len, extack);
322#else
323		return -EAFNOSUPPORT;
324#endif
325	default:
326		NL_SET_ERR_MSG(extack, "Cannot set tunnel options for unknown tunnel type");
327		return -EINVAL;
328	}
329}
330
331static const struct nla_policy tunnel_key_policy[TCA_TUNNEL_KEY_MAX + 1] = {
332	[TCA_TUNNEL_KEY_PARMS]	    = { .len = sizeof(struct tc_tunnel_key) },
333	[TCA_TUNNEL_KEY_ENC_IPV4_SRC] = { .type = NLA_U32 },
334	[TCA_TUNNEL_KEY_ENC_IPV4_DST] = { .type = NLA_U32 },
335	[TCA_TUNNEL_KEY_ENC_IPV6_SRC] = { .len = sizeof(struct in6_addr) },
336	[TCA_TUNNEL_KEY_ENC_IPV6_DST] = { .len = sizeof(struct in6_addr) },
337	[TCA_TUNNEL_KEY_ENC_KEY_ID]   = { .type = NLA_U32 },
338	[TCA_TUNNEL_KEY_ENC_DST_PORT] = {.type = NLA_U16},
339	[TCA_TUNNEL_KEY_NO_CSUM]      = { .type = NLA_U8 },
340	[TCA_TUNNEL_KEY_ENC_OPTS]     = { .type = NLA_NESTED },
341	[TCA_TUNNEL_KEY_ENC_TOS]      = { .type = NLA_U8 },
342	[TCA_TUNNEL_KEY_ENC_TTL]      = { .type = NLA_U8 },
343};
344
345static void tunnel_key_release_params(struct tcf_tunnel_key_params *p)
346{
347	if (!p)
348		return;
349	if (p->tcft_action == TCA_TUNNEL_KEY_ACT_SET)
350		dst_release(&p->tcft_enc_metadata->dst);
351
352	kfree_rcu(p, rcu);
353}
354
355static int tunnel_key_init(struct net *net, struct nlattr *nla,
356			   struct nlattr *est, struct tc_action **a,
357			   struct tcf_proto *tp, u32 act_flags,
358			   struct netlink_ext_ack *extack)
359{
360	struct tc_action_net *tn = net_generic(net, act_tunnel_key_ops.net_id);
361	bool bind = act_flags & TCA_ACT_FLAGS_BIND;
362	struct nlattr *tb[TCA_TUNNEL_KEY_MAX + 1];
363	struct tcf_tunnel_key_params *params_new;
364	IP_TUNNEL_DECLARE_FLAGS(flags) = { };
365	struct metadata_dst *metadata = NULL;
366	struct tcf_chain *goto_ch = NULL;
367	struct tc_tunnel_key *parm;
368	struct tcf_tunnel_key *t;
369	bool exists = false;
370	__be16 dst_port = 0;
371	__be64 key_id = 0;
372	int opts_len = 0;
373	u8 tos, ttl;
374	int ret = 0;
375	u32 index;
376	int err;
377
378	if (!nla) {
379		NL_SET_ERR_MSG(extack, "Tunnel requires attributes to be passed");
380		return -EINVAL;
381	}
382
383	err = nla_parse_nested_deprecated(tb, TCA_TUNNEL_KEY_MAX, nla,
384					  tunnel_key_policy, extack);
385	if (err < 0) {
386		NL_SET_ERR_MSG(extack, "Failed to parse nested tunnel key attributes");
387		return err;
388	}
389
390	if (!tb[TCA_TUNNEL_KEY_PARMS]) {
391		NL_SET_ERR_MSG(extack, "Missing tunnel key parameters");
392		return -EINVAL;
393	}
394
395	parm = nla_data(tb[TCA_TUNNEL_KEY_PARMS]);
396	index = parm->index;
397	err = tcf_idr_check_alloc(tn, &index, a, bind);
398	if (err < 0)
399		return err;
400	exists = err;
401	if (exists && bind)
402		return ACT_P_BOUND;
403
404	switch (parm->t_action) {
405	case TCA_TUNNEL_KEY_ACT_RELEASE:
406		break;
407	case TCA_TUNNEL_KEY_ACT_SET:
408		if (tb[TCA_TUNNEL_KEY_ENC_KEY_ID]) {
409			__be32 key32;
410
411			key32 = nla_get_be32(tb[TCA_TUNNEL_KEY_ENC_KEY_ID]);
412			key_id = key32_to_tunnel_id(key32);
413			__set_bit(IP_TUNNEL_KEY_BIT, flags);
414		}
415
416		__set_bit(IP_TUNNEL_CSUM_BIT, flags);
417		if (tb[TCA_TUNNEL_KEY_NO_CSUM] &&
418		    nla_get_u8(tb[TCA_TUNNEL_KEY_NO_CSUM]))
419			__clear_bit(IP_TUNNEL_CSUM_BIT, flags);
420
421		if (nla_get_flag(tb[TCA_TUNNEL_KEY_NO_FRAG]))
422			__set_bit(IP_TUNNEL_DONT_FRAGMENT_BIT, flags);
423
424		if (tb[TCA_TUNNEL_KEY_ENC_DST_PORT])
425			dst_port = nla_get_be16(tb[TCA_TUNNEL_KEY_ENC_DST_PORT]);
426
427		if (tb[TCA_TUNNEL_KEY_ENC_OPTS]) {
428			opts_len = tunnel_key_get_opts_len(tb[TCA_TUNNEL_KEY_ENC_OPTS],
429							   extack);
430			if (opts_len < 0) {
431				ret = opts_len;
432				goto err_out;
433			}
434		}
435
436		tos = 0;
437		if (tb[TCA_TUNNEL_KEY_ENC_TOS])
438			tos = nla_get_u8(tb[TCA_TUNNEL_KEY_ENC_TOS]);
439		ttl = 0;
440		if (tb[TCA_TUNNEL_KEY_ENC_TTL])
441			ttl = nla_get_u8(tb[TCA_TUNNEL_KEY_ENC_TTL]);
442
443		if (tb[TCA_TUNNEL_KEY_ENC_IPV4_SRC] &&
444		    tb[TCA_TUNNEL_KEY_ENC_IPV4_DST]) {
445			__be32 saddr;
446			__be32 daddr;
447
448			saddr = nla_get_in_addr(tb[TCA_TUNNEL_KEY_ENC_IPV4_SRC]);
449			daddr = nla_get_in_addr(tb[TCA_TUNNEL_KEY_ENC_IPV4_DST]);
450
451			metadata = __ip_tun_set_dst(saddr, daddr, tos, ttl,
452						    dst_port, flags,
453						    key_id, opts_len);
454		} else if (tb[TCA_TUNNEL_KEY_ENC_IPV6_SRC] &&
455			   tb[TCA_TUNNEL_KEY_ENC_IPV6_DST]) {
456			struct in6_addr saddr;
457			struct in6_addr daddr;
458
459			saddr = nla_get_in6_addr(tb[TCA_TUNNEL_KEY_ENC_IPV6_SRC]);
460			daddr = nla_get_in6_addr(tb[TCA_TUNNEL_KEY_ENC_IPV6_DST]);
461
462			metadata = __ipv6_tun_set_dst(&saddr, &daddr, tos, ttl, dst_port,
463						      0, flags,
464						      key_id, opts_len);
465		} else {
466			NL_SET_ERR_MSG(extack, "Missing either ipv4 or ipv6 src and dst");
467			ret = -EINVAL;
468			goto err_out;
469		}
470
471		if (!metadata) {
472			NL_SET_ERR_MSG(extack, "Cannot allocate tunnel metadata dst");
473			ret = -ENOMEM;
474			goto err_out;
475		}
476
477#ifdef CONFIG_DST_CACHE
478		ret = dst_cache_init(&metadata->u.tun_info.dst_cache, GFP_KERNEL);
479		if (ret)
480			goto release_tun_meta;
481#endif
482
483		if (opts_len) {
484			ret = tunnel_key_opts_set(tb[TCA_TUNNEL_KEY_ENC_OPTS],
485						  &metadata->u.tun_info,
486						  opts_len, extack);
487			if (ret < 0)
488				goto release_tun_meta;
489		}
490
491		metadata->u.tun_info.mode |= IP_TUNNEL_INFO_TX;
492		break;
493	default:
494		NL_SET_ERR_MSG(extack, "Unknown tunnel key action");
495		ret = -EINVAL;
496		goto err_out;
497	}
498
499	if (!exists) {
500		ret = tcf_idr_create_from_flags(tn, index, est, a,
501						&act_tunnel_key_ops, bind,
502						act_flags);
503		if (ret) {
504			NL_SET_ERR_MSG(extack, "Cannot create TC IDR");
505			goto release_tun_meta;
506		}
507
508		ret = ACT_P_CREATED;
509	} else if (!(act_flags & TCA_ACT_FLAGS_REPLACE)) {
510		NL_SET_ERR_MSG(extack, "TC IDR already exists");
511		ret = -EEXIST;
512		goto release_tun_meta;
513	}
514
515	err = tcf_action_check_ctrlact(parm->action, tp, &goto_ch, extack);
516	if (err < 0) {
517		ret = err;
518		exists = true;
519		goto release_tun_meta;
520	}
521	t = to_tunnel_key(*a);
522
523	params_new = kzalloc(sizeof(*params_new), GFP_KERNEL);
524	if (unlikely(!params_new)) {
525		NL_SET_ERR_MSG(extack, "Cannot allocate tunnel key parameters");
526		ret = -ENOMEM;
527		exists = true;
528		goto put_chain;
529	}
530	params_new->tcft_action = parm->t_action;
531	params_new->tcft_enc_metadata = metadata;
532
533	params_new->action = parm->action;
534	spin_lock_bh(&t->tcf_lock);
535	goto_ch = tcf_action_set_ctrlact(*a, parm->action, goto_ch);
536	params_new = rcu_replace_pointer(t->params, params_new,
537					 lockdep_is_held(&t->tcf_lock));
538	spin_unlock_bh(&t->tcf_lock);
539	tunnel_key_release_params(params_new);
540	if (goto_ch)
541		tcf_chain_put_by_act(goto_ch);
542
543	return ret;
544
545put_chain:
546	if (goto_ch)
547		tcf_chain_put_by_act(goto_ch);
548
549release_tun_meta:
550	if (metadata)
551		dst_release(&metadata->dst);
552
553err_out:
554	if (exists)
555		tcf_idr_release(*a, bind);
556	else
557		tcf_idr_cleanup(tn, index);
558	return ret;
559}
560
561static void tunnel_key_release(struct tc_action *a)
562{
563	struct tcf_tunnel_key *t = to_tunnel_key(a);
564	struct tcf_tunnel_key_params *params;
565
566	params = rcu_dereference_protected(t->params, 1);
567	tunnel_key_release_params(params);
568}
569
570static int tunnel_key_geneve_opts_dump(struct sk_buff *skb,
571				       const struct ip_tunnel_info *info)
572{
573	const u8 *src = ip_tunnel_info_opts(info);
574	int len = info->options_len;
575	struct nlattr *start;
576
577	start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_GENEVE);
578	if (!start)
579		return -EMSGSIZE;
580
581	while (len > 0) {
582		const struct geneve_opt *opt = (const struct geneve_opt *)src;
583
584		if (nla_put_be16(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_CLASS,
585				 opt->opt_class) ||
586		    nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_TYPE,
587			       opt->type) ||
588		    nla_put(skb, TCA_TUNNEL_KEY_ENC_OPT_GENEVE_DATA,
589			    opt->length * 4, opt + 1)) {
590			nla_nest_cancel(skb, start);
591			return -EMSGSIZE;
592		}
593
594		len -= sizeof(struct geneve_opt) + opt->length * 4;
595		src += sizeof(struct geneve_opt) + opt->length * 4;
596	}
597
598	nla_nest_end(skb, start);
599	return 0;
600}
601
602static int tunnel_key_vxlan_opts_dump(struct sk_buff *skb,
603				      const struct ip_tunnel_info *info)
604{
605	const struct vxlan_metadata *md = ip_tunnel_info_opts(info);
606	struct nlattr *start;
607
608	start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_VXLAN);
609	if (!start)
610		return -EMSGSIZE;
611
612	if (nla_put_u32(skb, TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP, md->gbp)) {
613		nla_nest_cancel(skb, start);
614		return -EMSGSIZE;
615	}
616
617	nla_nest_end(skb, start);
618	return 0;
619}
620
621static int tunnel_key_erspan_opts_dump(struct sk_buff *skb,
622				       const struct ip_tunnel_info *info)
623{
624	const struct erspan_metadata *md = ip_tunnel_info_opts(info);
625	struct nlattr *start;
626
627	start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS_ERSPAN);
628	if (!start)
629		return -EMSGSIZE;
630
631	if (nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_VER, md->version))
632		goto err;
633
634	if (md->version == 1 &&
635	    nla_put_be32(skb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_INDEX, md->u.index))
636		goto err;
637
638	if (md->version == 2 &&
639	    (nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_DIR,
640			md->u.md2.dir) ||
641	     nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_OPT_ERSPAN_HWID,
642			get_hwid(&md->u.md2))))
643		goto err;
644
645	nla_nest_end(skb, start);
646	return 0;
647err:
648	nla_nest_cancel(skb, start);
649	return -EMSGSIZE;
650}
651
652static int tunnel_key_opts_dump(struct sk_buff *skb,
653				const struct ip_tunnel_info *info)
654{
655	struct nlattr *start;
656	int err = -EINVAL;
657
658	if (!info->options_len)
659		return 0;
660
661	start = nla_nest_start_noflag(skb, TCA_TUNNEL_KEY_ENC_OPTS);
662	if (!start)
663		return -EMSGSIZE;
664
665	if (test_bit(IP_TUNNEL_GENEVE_OPT_BIT, info->key.tun_flags)) {
666		err = tunnel_key_geneve_opts_dump(skb, info);
667		if (err)
668			goto err_out;
669	} else if (test_bit(IP_TUNNEL_VXLAN_OPT_BIT, info->key.tun_flags)) {
670		err = tunnel_key_vxlan_opts_dump(skb, info);
671		if (err)
672			goto err_out;
673	} else if (test_bit(IP_TUNNEL_ERSPAN_OPT_BIT, info->key.tun_flags)) {
674		err = tunnel_key_erspan_opts_dump(skb, info);
675		if (err)
676			goto err_out;
677	} else {
678err_out:
679		nla_nest_cancel(skb, start);
680		return err;
681	}
682
683	nla_nest_end(skb, start);
684	return 0;
685}
686
687static int tunnel_key_dump_addresses(struct sk_buff *skb,
688				     const struct ip_tunnel_info *info)
689{
690	unsigned short family = ip_tunnel_info_af(info);
691
692	if (family == AF_INET) {
693		__be32 saddr = info->key.u.ipv4.src;
694		__be32 daddr = info->key.u.ipv4.dst;
695
696		if (!nla_put_in_addr(skb, TCA_TUNNEL_KEY_ENC_IPV4_SRC, saddr) &&
697		    !nla_put_in_addr(skb, TCA_TUNNEL_KEY_ENC_IPV4_DST, daddr))
698			return 0;
699	}
700
701	if (family == AF_INET6) {
702		const struct in6_addr *saddr6 = &info->key.u.ipv6.src;
703		const struct in6_addr *daddr6 = &info->key.u.ipv6.dst;
704
705		if (!nla_put_in6_addr(skb,
706				      TCA_TUNNEL_KEY_ENC_IPV6_SRC, saddr6) &&
707		    !nla_put_in6_addr(skb,
708				      TCA_TUNNEL_KEY_ENC_IPV6_DST, daddr6))
709			return 0;
710	}
711
712	return -EINVAL;
713}
714
715static int tunnel_key_dump(struct sk_buff *skb, struct tc_action *a,
716			   int bind, int ref)
717{
718	unsigned char *b = skb_tail_pointer(skb);
719	struct tcf_tunnel_key *t = to_tunnel_key(a);
720	struct tcf_tunnel_key_params *params;
721	struct tc_tunnel_key opt = {
722		.index    = t->tcf_index,
723		.refcnt   = refcount_read(&t->tcf_refcnt) - ref,
724		.bindcnt  = atomic_read(&t->tcf_bindcnt) - bind,
725	};
726	struct tcf_t tm;
727
728	rcu_read_lock();
729	params = rcu_dereference(t->params);
730	opt.action   = params->action;
731	opt.t_action = params->tcft_action;
732
733	if (nla_put(skb, TCA_TUNNEL_KEY_PARMS, sizeof(opt), &opt))
734		goto nla_put_failure;
735
736	if (params->tcft_action == TCA_TUNNEL_KEY_ACT_SET) {
737		struct ip_tunnel_info *info =
738			&params->tcft_enc_metadata->u.tun_info;
739		struct ip_tunnel_key *key = &info->key;
740		__be32 key_id = tunnel_id_to_key32(key->tun_id);
741
742		if ((test_bit(IP_TUNNEL_KEY_BIT, key->tun_flags) &&
743		     nla_put_be32(skb, TCA_TUNNEL_KEY_ENC_KEY_ID, key_id)) ||
744		    tunnel_key_dump_addresses(skb,
745					      &params->tcft_enc_metadata->u.tun_info) ||
746		    (key->tp_dst &&
747		      nla_put_be16(skb, TCA_TUNNEL_KEY_ENC_DST_PORT,
748				   key->tp_dst)) ||
749		    nla_put_u8(skb, TCA_TUNNEL_KEY_NO_CSUM,
750			       !test_bit(IP_TUNNEL_CSUM_BIT, key->tun_flags)) ||
751		    (test_bit(IP_TUNNEL_DONT_FRAGMENT_BIT, key->tun_flags) &&
752		     nla_put_flag(skb, TCA_TUNNEL_KEY_NO_FRAG)) ||
753		    tunnel_key_opts_dump(skb, info))
754			goto nla_put_failure;
755
756		if (key->tos && nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_TOS, key->tos))
757			goto nla_put_failure;
758
759		if (key->ttl && nla_put_u8(skb, TCA_TUNNEL_KEY_ENC_TTL, key->ttl))
760			goto nla_put_failure;
761	}
762
763	tcf_tm_dump(&tm, &t->tcf_tm);
764	if (nla_put_64bit(skb, TCA_TUNNEL_KEY_TM, sizeof(tm),
765			  &tm, TCA_TUNNEL_KEY_PAD))
766		goto nla_put_failure;
767	rcu_read_unlock();
768
769	return skb->len;
770
771nla_put_failure:
772	rcu_read_unlock();
773	nlmsg_trim(skb, b);
774	return -1;
775}
776
777static void tcf_tunnel_encap_put_tunnel(void *priv)
778{
779	struct ip_tunnel_info *tunnel = priv;
780
781	kfree(tunnel);
782}
783
784static int tcf_tunnel_encap_get_tunnel(struct flow_action_entry *entry,
785				       const struct tc_action *act)
786{
787	entry->tunnel = tcf_tunnel_info_copy(act);
788	if (!entry->tunnel)
789		return -ENOMEM;
790	entry->destructor = tcf_tunnel_encap_put_tunnel;
791	entry->destructor_priv = entry->tunnel;
792	return 0;
793}
794
795static int tcf_tunnel_key_offload_act_setup(struct tc_action *act,
796					    void *entry_data,
797					    u32 *index_inc,
798					    bool bind,
799					    struct netlink_ext_ack *extack)
800{
801	int err;
802
803	if (bind) {
804		struct flow_action_entry *entry = entry_data;
805
806		if (is_tcf_tunnel_set(act)) {
807			entry->id = FLOW_ACTION_TUNNEL_ENCAP;
808			err = tcf_tunnel_encap_get_tunnel(entry, act);
809			if (err)
810				return err;
811		} else if (is_tcf_tunnel_release(act)) {
812			entry->id = FLOW_ACTION_TUNNEL_DECAP;
813		} else {
814			NL_SET_ERR_MSG_MOD(extack, "Unsupported tunnel key mode offload");
815			return -EOPNOTSUPP;
816		}
817		*index_inc = 1;
818	} else {
819		struct flow_offload_action *fl_action = entry_data;
820
821		if (is_tcf_tunnel_set(act))
822			fl_action->id = FLOW_ACTION_TUNNEL_ENCAP;
823		else if (is_tcf_tunnel_release(act))
824			fl_action->id = FLOW_ACTION_TUNNEL_DECAP;
825		else
826			return -EOPNOTSUPP;
827	}
828
829	return 0;
830}
831
832static struct tc_action_ops act_tunnel_key_ops = {
833	.kind		=	"tunnel_key",
834	.id		=	TCA_ID_TUNNEL_KEY,
835	.owner		=	THIS_MODULE,
836	.act		=	tunnel_key_act,
837	.dump		=	tunnel_key_dump,
838	.init		=	tunnel_key_init,
839	.cleanup	=	tunnel_key_release,
840	.offload_act_setup =	tcf_tunnel_key_offload_act_setup,
841	.size		=	sizeof(struct tcf_tunnel_key),
842};
843MODULE_ALIAS_NET_ACT("tunnel_key");
844
845static __net_init int tunnel_key_init_net(struct net *net)
846{
847	struct tc_action_net *tn = net_generic(net, act_tunnel_key_ops.net_id);
848
849	return tc_action_net_init(net, tn, &act_tunnel_key_ops);
850}
851
852static void __net_exit tunnel_key_exit_net(struct list_head *net_list)
853{
854	tc_action_net_exit(net_list, act_tunnel_key_ops.net_id);
855}
856
857static struct pernet_operations tunnel_key_net_ops = {
858	.init = tunnel_key_init_net,
859	.exit_batch = tunnel_key_exit_net,
860	.id   = &act_tunnel_key_ops.net_id,
861	.size = sizeof(struct tc_action_net),
862};
863
864static int __init tunnel_key_init_module(void)
865{
866	return tcf_register_action(&act_tunnel_key_ops, &tunnel_key_net_ops);
867}
868
869static void __exit tunnel_key_cleanup_module(void)
870{
871	tcf_unregister_action(&act_tunnel_key_ops, &tunnel_key_net_ops);
872}
873
874module_init(tunnel_key_init_module);
875module_exit(tunnel_key_cleanup_module);
876
877MODULE_AUTHOR("Amir Vadai <amir@vadai.me>");
878MODULE_DESCRIPTION("ip tunnel manipulation actions");
879MODULE_LICENSE("GPL v2");
~/ Read-only file preview.