#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/string_helpers.h>
#include <linux/skbuff.h>
#include <linux/mutex.h>
#include <linux/bitmap.h>
#include <linux/rwsem.h>
#include <linux/idr.h>
#include <net/sock.h>
#include <net/genetlink.h>
#include "genetlink.h"
static DEFINE_MUTEX(genl_mutex);
static DECLARE_RWSEM(cb_lock);
atomic_t genl_sk_destructing_cnt = …;
DECLARE_WAIT_QUEUE_HEAD(…);
void genl_lock(void)
{ … }
EXPORT_SYMBOL(…);
void genl_unlock(void)
{ … }
EXPORT_SYMBOL(…);
static void genl_lock_all(void)
{ … }
static void genl_unlock_all(void)
{ … }
static void genl_op_lock(const struct genl_family *family)
{ … }
static void genl_op_unlock(const struct genl_family *family)
{ … }
static DEFINE_IDR(genl_fam_idr);
static unsigned long mc_group_start = …;
static unsigned long *mc_groups = …;
static unsigned long mc_groups_longs = …;
static struct nla_policy genl_policy_reject_all[] = …;
static int genl_ctrl_event(int event, const struct genl_family *family,
const struct genl_multicast_group *grp,
int grp_id);
static void
genl_op_fill_in_reject_policy(const struct genl_family *family,
struct genl_ops *op)
{ … }
static void
genl_op_fill_in_reject_policy_split(const struct genl_family *family,
struct genl_split_ops *op)
{ … }
static const struct genl_family *genl_family_find_byid(unsigned int id)
{ … }
static const struct genl_family *genl_family_find_byname(char *name)
{ … }
struct genl_op_iter { … };
static void genl_op_from_full(const struct genl_family *family,
unsigned int i, struct genl_ops *op)
{ … }
static int genl_get_cmd_full(u32 cmd, const struct genl_family *family,
struct genl_ops *op)
{ … }
static void genl_op_from_small(const struct genl_family *family,
unsigned int i, struct genl_ops *op)
{ … }
static int genl_get_cmd_small(u32 cmd, const struct genl_family *family,
struct genl_ops *op)
{ … }
static void genl_op_from_split(struct genl_op_iter *iter)
{ … }
static int
genl_get_cmd_split(u32 cmd, u8 flag, const struct genl_family *family,
struct genl_split_ops *op)
{ … }
static int
genl_cmd_full_to_split(struct genl_split_ops *op,
const struct genl_family *family,
const struct genl_ops *full, u8 flags)
{ … }
static int
genl_get_cmd(u32 cmd, u8 flags, const struct genl_family *family,
struct genl_split_ops *op)
{ … }
static int
genl_get_cmd_both(u32 cmd, const struct genl_family *family,
struct genl_split_ops *doit, struct genl_split_ops *dumpit)
{ … }
static bool
genl_op_iter_init(const struct genl_family *family, struct genl_op_iter *iter)
{ … }
static bool genl_op_iter_next(struct genl_op_iter *iter)
{ … }
static void
genl_op_iter_copy(struct genl_op_iter *dst, struct genl_op_iter *src)
{ … }
static unsigned int genl_op_iter_idx(struct genl_op_iter *iter)
{ … }
static int genl_allocate_reserve_groups(int n_groups, int *first_id)
{ … }
static struct genl_family genl_ctrl;
static int genl_validate_assign_mc_groups(struct genl_family *family)
{ … }
static void genl_unregister_mc_groups(const struct genl_family *family)
{ … }
static bool genl_split_op_check(const struct genl_split_ops *op)
{ … }
static int genl_validate_ops(const struct genl_family *family)
{ … }
static void *genl_sk_priv_alloc(struct genl_family *family)
{ … }
static void genl_sk_priv_free(const struct genl_family *family, void *priv)
{ … }
static int genl_sk_privs_alloc(struct genl_family *family)
{ … }
static void genl_sk_privs_free(const struct genl_family *family)
{ … }
static void genl_sk_priv_free_by_sock(struct genl_family *family,
struct sock *sk)
{ … }
static void genl_release(struct sock *sk, unsigned long *groups)
{ … }
void *__genl_sk_priv_get(struct genl_family *family, struct sock *sk)
{ … }
void *genl_sk_priv_get(struct genl_family *family, struct sock *sk)
{ … }
int genl_register_family(struct genl_family *family)
{ … }
EXPORT_SYMBOL(…);
int genl_unregister_family(const struct genl_family *family)
{ … }
EXPORT_SYMBOL(…);
void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
const struct genl_family *family, int flags, u8 cmd)
{ … }
EXPORT_SYMBOL(…);
static struct genl_dumpit_info *genl_dumpit_info_alloc(void)
{ … }
static void genl_dumpit_info_free(const struct genl_dumpit_info *info)
{ … }
static struct nlattr **
genl_family_rcv_msg_attrs_parse(const struct genl_family *family,
struct nlmsghdr *nlh,
struct netlink_ext_ack *extack,
const struct genl_split_ops *ops,
int hdrlen,
enum genl_validate_flags no_strict_flag)
{ … }
static void genl_family_rcv_msg_attrs_free(struct nlattr **attrbuf)
{ … }
struct genl_start_context { … };
static int genl_start(struct netlink_callback *cb)
{ … }
static int genl_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
static int genl_done(struct netlink_callback *cb)
{ … }
static int genl_family_rcv_msg_dumpit(const struct genl_family *family,
struct sk_buff *skb,
struct nlmsghdr *nlh,
struct netlink_ext_ack *extack,
const struct genl_split_ops *ops,
int hdrlen, struct net *net)
{ … }
static int genl_family_rcv_msg_doit(const struct genl_family *family,
struct sk_buff *skb,
struct nlmsghdr *nlh,
struct netlink_ext_ack *extack,
const struct genl_split_ops *ops,
int hdrlen, struct net *net)
{ … }
static int genl_header_check(const struct genl_family *family,
struct nlmsghdr *nlh, struct genlmsghdr *hdr,
struct netlink_ext_ack *extack)
{ … }
static int genl_family_rcv_msg(const struct genl_family *family,
struct sk_buff *skb,
struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{ … }
static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
struct netlink_ext_ack *extack)
{ … }
static void genl_rcv(struct sk_buff *skb)
{ … }
static struct genl_family genl_ctrl;
static int ctrl_fill_info(const struct genl_family *family, u32 portid, u32 seq,
u32 flags, struct sk_buff *skb, u8 cmd)
{ … }
static int ctrl_fill_mcgrp_info(const struct genl_family *family,
const struct genl_multicast_group *grp,
int grp_id, u32 portid, u32 seq, u32 flags,
struct sk_buff *skb, u8 cmd)
{ … }
static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
static struct sk_buff *ctrl_build_family_msg(const struct genl_family *family,
u32 portid, int seq, u8 cmd)
{ … }
static struct sk_buff *
ctrl_build_mcgrp_msg(const struct genl_family *family,
const struct genl_multicast_group *grp,
int grp_id, u32 portid, int seq, u8 cmd)
{ … }
static const struct nla_policy ctrl_policy_family[] = …;
static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
{ … }
static int genl_ctrl_event(int event, const struct genl_family *family,
const struct genl_multicast_group *grp,
int grp_id)
{ … }
struct ctrl_dump_policy_ctx { … };
static const struct nla_policy ctrl_policy_policy[] = …;
static int ctrl_dumppolicy_start(struct netlink_callback *cb)
{ … }
static void *ctrl_dumppolicy_prep(struct sk_buff *skb,
struct netlink_callback *cb)
{ … }
static int ctrl_dumppolicy_put_op(struct sk_buff *skb,
struct netlink_callback *cb,
struct genl_split_ops *doit,
struct genl_split_ops *dumpit)
{ … }
static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
static int ctrl_dumppolicy_done(struct netlink_callback *cb)
{ … }
static const struct genl_split_ops genl_ctrl_ops[] = …;
static const struct genl_multicast_group genl_ctrl_groups[] = …;
static struct genl_family genl_ctrl __ro_after_init = …;
static int genl_bind(struct net *net, int group)
{ … }
static void genl_unbind(struct net *net, int group)
{ … }
static int __net_init genl_pernet_init(struct net *net)
{ … }
static void __net_exit genl_pernet_exit(struct net *net)
{ … }
static struct pernet_operations genl_pernet_ops = …;
static int __init genl_init(void)
{ … }
core_initcall(genl_init);
static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
gfp_t flags)
{ … }
int genlmsg_multicast_allns(const struct genl_family *family,
struct sk_buff *skb, u32 portid,
unsigned int group, gfp_t flags)
{ … }
EXPORT_SYMBOL(…);
void genl_notify(const struct genl_family *family, struct sk_buff *skb,
struct genl_info *info, u32 group, gfp_t flags)
{ … }
EXPORT_SYMBOL(…);