#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/pkt_cls.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <linux/rhashtable.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
#include <net/pkt_cls.h>
#include <net/act_api.h>
#include <net/ip.h>
#include <net/ipv6_frag.h>
#include <uapi/linux/tc_act/tc_ct.h>
#include <net/tc_act/tc_ct.h>
#include <net/tc_wrapper.h>
#include <net/netfilter/nf_flow_table.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_zones.h>
#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_acct.h>
#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
#include <net/netfilter/nf_conntrack_act_ct.h>
#include <net/netfilter/nf_conntrack_seqadj.h>
#include <uapi/linux/netfilter/nf_nat.h>
static struct workqueue_struct *act_ct_wq;
static struct rhashtable zones_ht;
static DEFINE_MUTEX(zones_mutex);
struct zones_ht_key { … };
struct tcf_ct_flow_table { … };
static const struct rhashtable_params zones_params = …;
static struct flow_action_entry *
tcf_ct_flow_table_flow_action_get_next(struct flow_action *flow_action)
{ … }
static void tcf_ct_add_mangle_action(struct flow_action *action,
enum flow_action_mangle_base htype,
u32 offset,
u32 mask,
u32 val)
{ … }
static void
tcf_ct_flow_table_add_action_nat_ipv4(const struct nf_conntrack_tuple *tuple,
struct nf_conntrack_tuple target,
struct flow_action *action)
{ … }
static void
tcf_ct_add_ipv6_addr_mangle_action(struct flow_action *action,
union nf_inet_addr *addr,
u32 offset)
{ … }
static void
tcf_ct_flow_table_add_action_nat_ipv6(const struct nf_conntrack_tuple *tuple,
struct nf_conntrack_tuple target,
struct flow_action *action)
{ … }
static void
tcf_ct_flow_table_add_action_nat_tcp(const struct nf_conntrack_tuple *tuple,
struct nf_conntrack_tuple target,
struct flow_action *action)
{ … }
static void
tcf_ct_flow_table_add_action_nat_udp(const struct nf_conntrack_tuple *tuple,
struct nf_conntrack_tuple target,
struct flow_action *action)
{ … }
static void tcf_ct_flow_table_add_action_meta(struct nf_conn *ct,
enum ip_conntrack_dir dir,
enum ip_conntrack_info ctinfo,
struct flow_action *action)
{ … }
static int tcf_ct_flow_table_add_action_nat(struct net *net,
struct nf_conn *ct,
enum ip_conntrack_dir dir,
struct flow_action *action)
{ … }
static int tcf_ct_flow_table_fill_actions(struct net *net,
struct flow_offload *flow,
enum flow_offload_tuple_dir tdir,
struct nf_flow_rule *flow_rule)
{ … }
static bool tcf_ct_flow_is_outdated(const struct flow_offload *flow)
{ … }
static void tcf_ct_flow_table_get_ref(struct tcf_ct_flow_table *ct_ft);
static void tcf_ct_nf_get(struct nf_flowtable *ft)
{ … }
static void tcf_ct_flow_table_put(struct tcf_ct_flow_table *ct_ft);
static void tcf_ct_nf_put(struct nf_flowtable *ft)
{ … }
static struct nf_flowtable_type flowtable_ct = …;
static int tcf_ct_flow_table_get(struct net *net, struct tcf_ct_params *params)
{ … }
static void tcf_ct_flow_table_get_ref(struct tcf_ct_flow_table *ct_ft)
{ … }
static void tcf_ct_flow_table_cleanup_work(struct work_struct *work)
{ … }
static void tcf_ct_flow_table_put(struct tcf_ct_flow_table *ct_ft)
{ … }
static void tcf_ct_flow_tc_ifidx(struct flow_offload *entry,
struct nf_conn_act_ct_ext *act_ct_ext, u8 dir)
{ … }
static void tcf_ct_flow_ct_ext_ifidx_update(struct flow_offload *entry)
{ … }
static void tcf_ct_flow_table_add(struct tcf_ct_flow_table *ct_ft,
struct nf_conn *ct,
bool tcp, bool bidirectional)
{ … }
static void tcf_ct_flow_table_process_conn(struct tcf_ct_flow_table *ct_ft,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo)
{ … }
static bool
tcf_ct_flow_table_fill_tuple_ipv4(struct sk_buff *skb,
struct flow_offload_tuple *tuple,
struct tcphdr **tcph)
{ … }
static bool
tcf_ct_flow_table_fill_tuple_ipv6(struct sk_buff *skb,
struct flow_offload_tuple *tuple,
struct tcphdr **tcph)
{ … }
static bool tcf_ct_flow_table_lookup(struct tcf_ct_params *p,
struct sk_buff *skb,
u8 family)
{ … }
static int tcf_ct_flow_tables_init(void)
{ … }
static void tcf_ct_flow_tables_uninit(void)
{ … }
static struct tc_action_ops act_ct_ops;
struct tc_ct_action_net { … };
static bool tcf_ct_skb_nfct_cached(struct net *net, struct sk_buff *skb,
struct tcf_ct_params *p)
{ … }
static u8 tcf_ct_skb_nf_family(struct sk_buff *skb)
{ … }
static int tcf_ct_ipv4_is_fragment(struct sk_buff *skb, bool *frag)
{ … }
static int tcf_ct_ipv6_is_fragment(struct sk_buff *skb, bool *frag)
{ … }
static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
u8 family, u16 zone, bool *defrag)
{ … }
static void tcf_ct_params_free(struct tcf_ct_params *params)
{ … }
static void tcf_ct_params_free_rcu(struct rcu_head *head)
{ … }
static void tcf_ct_act_set_mark(struct nf_conn *ct, u32 mark, u32 mask)
{ … }
static void tcf_ct_act_set_labels(struct nf_conn *ct,
u32 *labels,
u32 *labels_m)
{ … }
static int tcf_ct_act_nat(struct sk_buff *skb,
struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
int ct_action,
struct nf_nat_range2 *range,
bool commit)
{ … }
TC_INDIRECT_SCOPE int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
struct tcf_result *res)
{ … }
static const struct nla_policy ct_policy[TCA_CT_MAX + 1] = …;
static int tcf_ct_fill_params_nat(struct tcf_ct_params *p,
struct tc_ct *parm,
struct nlattr **tb,
struct netlink_ext_ack *extack)
{ … }
static void tcf_ct_set_key_val(struct nlattr **tb,
void *val, int val_type,
void *mask, int mask_type,
int len)
{ … }
static int tcf_ct_fill_params(struct net *net,
struct tcf_ct_params *p,
struct tc_ct *parm,
struct nlattr **tb,
struct netlink_ext_ack *extack)
{ … }
static int tcf_ct_init(struct net *net, struct nlattr *nla,
struct nlattr *est, struct tc_action **a,
struct tcf_proto *tp, u32 flags,
struct netlink_ext_ack *extack)
{ … }
static void tcf_ct_cleanup(struct tc_action *a)
{ … }
static int tcf_ct_dump_key_val(struct sk_buff *skb,
void *val, int val_type,
void *mask, int mask_type,
int len)
{ … }
static int tcf_ct_dump_nat(struct sk_buff *skb, struct tcf_ct_params *p)
{ … }
static int tcf_ct_dump_helper(struct sk_buff *skb, struct nf_conntrack_helper *helper)
{ … }
static inline int tcf_ct_dump(struct sk_buff *skb, struct tc_action *a,
int bind, int ref)
{ … }
static void tcf_stats_update(struct tc_action *a, u64 bytes, u64 packets,
u64 drops, u64 lastuse, bool hw)
{ … }
static int tcf_ct_offload_act_setup(struct tc_action *act, void *entry_data,
u32 *index_inc, bool bind,
struct netlink_ext_ack *extack)
{ … }
static struct tc_action_ops act_ct_ops = …;
MODULE_ALIAS_NET_ACT(…) …;
static __net_init int ct_init_net(struct net *net)
{ … }
static void __net_exit ct_exit_net(struct list_head *net_list)
{ … }
static struct pernet_operations ct_net_ops = …;
static int __init ct_init_module(void)
{ … }
static void __exit ct_cleanup_module(void)
{ … }
module_init(…) …;
module_exit(ct_cleanup_module);
MODULE_AUTHOR(…) …;
MODULE_AUTHOR(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;