#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/rculist.h>
#include <linux/rculist_nulls.h>
#include <linux/types.h>
#include <linux/timer.h>
#include <linux/security.h>
#include <linux/skbuff.h>
#include <linux/errno.h>
#include <linux/netlink.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/siphash.h>
#include <linux/netfilter.h>
#include <net/netlink.h>
#include <net/sock.h>
#include <net/netfilter/nf_conntrack.h>
#include <net/netfilter/nf_conntrack_core.h>
#include <net/netfilter/nf_conntrack_expect.h>
#include <net/netfilter/nf_conntrack_helper.h>
#include <net/netfilter/nf_conntrack_seqadj.h>
#include <net/netfilter/nf_conntrack_l4proto.h>
#include <net/netfilter/nf_conntrack_tuple.h>
#include <net/netfilter/nf_conntrack_acct.h>
#include <net/netfilter/nf_conntrack_zones.h>
#include <net/netfilter/nf_conntrack_timestamp.h>
#include <net/netfilter/nf_conntrack_labels.h>
#include <net/netfilter/nf_conntrack_synproxy.h>
#if IS_ENABLED(CONFIG_NF_NAT)
#include <net/netfilter/nf_nat.h>
#include <net/netfilter/nf_nat_helper.h>
#endif
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/nfnetlink_conntrack.h>
#include "nf_internals.h"
MODULE_LICENSE(…) …;
MODULE_DESCRIPTION(…) …;
struct ctnetlink_list_dump_ctx { … };
static int ctnetlink_dump_tuples_proto(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_l4proto *l4proto)
{ … }
static int ipv4_tuple_to_nlattr(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple)
{ … }
static int ipv6_tuple_to_nlattr(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple)
{ … }
static int ctnetlink_dump_tuples_ip(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple)
{ … }
static int ctnetlink_dump_tuples(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple)
{ … }
static int ctnetlink_dump_zone_id(struct sk_buff *skb, int attrtype,
const struct nf_conntrack_zone *zone, int dir)
{ … }
static int ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct)
{ … }
static int ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct,
bool skip_zero)
{ … }
static int ctnetlink_dump_protoinfo(struct sk_buff *skb, struct nf_conn *ct,
bool destroy)
{ … }
static int ctnetlink_dump_helpinfo(struct sk_buff *skb,
const struct nf_conn *ct)
{ … }
static int
dump_counters(struct sk_buff *skb, struct nf_conn_acct *acct,
enum ip_conntrack_dir dir, int type)
{ … }
static int
ctnetlink_dump_acct(struct sk_buff *skb, const struct nf_conn *ct, int type)
{ … }
static int
ctnetlink_dump_timestamp(struct sk_buff *skb, const struct nf_conn *ct)
{ … }
#ifdef CONFIG_NF_CONNTRACK_MARK
static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct,
bool dump)
{ … }
#else
#define ctnetlink_dump_mark …
#endif
#ifdef CONFIG_NF_CONNTRACK_SECMARK
static int ctnetlink_dump_secctx(struct sk_buff *skb, const struct nf_conn *ct)
{ … }
#else
#define ctnetlink_dump_secctx …
#endif
#ifdef CONFIG_NF_CONNTRACK_LABELS
static inline int ctnetlink_label_size(const struct nf_conn *ct)
{ … }
static int
ctnetlink_dump_labels(struct sk_buff *skb, const struct nf_conn *ct)
{ … }
#else
#define ctnetlink_dump_labels …
#define ctnetlink_label_size …
#endif
#define master_tuple(ct) …
static int ctnetlink_dump_master(struct sk_buff *skb, const struct nf_conn *ct)
{ … }
static int
dump_ct_seq_adj(struct sk_buff *skb, const struct nf_ct_seqadj *seq, int type)
{ … }
static int ctnetlink_dump_ct_seq_adj(struct sk_buff *skb, struct nf_conn *ct)
{ … }
static int ctnetlink_dump_ct_synproxy(struct sk_buff *skb, struct nf_conn *ct)
{ … }
static int ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct)
{ … }
static int ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct)
{ … }
static int ctnetlink_dump_extinfo(struct sk_buff *skb,
struct nf_conn *ct, u32 type)
{ … }
static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
{ … }
static int
ctnetlink_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
struct nf_conn *ct, bool extinfo, unsigned int flags)
{ … }
static const struct nla_policy cta_ip_nla_policy[CTA_IP_MAX + 1] = …;
#if defined(CONFIG_NETFILTER_NETLINK_GLUE_CT) || defined(CONFIG_NF_CONNTRACK_EVENTS)
static size_t ctnetlink_proto_size(const struct nf_conn *ct)
{ … }
#endif
static inline size_t ctnetlink_acct_size(const struct nf_conn *ct)
{ … }
static inline int ctnetlink_secctx_size(const struct nf_conn *ct)
{ … }
static inline size_t ctnetlink_timestamp_size(const struct nf_conn *ct)
{ … }
#ifdef CONFIG_NF_CONNTRACK_EVENTS
static size_t ctnetlink_nlmsg_size(const struct nf_conn *ct)
{ … }
static int
ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
{ … }
#endif
static int ctnetlink_done(struct netlink_callback *cb)
{ … }
struct ctnetlink_filter_u32 { … };
struct ctnetlink_filter { … };
static const struct nla_policy cta_filter_nla_policy[CTA_FILTER_MAX + 1] = …;
static int ctnetlink_parse_filter(const struct nlattr *attr,
struct ctnetlink_filter *filter)
{ … }
static int ctnetlink_parse_zone(const struct nlattr *attr,
struct nf_conntrack_zone *zone);
static int ctnetlink_parse_tuple_filter(const struct nlattr * const cda[],
struct nf_conntrack_tuple *tuple,
u32 type, u_int8_t l3num,
struct nf_conntrack_zone *zone,
u_int32_t flags);
static int ctnetlink_filter_parse_mark(struct ctnetlink_filter_u32 *mark,
const struct nlattr * const cda[])
{ … }
static int ctnetlink_filter_parse_status(struct ctnetlink_filter_u32 *status,
const struct nlattr * const cda[])
{ … }
static struct ctnetlink_filter *
ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
{ … }
static bool ctnetlink_needs_filter(u8 family, const struct nlattr * const *cda)
{ … }
static int ctnetlink_start(struct netlink_callback *cb)
{ … }
static int ctnetlink_filter_match_tuple(struct nf_conntrack_tuple *filter_tuple,
struct nf_conntrack_tuple *ct_tuple,
u_int32_t flags, int family)
{ … }
static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
{ … }
static int
ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
static int ipv4_nlattr_to_tuple(struct nlattr *tb[],
struct nf_conntrack_tuple *t,
u_int32_t flags)
{ … }
static int ipv6_nlattr_to_tuple(struct nlattr *tb[],
struct nf_conntrack_tuple *t,
u_int32_t flags)
{ … }
static int ctnetlink_parse_tuple_ip(struct nlattr *attr,
struct nf_conntrack_tuple *tuple,
u_int32_t flags)
{ … }
static const struct nla_policy proto_nla_policy[CTA_PROTO_MAX+1] = …;
static int ctnetlink_parse_tuple_proto(struct nlattr *attr,
struct nf_conntrack_tuple *tuple,
u_int32_t flags)
{ … }
static int
ctnetlink_parse_zone(const struct nlattr *attr,
struct nf_conntrack_zone *zone)
{ … }
static int
ctnetlink_parse_tuple_zone(struct nlattr *attr, enum ctattr_type type,
struct nf_conntrack_zone *zone)
{ … }
static const struct nla_policy tuple_nla_policy[CTA_TUPLE_MAX+1] = …;
#define CTA_FILTER_F_ALL_CTA_PROTO …
static int
ctnetlink_parse_tuple_filter(const struct nlattr * const cda[],
struct nf_conntrack_tuple *tuple, u32 type,
u_int8_t l3num, struct nf_conntrack_zone *zone,
u_int32_t flags)
{ … }
static int
ctnetlink_parse_tuple(const struct nlattr * const cda[],
struct nf_conntrack_tuple *tuple, u32 type,
u_int8_t l3num, struct nf_conntrack_zone *zone)
{ … }
static const struct nla_policy help_nla_policy[CTA_HELP_MAX+1] = …;
static int ctnetlink_parse_help(const struct nlattr *attr, char **helper_name,
struct nlattr **helpinfo)
{ … }
static const struct nla_policy ct_nla_policy[CTA_MAX+1] = …;
static int ctnetlink_flush_iterate(struct nf_conn *ct, void *data)
{ … }
static int ctnetlink_flush_conntrack(struct net *net,
const struct nlattr * const cda[],
u32 portid, int report, u8 family)
{ … }
static int ctnetlink_del_conntrack(struct sk_buff *skb,
const struct nfnl_info *info,
const struct nlattr * const cda[])
{ … }
static int ctnetlink_get_conntrack(struct sk_buff *skb,
const struct nfnl_info *info,
const struct nlattr * const cda[])
{ … }
static int ctnetlink_done_list(struct netlink_callback *cb)
{ … }
#ifdef CONFIG_NF_CONNTRACK_EVENTS
static int ctnetlink_dump_one_entry(struct sk_buff *skb,
struct netlink_callback *cb,
struct nf_conn *ct,
bool dying)
{ … }
#endif
static int
ctnetlink_dump_unconfirmed(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
static int
ctnetlink_dump_dying(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
static int ctnetlink_get_ct_dying(struct sk_buff *skb,
const struct nfnl_info *info,
const struct nlattr * const cda[])
{ … }
static int ctnetlink_get_ct_unconfirmed(struct sk_buff *skb,
const struct nfnl_info *info,
const struct nlattr * const cda[])
{ … }
#if IS_ENABLED(CONFIG_NF_NAT)
static int
ctnetlink_parse_nat_setup(struct nf_conn *ct,
enum nf_nat_manip_type manip,
const struct nlattr *attr)
__must_hold(RCU)
{ … }
#endif
static int
ctnetlink_change_status(struct nf_conn *ct, const struct nlattr * const cda[])
{ … }
static int
ctnetlink_setup_nat(struct nf_conn *ct, const struct nlattr * const cda[])
{ … }
static int ctnetlink_change_helper(struct nf_conn *ct,
const struct nlattr * const cda[])
{ … }
static int ctnetlink_change_timeout(struct nf_conn *ct,
const struct nlattr * const cda[])
{ … }
#if defined(CONFIG_NF_CONNTRACK_MARK)
static void ctnetlink_change_mark(struct nf_conn *ct,
const struct nlattr * const cda[])
{ … }
#endif
static const struct nla_policy protoinfo_policy[CTA_PROTOINFO_MAX+1] = …;
static int ctnetlink_change_protoinfo(struct nf_conn *ct,
const struct nlattr * const cda[])
{ … }
static const struct nla_policy seqadj_policy[CTA_SEQADJ_MAX+1] = …;
static int change_seq_adj(struct nf_ct_seqadj *seq,
const struct nlattr * const attr)
{ … }
static int
ctnetlink_change_seq_adj(struct nf_conn *ct,
const struct nlattr * const cda[])
{ … }
static const struct nla_policy synproxy_policy[CTA_SYNPROXY_MAX + 1] = …;
static int ctnetlink_change_synproxy(struct nf_conn *ct,
const struct nlattr * const cda[])
{ … }
static int
ctnetlink_attach_labels(struct nf_conn *ct, const struct nlattr * const cda[])
{ … }
static int
ctnetlink_change_conntrack(struct nf_conn *ct,
const struct nlattr * const cda[])
{ … }
static struct nf_conn *
ctnetlink_create_conntrack(struct net *net,
const struct nf_conntrack_zone *zone,
const struct nlattr * const cda[],
struct nf_conntrack_tuple *otuple,
struct nf_conntrack_tuple *rtuple,
u8 u3)
{ … }
static int ctnetlink_new_conntrack(struct sk_buff *skb,
const struct nfnl_info *info,
const struct nlattr * const cda[])
{ … }
static int
ctnetlink_ct_stat_cpu_fill_info(struct sk_buff *skb, u32 portid, u32 seq,
__u16 cpu, const struct ip_conntrack_stat *st)
{ … }
static int
ctnetlink_ct_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
static int ctnetlink_stat_ct_cpu(struct sk_buff *skb,
const struct nfnl_info *info,
const struct nlattr * const cda[])
{ … }
static int
ctnetlink_stat_ct_fill_info(struct sk_buff *skb, u32 portid, u32 seq, u32 type,
struct net *net)
{ … }
static int ctnetlink_stat_ct(struct sk_buff *skb, const struct nfnl_info *info,
const struct nlattr * const cda[])
{ … }
static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = …;
static struct nf_conntrack_expect *
ctnetlink_alloc_expect(const struct nlattr *const cda[], struct nf_conn *ct,
struct nf_conntrack_helper *helper,
struct nf_conntrack_tuple *tuple,
struct nf_conntrack_tuple *mask);
#ifdef CONFIG_NETFILTER_NETLINK_GLUE_CT
static size_t
ctnetlink_glue_build_size(const struct nf_conn *ct)
{ … }
static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
{ … }
static int
ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo,
u_int16_t ct_attr, u_int16_t ct_info_attr)
{ … }
static int
ctnetlink_update_status(struct nf_conn *ct, const struct nlattr * const cda[])
{ … }
static int
ctnetlink_glue_parse_ct(const struct nlattr *cda[], struct nf_conn *ct)
{ … }
static int
ctnetlink_glue_parse(const struct nlattr *attr, struct nf_conn *ct)
{ … }
static int ctnetlink_glue_exp_parse(const struct nlattr * const *cda,
const struct nf_conn *ct,
struct nf_conntrack_tuple *tuple,
struct nf_conntrack_tuple *mask)
{ … }
static int
ctnetlink_glue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
u32 portid, u32 report)
{ … }
static void ctnetlink_glue_seqadj(struct sk_buff *skb, struct nf_conn *ct,
enum ip_conntrack_info ctinfo, int diff)
{ … }
static const struct nfnl_ct_hook ctnetlink_glue_hook = …;
#endif
static int ctnetlink_exp_dump_tuple(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple,
u32 type)
{ … }
static int ctnetlink_exp_dump_mask(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_tuple_mask *mask)
{ … }
#if IS_ENABLED(CONFIG_NF_NAT)
static const union nf_inet_addr any_addr;
#endif
static __be32 nf_expect_get_id(const struct nf_conntrack_expect *exp)
{ … }
static int
ctnetlink_exp_dump_expect(struct sk_buff *skb,
const struct nf_conntrack_expect *exp)
{ … }
static int
ctnetlink_exp_fill_info(struct sk_buff *skb, u32 portid, u32 seq,
int event, const struct nf_conntrack_expect *exp)
{ … }
#ifdef CONFIG_NF_CONNTRACK_EVENTS
static int
ctnetlink_expect_event(unsigned int events, const struct nf_exp_event *item)
{ … }
#endif
static int ctnetlink_exp_done(struct netlink_callback *cb)
{ … }
static int
ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
static int
ctnetlink_exp_ct_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
static int ctnetlink_dump_exp_ct(struct net *net, struct sock *ctnl,
struct sk_buff *skb,
const struct nlmsghdr *nlh,
const struct nlattr * const cda[],
struct netlink_ext_ack *extack)
{ … }
static int ctnetlink_get_expect(struct sk_buff *skb,
const struct nfnl_info *info,
const struct nlattr * const cda[])
{ … }
static bool expect_iter_name(struct nf_conntrack_expect *exp, void *data)
{ … }
static bool expect_iter_all(struct nf_conntrack_expect *exp, void *data)
{ … }
static int ctnetlink_del_expect(struct sk_buff *skb,
const struct nfnl_info *info,
const struct nlattr * const cda[])
{ … }
static int
ctnetlink_change_expect(struct nf_conntrack_expect *x,
const struct nlattr * const cda[])
{ … }
#if IS_ENABLED(CONFIG_NF_NAT)
static const struct nla_policy exp_nat_nla_policy[CTA_EXPECT_NAT_MAX+1] = …;
#endif
static int
ctnetlink_parse_expect_nat(const struct nlattr *attr,
struct nf_conntrack_expect *exp,
u_int8_t u3)
{ … }
static struct nf_conntrack_expect *
ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct,
struct nf_conntrack_helper *helper,
struct nf_conntrack_tuple *tuple,
struct nf_conntrack_tuple *mask)
{ … }
static int
ctnetlink_create_expect(struct net *net,
const struct nf_conntrack_zone *zone,
const struct nlattr * const cda[],
u_int8_t u3, u32 portid, int report)
{ … }
static int ctnetlink_new_expect(struct sk_buff *skb,
const struct nfnl_info *info,
const struct nlattr * const cda[])
{ … }
static int
ctnetlink_exp_stat_fill_info(struct sk_buff *skb, u32 portid, u32 seq, int cpu,
const struct ip_conntrack_stat *st)
{ … }
static int
ctnetlink_exp_stat_cpu_dump(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
static int ctnetlink_stat_exp_cpu(struct sk_buff *skb,
const struct nfnl_info *info,
const struct nlattr * const cda[])
{ … }
#ifdef CONFIG_NF_CONNTRACK_EVENTS
static struct nf_ct_event_notifier ctnl_notifier = …;
#endif
static const struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = …;
static const struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_EXP_MAX] = …;
static const struct nfnetlink_subsystem ctnl_subsys = …;
static const struct nfnetlink_subsystem ctnl_exp_subsys = …;
MODULE_ALIAS(…) …;
MODULE_ALIAS_NFNL_SUBSYS(…);
MODULE_ALIAS_NFNL_SUBSYS(…);
static int __net_init ctnetlink_net_init(struct net *net)
{ … }
static void ctnetlink_net_pre_exit(struct net *net)
{ … }
static struct pernet_operations ctnetlink_net_ops = …;
static int __init ctnetlink_init(void)
{ … }
static void __exit ctnetlink_exit(void)
{ … }
module_init(…) …;
module_exit(ctnetlink_exit);