#include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/netfilter.h> #include <linux/rhashtable.h> #include <linux/netdevice.h> #include <linux/tc_act/tc_csum.h> #include <net/flow_offload.h> #include <net/netfilter/nf_flow_table.h> #include <net/netfilter/nf_tables.h> #include <net/netfilter/nf_conntrack.h> #include <net/netfilter/nf_conntrack_acct.h> #include <net/netfilter/nf_conntrack_core.h> #include <net/netfilter/nf_conntrack_tuple.h> static struct workqueue_struct *nf_flow_offload_add_wq; static struct workqueue_struct *nf_flow_offload_del_wq; static struct workqueue_struct *nf_flow_offload_stats_wq; struct flow_offload_work { … }; #define NF_FLOW_DISSECTOR(__match, __type, __field) … static void nf_flow_rule_lwt_match(struct nf_flow_match *match, struct ip_tunnel_info *tun_info) { … } static void nf_flow_rule_vlan_match(struct flow_dissector_key_vlan *key, struct flow_dissector_key_vlan *mask, u16 vlan_id, __be16 proto) { … } static int nf_flow_rule_match(struct nf_flow_match *match, const struct flow_offload_tuple *tuple, struct dst_entry *other_dst) { … } static void flow_offload_mangle(struct flow_action_entry *entry, enum flow_action_mangle_base htype, u32 offset, const __be32 *value, const __be32 *mask) { … } static inline struct flow_action_entry * flow_action_entry_next(struct nf_flow_rule *flow_rule) { … } static int flow_offload_eth_src(struct net *net, const struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } static int flow_offload_eth_dst(struct net *net, const struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } static void flow_offload_ipv4_snat(struct net *net, const struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } static void flow_offload_ipv4_dnat(struct net *net, const struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } static void flow_offload_ipv6_mangle(struct nf_flow_rule *flow_rule, unsigned int offset, const __be32 *addr, const __be32 *mask) { … } static void flow_offload_ipv6_snat(struct net *net, const struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } static void flow_offload_ipv6_dnat(struct net *net, const struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } static int flow_offload_l4proto(const struct flow_offload *flow) { … } static void flow_offload_port_snat(struct net *net, const struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } static void flow_offload_port_dnat(struct net *net, const struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } static void flow_offload_ipv4_checksum(struct net *net, const struct flow_offload *flow, struct nf_flow_rule *flow_rule) { … } static void flow_offload_redirect(struct net *net, const struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } static void flow_offload_encap_tunnel(const struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } static void flow_offload_decap_tunnel(const struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } static int nf_flow_rule_route_common(struct net *net, const struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } int nf_flow_rule_route_ipv4(struct net *net, struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } EXPORT_SYMBOL_GPL(…); int nf_flow_rule_route_ipv6(struct net *net, struct flow_offload *flow, enum flow_offload_tuple_dir dir, struct nf_flow_rule *flow_rule) { … } EXPORT_SYMBOL_GPL(…); #define NF_FLOW_RULE_ACTION_MAX … static struct nf_flow_rule * nf_flow_offload_rule_alloc(struct net *net, const struct flow_offload_work *offload, enum flow_offload_tuple_dir dir) { … } static void __nf_flow_offload_destroy(struct nf_flow_rule *flow_rule) { … } static void nf_flow_offload_destroy(struct nf_flow_rule *flow_rule[]) { … } static int nf_flow_offload_alloc(const struct flow_offload_work *offload, struct nf_flow_rule *flow_rule[]) { … } static void nf_flow_offload_init(struct flow_cls_offload *cls_flow, __be16 proto, int priority, enum flow_cls_command cmd, const struct flow_offload_tuple *tuple, struct netlink_ext_ack *extack) { … } static int nf_flow_offload_tuple(struct nf_flowtable *flowtable, struct flow_offload *flow, struct nf_flow_rule *flow_rule, enum flow_offload_tuple_dir dir, int priority, int cmd, struct flow_stats *stats, struct list_head *block_cb_list) { … } static int flow_offload_tuple_add(struct flow_offload_work *offload, struct nf_flow_rule *flow_rule, enum flow_offload_tuple_dir dir) { … } static void flow_offload_tuple_del(struct flow_offload_work *offload, enum flow_offload_tuple_dir dir) { … } static int flow_offload_rule_add(struct flow_offload_work *offload, struct nf_flow_rule *flow_rule[]) { … } static void flow_offload_work_add(struct flow_offload_work *offload) { … } static void flow_offload_work_del(struct flow_offload_work *offload) { … } static void flow_offload_tuple_stats(struct flow_offload_work *offload, enum flow_offload_tuple_dir dir, struct flow_stats *stats) { … } static void flow_offload_work_stats(struct flow_offload_work *offload) { … } static void flow_offload_work_handler(struct work_struct *work) { … } static void flow_offload_queue_work(struct flow_offload_work *offload) { … } static struct flow_offload_work * nf_flow_offload_work_alloc(struct nf_flowtable *flowtable, struct flow_offload *flow, unsigned int cmd) { … } void nf_flow_offload_add(struct nf_flowtable *flowtable, struct flow_offload *flow) { … } void nf_flow_offload_del(struct nf_flowtable *flowtable, struct flow_offload *flow) { … } void nf_flow_offload_stats(struct nf_flowtable *flowtable, struct flow_offload *flow) { … } void nf_flow_table_offload_flush_cleanup(struct nf_flowtable *flowtable) { … } void nf_flow_table_offload_flush(struct nf_flowtable *flowtable) { … } static int nf_flow_table_block_setup(struct nf_flowtable *flowtable, struct flow_block_offload *bo, enum flow_block_command cmd) { … } static void nf_flow_table_block_offload_init(struct flow_block_offload *bo, struct net *net, enum flow_block_command cmd, struct nf_flowtable *flowtable, struct netlink_ext_ack *extack) { … } static void nf_flow_table_indr_cleanup(struct flow_block_cb *block_cb) { … } static int nf_flow_table_indr_offload_cmd(struct flow_block_offload *bo, struct nf_flowtable *flowtable, struct net_device *dev, enum flow_block_command cmd, struct netlink_ext_ack *extack) { … } static int nf_flow_table_offload_cmd(struct flow_block_offload *bo, struct nf_flowtable *flowtable, struct net_device *dev, enum flow_block_command cmd, struct netlink_ext_ack *extack) { … } int nf_flow_table_offload_setup(struct nf_flowtable *flowtable, struct net_device *dev, enum flow_block_command cmd) { … } EXPORT_SYMBOL_GPL(…); int nf_flow_table_offload_init(void) { … } void nf_flow_table_offload_exit(void) { … }