162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef __NET_TC_CT_H 362306a36Sopenharmony_ci#define __NET_TC_CT_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <net/act_api.h> 662306a36Sopenharmony_ci#include <uapi/linux/tc_act/tc_ct.h> 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NF_CONNTRACK) 962306a36Sopenharmony_ci#include <net/netfilter/nf_nat.h> 1062306a36Sopenharmony_ci#include <net/netfilter/nf_conntrack_labels.h> 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_cistruct tcf_ct_params { 1362306a36Sopenharmony_ci struct nf_conntrack_helper *helper; 1462306a36Sopenharmony_ci struct nf_conn *tmpl; 1562306a36Sopenharmony_ci u16 zone; 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci u32 mark; 1862306a36Sopenharmony_ci u32 mark_mask; 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci u32 labels[NF_CT_LABELS_MAX_SIZE / sizeof(u32)]; 2162306a36Sopenharmony_ci u32 labels_mask[NF_CT_LABELS_MAX_SIZE / sizeof(u32)]; 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci struct nf_nat_range2 range; 2462306a36Sopenharmony_ci bool ipv4_range; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci u16 ct_action; 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci struct rcu_head rcu; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci struct tcf_ct_flow_table *ct_ft; 3162306a36Sopenharmony_ci struct nf_flowtable *nf_ft; 3262306a36Sopenharmony_ci}; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cistruct tcf_ct { 3562306a36Sopenharmony_ci struct tc_action common; 3662306a36Sopenharmony_ci struct tcf_ct_params __rcu *params; 3762306a36Sopenharmony_ci}; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci#define to_ct(a) ((struct tcf_ct *)a) 4062306a36Sopenharmony_ci#define to_ct_params(a) \ 4162306a36Sopenharmony_ci ((struct tcf_ct_params *) \ 4262306a36Sopenharmony_ci rcu_dereference_protected(to_ct(a)->params, \ 4362306a36Sopenharmony_ci lockdep_is_held(&a->tcfa_lock))) 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistatic inline uint16_t tcf_ct_zone(const struct tc_action *a) 4662306a36Sopenharmony_ci{ 4762306a36Sopenharmony_ci return to_ct_params(a)->zone; 4862306a36Sopenharmony_ci} 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_cistatic inline int tcf_ct_action(const struct tc_action *a) 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci return to_ct_params(a)->ct_action; 5362306a36Sopenharmony_ci} 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_cistatic inline struct nf_flowtable *tcf_ct_ft(const struct tc_action *a) 5662306a36Sopenharmony_ci{ 5762306a36Sopenharmony_ci return to_ct_params(a)->nf_ft; 5862306a36Sopenharmony_ci} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic inline struct nf_conntrack_helper *tcf_ct_helper(const struct tc_action *a) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci return to_ct_params(a)->helper; 6362306a36Sopenharmony_ci} 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci#else 6662306a36Sopenharmony_cistatic inline uint16_t tcf_ct_zone(const struct tc_action *a) { return 0; } 6762306a36Sopenharmony_cistatic inline int tcf_ct_action(const struct tc_action *a) { return 0; } 6862306a36Sopenharmony_cistatic inline struct nf_flowtable *tcf_ct_ft(const struct tc_action *a) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci return NULL; 7162306a36Sopenharmony_ci} 7262306a36Sopenharmony_cistatic inline struct nf_conntrack_helper *tcf_ct_helper(const struct tc_action *a) 7362306a36Sopenharmony_ci{ 7462306a36Sopenharmony_ci return NULL; 7562306a36Sopenharmony_ci} 7662306a36Sopenharmony_ci#endif /* CONFIG_NF_CONNTRACK */ 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_NET_ACT_CT) 7962306a36Sopenharmony_cistatic inline void 8062306a36Sopenharmony_citcf_ct_flow_table_restore_skb(struct sk_buff *skb, unsigned long cookie) 8162306a36Sopenharmony_ci{ 8262306a36Sopenharmony_ci enum ip_conntrack_info ctinfo = cookie & NFCT_INFOMASK; 8362306a36Sopenharmony_ci struct nf_conn *ct; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci ct = (struct nf_conn *)(cookie & NFCT_PTRMASK); 8662306a36Sopenharmony_ci nf_conntrack_get(&ct->ct_general); 8762306a36Sopenharmony_ci nf_ct_set(skb, ct, ctinfo); 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci#else 9062306a36Sopenharmony_cistatic inline void 9162306a36Sopenharmony_citcf_ct_flow_table_restore_skb(struct sk_buff *skb, unsigned long cookie) { } 9262306a36Sopenharmony_ci#endif 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_cistatic inline bool is_tcf_ct(const struct tc_action *a) 9562306a36Sopenharmony_ci{ 9662306a36Sopenharmony_ci#if defined(CONFIG_NET_CLS_ACT) && IS_ENABLED(CONFIG_NF_CONNTRACK) 9762306a36Sopenharmony_ci if (a->ops && a->ops->id == TCA_ID_CT) 9862306a36Sopenharmony_ci return true; 9962306a36Sopenharmony_ci#endif 10062306a36Sopenharmony_ci return false; 10162306a36Sopenharmony_ci} 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci#endif /* __NET_TC_CT_H */ 104