linux/net/netfilter/ipset/ip_set_core.c

// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (C) 2000-2002 Joakim Axelsson <[email protected]>
 *                         Patrick Schaaf <[email protected]>
 * Copyright (C) 2003-2013 Jozsef Kadlecsik <[email protected]>
 */

/* Kernel module for IP set management */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/ip.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/rculist.h>
#include <net/netlink.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>

#include <linux/netfilter.h>
#include <linux/netfilter/x_tables.h>
#include <linux/netfilter/nfnetlink.h>
#include <linux/netfilter/ipset/ip_set.h>

static LIST_HEAD(ip_set_type_list);		/* all registered set types */
static DEFINE_MUTEX(ip_set_type_mutex);		/* protects ip_set_type_list */
static DEFINE_RWLOCK(ip_set_ref_lock);		/* protects the set refs */

struct ip_set_net {};

static unsigned int ip_set_net_id __read_mostly;

static struct ip_set_net *ip_set_pernet(struct net *net)
{}

#define IP_SET_INC
#define STRNCMP(a, b)

static unsigned int max_sets;

module_param(max_sets, int, 0600);
MODULE_PARM_DESC();
MODULE_LICENSE();
MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_ALIAS_NFNL_SUBSYS();

/* When the nfnl mutex or ip_set_ref_lock is held: */
#define ip_set_dereference(inst)
#define ip_set(inst, id)
#define ip_set_ref_netlink(inst,id)
#define ip_set_dereference_nfnl(p)

/* The set types are implemented in modules and registered set types
 * can be found in ip_set_type_list. Adding/deleting types is
 * serialized by ip_set_type_mutex.
 */

static void
ip_set_type_lock(void)
{}

static void
ip_set_type_unlock(void)
{}

/* Register and deregister settype */

static struct ip_set_type *
find_set_type(const char *name, u8 family, u8 revision)
{}

/* Unlock, try to load a set type module and lock again */
static bool
load_settype(const char *name)
{}

/* Find a set type and reference it */
#define find_set_type_get(name, family, revision, found)

static int
__find_set_type_get(const char *name, u8 family, u8 revision,
		    struct ip_set_type **found, bool retry)
{}

/* Find a given set type by name and family.
 * If we succeeded, the supported minimal and maximum revisions are
 * filled out.
 */
#define find_set_type_minmax(name, family, min, max)

static int
__find_set_type_minmax(const char *name, u8 family, u8 *min, u8 *max,
		       bool retry)
{}

#define family_name(f)

/* Register a set type structure. The type is identified by
 * the unique triple of name, family and revision.
 */
int
ip_set_type_register(struct ip_set_type *type)
{}
EXPORT_SYMBOL_GPL();

/* Unregister a set type. There's a small race with ip_set_create */
void
ip_set_type_unregister(struct ip_set_type *type)
{}
EXPORT_SYMBOL_GPL();

/* Utility functions */
void *
ip_set_alloc(size_t size)
{}
EXPORT_SYMBOL_GPL();

void
ip_set_free(void *members)
{}
EXPORT_SYMBOL_GPL();

static bool
flag_nested(const struct nlattr *nla)
{}

static const struct nla_policy ipaddr_policy[IPSET_ATTR_IPADDR_MAX + 1] =;

int
ip_set_get_ipaddr4(struct nlattr *nla,  __be32 *ipaddr)
{}
EXPORT_SYMBOL_GPL();

int
ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr)
{}
EXPORT_SYMBOL_GPL();

static u32
ip_set_timeout_get(const unsigned long *timeout)
{}

static char *
ip_set_comment_uget(struct nlattr *tb)
{}

/* Called from uadd only, protected by the set spinlock.
 * The kadt functions don't use the comment extensions in any way.
 */
void
ip_set_init_comment(struct ip_set *set, struct ip_set_comment *comment,
		    const struct ip_set_ext *ext)
{}
EXPORT_SYMBOL_GPL();

/* Used only when dumping a set, protected by rcu_read_lock() */
static int
ip_set_put_comment(struct sk_buff *skb, const struct ip_set_comment *comment)
{}

/* Called from uadd/udel, flush or the garbage collectors protected
 * by the set spinlock.
 * Called when the set is destroyed and when there can't be any user
 * of the set data anymore.
 */
static void
ip_set_comment_free(struct ip_set *set, void *ptr)
{}

destroyer;
/* ipset data extension types, in size order */

const struct ip_set_ext_type ip_set_extensions[] =;
EXPORT_SYMBOL_GPL();

static bool
add_extension(enum ip_set_ext_id id, u32 flags, struct nlattr *tb[])
{}

size_t
ip_set_elem_len(struct ip_set *set, struct nlattr *tb[], size_t len,
		size_t align)
{}
EXPORT_SYMBOL_GPL();

int
ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[],
		      struct ip_set_ext *ext)
{}
EXPORT_SYMBOL_GPL();

static u64
ip_set_get_bytes(const struct ip_set_counter *counter)
{}

static u64
ip_set_get_packets(const struct ip_set_counter *counter)
{}

static bool
ip_set_put_counter(struct sk_buff *skb, const struct ip_set_counter *counter)
{}

static bool
ip_set_put_skbinfo(struct sk_buff *skb, const struct ip_set_skbinfo *skbinfo)
{}

int
ip_set_put_extensions(struct sk_buff *skb, const struct ip_set *set,
		      const void *e, bool active)
{}
EXPORT_SYMBOL_GPL();

static bool
ip_set_match_counter(u64 counter, u64 match, u8 op)
{}

static void
ip_set_add_bytes(u64 bytes, struct ip_set_counter *counter)
{}

static void
ip_set_add_packets(u64 packets, struct ip_set_counter *counter)
{}

static void
ip_set_update_counter(struct ip_set_counter *counter,
		      const struct ip_set_ext *ext, u32 flags)
{}

static void
ip_set_get_skbinfo(struct ip_set_skbinfo *skbinfo,
		   const struct ip_set_ext *ext,
		   struct ip_set_ext *mext, u32 flags)
{}

bool
ip_set_match_extensions(struct ip_set *set, const struct ip_set_ext *ext,
			struct ip_set_ext *mext, u32 flags, void *data)
{}
EXPORT_SYMBOL_GPL();

/* Creating/destroying/renaming/swapping affect the existence and
 * the properties of a set. All of these can be executed from userspace
 * only and serialized by the nfnl mutex indirectly from nfnetlink.
 *
 * Sets are identified by their index in ip_set_list and the index
 * is used by the external references (set/SET netfilter modules).
 *
 * The set behind an index may change by swapping only, from userspace.
 */

static void
__ip_set_get(struct ip_set *set)
{}

static void
__ip_set_put(struct ip_set *set)
{}

/* set->ref can be swapped out by ip_set_swap, netlink events (like dump) need
 * a separate reference counter
 */
static void
__ip_set_get_netlink(struct ip_set *set)
{}

static void
__ip_set_put_netlink(struct ip_set *set)
{}

/* Add, del and test set entries from kernel.
 *
 * The set behind the index must exist and must be referenced
 * so it can't be destroyed (or changed) under our foot.
 */

static struct ip_set *
ip_set_rcu_get(struct net *net, ip_set_id_t index)
{}

static inline void
ip_set_lock(struct ip_set *set)
{}

static inline void
ip_set_unlock(struct ip_set *set)
{}

int
ip_set_test(ip_set_id_t index, const struct sk_buff *skb,
	    const struct xt_action_param *par, struct ip_set_adt_opt *opt)
{}
EXPORT_SYMBOL_GPL();

int
ip_set_add(ip_set_id_t index, const struct sk_buff *skb,
	   const struct xt_action_param *par, struct ip_set_adt_opt *opt)
{}
EXPORT_SYMBOL_GPL();

int
ip_set_del(ip_set_id_t index, const struct sk_buff *skb,
	   const struct xt_action_param *par, struct ip_set_adt_opt *opt)
{}
EXPORT_SYMBOL_GPL();

/* Find set by name, reference it once. The reference makes sure the
 * thing pointed to, does not go away under our feet.
 *
 */
ip_set_id_t
ip_set_get_byname(struct net *net, const char *name, struct ip_set **set)
{}
EXPORT_SYMBOL_GPL();

/* If the given set pointer points to a valid set, decrement
 * reference count by 1. The caller shall not assume the index
 * to be valid, after calling this function.
 *
 */

static void
__ip_set_put_byindex(struct ip_set_net *inst, ip_set_id_t index)
{}

void
ip_set_put_byindex(struct net *net, ip_set_id_t index)
{}
EXPORT_SYMBOL_GPL();

/* Get the name of a set behind a set index.
 * Set itself is protected by RCU, but its name isn't: to protect against
 * renaming, grab ip_set_ref_lock as reader (see ip_set_rename()) and copy the
 * name.
 */
void
ip_set_name_byindex(struct net *net, ip_set_id_t index, char *name)
{}
EXPORT_SYMBOL_GPL();

/* Routines to call by external subsystems, which do not
 * call nfnl_lock for us.
 */

/* Find set by index, reference it once. The reference makes sure the
 * thing pointed to, does not go away under our feet.
 *
 * The nfnl mutex is used in the function.
 */
ip_set_id_t
ip_set_nfnl_get_byindex(struct net *net, ip_set_id_t index)
{}
EXPORT_SYMBOL_GPL();

/* If the given set pointer points to a valid set, decrement
 * reference count by 1. The caller shall not assume the index
 * to be valid, after calling this function.
 *
 * The nfnl mutex is used in the function.
 */
void
ip_set_nfnl_put(struct net *net, ip_set_id_t index)
{}
EXPORT_SYMBOL_GPL();

/* Communication protocol with userspace over netlink.
 *
 * The commands are serialized by the nfnl mutex.
 */

static inline u8 protocol(const struct nlattr * const tb[])
{}

static inline bool
protocol_failed(const struct nlattr * const tb[])
{}

static inline bool
protocol_min_failed(const struct nlattr * const tb[])
{}

static inline u32
flag_exist(const struct nlmsghdr *nlh)
{}

static struct nlmsghdr *
start_msg(struct sk_buff *skb, u32 portid, u32 seq, unsigned int flags,
	  enum ipset_cmd cmd)
{}

/* Create a set */

static const struct nla_policy ip_set_create_policy[IPSET_ATTR_CMD_MAX + 1] =;

static struct ip_set *
find_set_and_id(struct ip_set_net *inst, const char *name, ip_set_id_t *id)
{}

static inline struct ip_set *
find_set(struct ip_set_net *inst, const char *name)
{}

static int
find_free_id(struct ip_set_net *inst, const char *name, ip_set_id_t *index,
	     struct ip_set **set)
{}

static int ip_set_none(struct sk_buff *skb, const struct nfnl_info *info,
		       const struct nlattr * const attr[])
{}

static int ip_set_create(struct sk_buff *skb, const struct nfnl_info *info,
			 const struct nlattr * const attr[])
{}

/* Destroy sets */

static const struct nla_policy
ip_set_setname_policy[IPSET_ATTR_CMD_MAX + 1] =;

/* In order to return quickly when destroying a single set, it is split
 * into two stages:
 * - Cancel garbage collector
 * - Destroy the set itself via call_rcu()
 */

static void
ip_set_destroy_set_rcu(struct rcu_head *head)
{}

static void
_destroy_all_sets(struct ip_set_net *inst)
{}

static int ip_set_destroy(struct sk_buff *skb, const struct nfnl_info *info,
			  const struct nlattr * const attr[])
{}

/* Flush sets */

static void
ip_set_flush_set(struct ip_set *set)
{}

static int ip_set_flush(struct sk_buff *skb, const struct nfnl_info *info,
			const struct nlattr * const attr[])
{}

/* Rename a set */

static const struct nla_policy
ip_set_setname2_policy[IPSET_ATTR_CMD_MAX + 1] =;

static int ip_set_rename(struct sk_buff *skb, const struct nfnl_info *info,
			 const struct nlattr * const attr[])
{}

/* Swap two sets so that name/index points to the other.
 * References and set names are also swapped.
 *
 * The commands are serialized by the nfnl mutex and references are
 * protected by the ip_set_ref_lock. The kernel interfaces
 * do not hold the mutex but the pointer settings are atomic
 * so the ip_set_list always contains valid pointers to the sets.
 */

static int ip_set_swap(struct sk_buff *skb, const struct nfnl_info *info,
		       const struct nlattr * const attr[])
{}

/* List/save set data */

#define DUMP_INIT
#define DUMP_ALL
#define DUMP_ONE
#define DUMP_LAST

#define DUMP_TYPE(arg)
#define DUMP_FLAGS(arg)

int
ip_set_put_flags(struct sk_buff *skb, struct ip_set *set)
{}
EXPORT_SYMBOL_GPL();

static int
ip_set_dump_done(struct netlink_callback *cb)
{}

static inline void
dump_attrs(struct nlmsghdr *nlh)
{}

static const struct nla_policy
ip_set_dump_policy[IPSET_ATTR_CMD_MAX + 1] =;

static int
ip_set_dump_start(struct netlink_callback *cb)
{}

static int
ip_set_dump_do(struct sk_buff *skb, struct netlink_callback *cb)
{}

static int ip_set_dump(struct sk_buff *skb, const struct nfnl_info *info,
		       const struct nlattr * const attr[])
{}

/* Add, del and test */

static const struct nla_policy ip_set_adt_policy[IPSET_ATTR_CMD_MAX + 1] =;

static int
call_ad(struct net *net, struct sock *ctnl, struct sk_buff *skb,
	struct ip_set *set, struct nlattr *tb[], enum ipset_adt adt,
	u32 flags, bool use_lineno)
{}

static int ip_set_ad(struct net *net, struct sock *ctnl,
		     struct sk_buff *skb,
		     enum ipset_adt adt,
		     const struct nlmsghdr *nlh,
		     const struct nlattr * const attr[],
		     struct netlink_ext_ack *extack)
{}

static int ip_set_uadd(struct sk_buff *skb, const struct nfnl_info *info,
		       const struct nlattr * const attr[])
{}

static int ip_set_udel(struct sk_buff *skb, const struct nfnl_info *info,
		       const struct nlattr * const attr[])
{}

static int ip_set_utest(struct sk_buff *skb, const struct nfnl_info *info,
			const struct nlattr * const attr[])
{}

/* Get headed data of a set */

static int ip_set_header(struct sk_buff *skb, const struct nfnl_info *info,
			 const struct nlattr * const attr[])
{}

/* Get type data */

static const struct nla_policy ip_set_type_policy[IPSET_ATTR_CMD_MAX + 1] =;

static int ip_set_type(struct sk_buff *skb, const struct nfnl_info *info,
		       const struct nlattr * const attr[])
{}

/* Get protocol version */

static const struct nla_policy
ip_set_protocol_policy[IPSET_ATTR_CMD_MAX + 1] =;

static int ip_set_protocol(struct sk_buff *skb, const struct nfnl_info *info,
			   const struct nlattr * const attr[])
{}

/* Get set by name or index, from userspace */

static int ip_set_byname(struct sk_buff *skb, const struct nfnl_info *info,
			 const struct nlattr * const attr[])
{}

static const struct nla_policy ip_set_index_policy[IPSET_ATTR_CMD_MAX + 1] =;

static int ip_set_byindex(struct sk_buff *skb, const struct nfnl_info *info,
			  const struct nlattr * const attr[])
{}

static const struct nfnl_callback ip_set_netlink_subsys_cb[IPSET_MSG_MAX] =;

static struct nfnetlink_subsystem ip_set_netlink_subsys __read_mostly =;

/* Interface to iptables/ip6tables */

static int
ip_set_sockfn_get(struct sock *sk, int optval, void __user *user, int *len)
{}

static struct nf_sockopt_ops so_set __read_mostly =;

static int __net_init
ip_set_net_init(struct net *net)
{}

static void __net_exit
ip_set_net_pre_exit(struct net *net)
{}

static void __net_exit
ip_set_net_exit(struct net *net)
{}

static struct pernet_operations ip_set_net_ops =;

static int __init
ip_set_init(void)
{}

static void __exit
ip_set_fini(void)
{}

module_init();
module_exit(ip_set_fini);

MODULE_DESCRIPTION();