xref: /linux/include/net/tc_act/tc_tunnel_key.h (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
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 #ifndef __NET_TC_TUNNEL_KEY_H
8 #define __NET_TC_TUNNEL_KEY_H
9 
10 #include <net/act_api.h>
11 #include <linux/tc_act/tc_tunnel_key.h>
12 #include <net/dst_metadata.h>
13 
14 struct tcf_tunnel_key_params {
15 	struct rcu_head		rcu;
16 	int			tcft_action;
17 	int			action;
18 	struct metadata_dst     *tcft_enc_metadata;
19 };
20 
21 struct tcf_tunnel_key {
22 	struct tc_action	      common;
23 	struct tcf_tunnel_key_params __rcu *params;
24 };
25 
26 #define to_tunnel_key(a) ((struct tcf_tunnel_key *)a)
27 
28 static inline bool is_tcf_tunnel_set(const struct tc_action *a)
29 {
30 #ifdef CONFIG_NET_CLS_ACT
31 	struct tcf_tunnel_key *t = to_tunnel_key(a);
32 	struct tcf_tunnel_key_params *params;
33 
34 	params = rcu_dereference_protected(t->params,
35 					   lockdep_is_held(&a->tcfa_lock));
36 	if (a->ops && a->ops->id == TCA_ID_TUNNEL_KEY)
37 		return params->tcft_action == TCA_TUNNEL_KEY_ACT_SET;
38 #endif
39 	return false;
40 }
41 
42 static inline bool is_tcf_tunnel_release(const struct tc_action *a)
43 {
44 #ifdef CONFIG_NET_CLS_ACT
45 	struct tcf_tunnel_key *t = to_tunnel_key(a);
46 	struct tcf_tunnel_key_params *params;
47 
48 	params = rcu_dereference_protected(t->params,
49 					   lockdep_is_held(&a->tcfa_lock));
50 	if (a->ops && a->ops->id == TCA_ID_TUNNEL_KEY)
51 		return params->tcft_action == TCA_TUNNEL_KEY_ACT_RELEASE;
52 #endif
53 	return false;
54 }
55 
56 static inline struct ip_tunnel_info *tcf_tunnel_info(const struct tc_action *a)
57 {
58 #ifdef CONFIG_NET_CLS_ACT
59 	struct tcf_tunnel_key *t = to_tunnel_key(a);
60 	struct tcf_tunnel_key_params *params;
61 
62 	params = rcu_dereference_protected(t->params,
63 					   lockdep_is_held(&a->tcfa_lock));
64 
65 	return &params->tcft_enc_metadata->u.tun_info;
66 #else
67 	return NULL;
68 #endif
69 }
70 
71 static inline struct ip_tunnel_info *
72 tcf_tunnel_info_copy(const struct tc_action *a)
73 {
74 #ifdef CONFIG_NET_CLS_ACT
75 	struct ip_tunnel_info *tun = tcf_tunnel_info(a);
76 
77 	if (tun) {
78 		size_t tun_size = sizeof(*tun) + tun->options_len;
79 		struct ip_tunnel_info *tun_copy = kmemdup(tun, tun_size,
80 							  GFP_ATOMIC);
81 
82 		return tun_copy;
83 	}
84 #endif
85 	return NULL;
86 }
87 #endif /* __NET_TC_TUNNEL_KEY_H */
88