xref: /linux/include/net/tc_act/tc_tunnel_key.h (revision cbecf716ca618fd44feda6bd9a64a8179d031fc5)
12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
2d0f6dd8aSAmir Vadai /*
3d0f6dd8aSAmir Vadai  * Copyright (c) 2016, Amir Vadai <amir@vadai.me>
4d0f6dd8aSAmir Vadai  * Copyright (c) 2016, Mellanox Technologies. All rights reserved.
5d0f6dd8aSAmir Vadai  */
6d0f6dd8aSAmir Vadai 
7d0f6dd8aSAmir Vadai #ifndef __NET_TC_TUNNEL_KEY_H
8d0f6dd8aSAmir Vadai #define __NET_TC_TUNNEL_KEY_H
9d0f6dd8aSAmir Vadai 
10d0f6dd8aSAmir Vadai #include <net/act_api.h>
119ce183b4SHadar Hen Zion #include <linux/tc_act/tc_tunnel_key.h>
129ce183b4SHadar Hen Zion #include <net/dst_metadata.h>
13d0f6dd8aSAmir Vadai 
14d0f6dd8aSAmir Vadai struct tcf_tunnel_key_params {
15d0f6dd8aSAmir Vadai 	struct rcu_head		rcu;
16d0f6dd8aSAmir Vadai 	int			tcft_action;
17d0f6dd8aSAmir Vadai 	struct metadata_dst     *tcft_enc_metadata;
18d0f6dd8aSAmir Vadai };
19d0f6dd8aSAmir Vadai 
20d0f6dd8aSAmir Vadai struct tcf_tunnel_key {
21d0f6dd8aSAmir Vadai 	struct tc_action	      common;
22d0f6dd8aSAmir Vadai 	struct tcf_tunnel_key_params __rcu *params;
23d0f6dd8aSAmir Vadai };
24d0f6dd8aSAmir Vadai 
25d0f6dd8aSAmir Vadai #define to_tunnel_key(a) ((struct tcf_tunnel_key *)a)
26d0f6dd8aSAmir Vadai 
is_tcf_tunnel_set(const struct tc_action * a)279ce183b4SHadar Hen Zion static inline bool is_tcf_tunnel_set(const struct tc_action *a)
289ce183b4SHadar Hen Zion {
299ce183b4SHadar Hen Zion #ifdef CONFIG_NET_CLS_ACT
309ce183b4SHadar Hen Zion 	struct tcf_tunnel_key *t = to_tunnel_key(a);
313ebaf6daSIdo Schimmel 	struct tcf_tunnel_key_params *params;
329ce183b4SHadar Hen Zion 
333ebaf6daSIdo Schimmel 	params = rcu_dereference_protected(t->params,
343ebaf6daSIdo Schimmel 					   lockdep_is_held(&a->tcfa_lock));
35eddd2cf1SEli Cohen 	if (a->ops && a->ops->id == TCA_ID_TUNNEL_KEY)
369ce183b4SHadar Hen Zion 		return params->tcft_action == TCA_TUNNEL_KEY_ACT_SET;
379ce183b4SHadar Hen Zion #endif
389ce183b4SHadar Hen Zion 	return false;
399ce183b4SHadar Hen Zion }
409ce183b4SHadar Hen Zion 
is_tcf_tunnel_release(const struct tc_action * a)419ce183b4SHadar Hen Zion static inline bool is_tcf_tunnel_release(const struct tc_action *a)
429ce183b4SHadar Hen Zion {
439ce183b4SHadar Hen Zion #ifdef CONFIG_NET_CLS_ACT
449ce183b4SHadar Hen Zion 	struct tcf_tunnel_key *t = to_tunnel_key(a);
453ebaf6daSIdo Schimmel 	struct tcf_tunnel_key_params *params;
469ce183b4SHadar Hen Zion 
473ebaf6daSIdo Schimmel 	params = rcu_dereference_protected(t->params,
483ebaf6daSIdo Schimmel 					   lockdep_is_held(&a->tcfa_lock));
49eddd2cf1SEli Cohen 	if (a->ops && a->ops->id == TCA_ID_TUNNEL_KEY)
509ce183b4SHadar Hen Zion 		return params->tcft_action == TCA_TUNNEL_KEY_ACT_RELEASE;
519ce183b4SHadar Hen Zion #endif
529ce183b4SHadar Hen Zion 	return false;
539ce183b4SHadar Hen Zion }
549ce183b4SHadar Hen Zion 
tcf_tunnel_info(const struct tc_action * a)559ce183b4SHadar Hen Zion static inline struct ip_tunnel_info *tcf_tunnel_info(const struct tc_action *a)
569ce183b4SHadar Hen Zion {
579ce183b4SHadar Hen Zion #ifdef CONFIG_NET_CLS_ACT
589ce183b4SHadar Hen Zion 	struct tcf_tunnel_key *t = to_tunnel_key(a);
59*d086a1c6SLeon Romanovsky 	struct tcf_tunnel_key_params *params;
60*d086a1c6SLeon Romanovsky 
61*d086a1c6SLeon Romanovsky 	params = rcu_dereference_protected(t->params,
62*d086a1c6SLeon Romanovsky 					   lockdep_is_held(&a->tcfa_lock));
639ce183b4SHadar Hen Zion 
649ce183b4SHadar Hen Zion 	return &params->tcft_enc_metadata->u.tun_info;
659ce183b4SHadar Hen Zion #else
669ce183b4SHadar Hen Zion 	return NULL;
679ce183b4SHadar Hen Zion #endif
689ce183b4SHadar Hen Zion }
691444c175SVlad Buslov 
701444c175SVlad Buslov static inline struct ip_tunnel_info *
tcf_tunnel_info_copy(const struct tc_action * a)711444c175SVlad Buslov tcf_tunnel_info_copy(const struct tc_action *a)
721444c175SVlad Buslov {
731444c175SVlad Buslov #ifdef CONFIG_NET_CLS_ACT
741444c175SVlad Buslov 	struct ip_tunnel_info *tun = tcf_tunnel_info(a);
751444c175SVlad Buslov 
761444c175SVlad Buslov 	if (tun) {
771444c175SVlad Buslov 		size_t tun_size = sizeof(*tun) + tun->options_len;
781444c175SVlad Buslov 		struct ip_tunnel_info *tun_copy = kmemdup(tun, tun_size,
797a472814SVlad Buslov 							  GFP_ATOMIC);
801444c175SVlad Buslov 
811444c175SVlad Buslov 		return tun_copy;
821444c175SVlad Buslov 	}
831444c175SVlad Buslov #endif
841444c175SVlad Buslov 	return NULL;
851444c175SVlad Buslov }
86d0f6dd8aSAmir Vadai #endif /* __NET_TC_TUNNEL_KEY_H */
87