0001
0002 #ifndef __NET_TC_CT_H
0003 #define __NET_TC_CT_H
0004
0005 #include <net/act_api.h>
0006 #include <uapi/linux/tc_act/tc_ct.h>
0007
0008 #if IS_ENABLED(CONFIG_NF_CONNTRACK)
0009 #include <net/netfilter/nf_nat.h>
0010 #include <net/netfilter/nf_conntrack_labels.h>
0011
0012 struct tcf_ct_params {
0013 struct nf_conn *tmpl;
0014 u16 zone;
0015
0016 u32 mark;
0017 u32 mark_mask;
0018
0019 u32 labels[NF_CT_LABELS_MAX_SIZE / sizeof(u32)];
0020 u32 labels_mask[NF_CT_LABELS_MAX_SIZE / sizeof(u32)];
0021
0022 struct nf_nat_range2 range;
0023 bool ipv4_range;
0024
0025 u16 ct_action;
0026
0027 struct rcu_head rcu;
0028
0029 struct tcf_ct_flow_table *ct_ft;
0030 struct nf_flowtable *nf_ft;
0031 };
0032
0033 struct tcf_ct {
0034 struct tc_action common;
0035 struct tcf_ct_params __rcu *params;
0036 };
0037
0038 #define to_ct(a) ((struct tcf_ct *)a)
0039 #define to_ct_params(a) \
0040 ((struct tcf_ct_params *) \
0041 rcu_dereference_protected(to_ct(a)->params, \
0042 lockdep_is_held(&a->tcfa_lock)))
0043
0044 static inline uint16_t tcf_ct_zone(const struct tc_action *a)
0045 {
0046 return to_ct_params(a)->zone;
0047 }
0048
0049 static inline int tcf_ct_action(const struct tc_action *a)
0050 {
0051 return to_ct_params(a)->ct_action;
0052 }
0053
0054 static inline struct nf_flowtable *tcf_ct_ft(const struct tc_action *a)
0055 {
0056 return to_ct_params(a)->nf_ft;
0057 }
0058
0059 #else
0060 static inline uint16_t tcf_ct_zone(const struct tc_action *a) { return 0; }
0061 static inline int tcf_ct_action(const struct tc_action *a) { return 0; }
0062 static inline struct nf_flowtable *tcf_ct_ft(const struct tc_action *a)
0063 {
0064 return NULL;
0065 }
0066 #endif
0067
0068 #if IS_ENABLED(CONFIG_NET_ACT_CT)
0069 static inline void
0070 tcf_ct_flow_table_restore_skb(struct sk_buff *skb, unsigned long cookie)
0071 {
0072 enum ip_conntrack_info ctinfo = cookie & NFCT_INFOMASK;
0073 struct nf_conn *ct;
0074
0075 ct = (struct nf_conn *)(cookie & NFCT_PTRMASK);
0076 nf_conntrack_get(&ct->ct_general);
0077 nf_ct_set(skb, ct, ctinfo);
0078 }
0079 #else
0080 static inline void
0081 tcf_ct_flow_table_restore_skb(struct sk_buff *skb, unsigned long cookie) { }
0082 #endif
0083
0084 static inline bool is_tcf_ct(const struct tc_action *a)
0085 {
0086 #if defined(CONFIG_NET_CLS_ACT) && IS_ENABLED(CONFIG_NF_CONNTRACK)
0087 if (a->ops && a->ops->id == TCA_ID_CT)
0088 return true;
0089 #endif
0090 return false;
0091 }
0092
0093 #endif