Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * NETLINK      Generic Netlink Family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * 		Authors:	Jamal Hadi Salim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * 				Thomas Graf <tgraf@suug.ch>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  *				Johannes Berg <johannes@sipsolutions.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/socket.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/rwsem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/idr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include <net/genetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) static DEFINE_MUTEX(genl_mutex); /* serialization of message processing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) static DECLARE_RWSEM(cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) atomic_t genl_sk_destructing_cnt = ATOMIC_INIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) DECLARE_WAIT_QUEUE_HEAD(genl_sk_destructing_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) void genl_lock(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 	mutex_lock(&genl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) EXPORT_SYMBOL(genl_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) void genl_unlock(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) 	mutex_unlock(&genl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) EXPORT_SYMBOL(genl_unlock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #ifdef CONFIG_LOCKDEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) bool lockdep_genl_is_held(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	return lockdep_is_held(&genl_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) EXPORT_SYMBOL(lockdep_genl_is_held);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) static void genl_lock_all(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 	down_write(&cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	genl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) static void genl_unlock_all(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	genl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	up_write(&cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) static DEFINE_IDR(genl_fam_idr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66)  * Bitmap of multicast groups that are currently in use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68)  * To avoid an allocation at boot of just one unsigned long,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69)  * declare it global instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70)  * Bit 0 is marked as already used since group 0 is invalid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71)  * Bit 1 is marked as already used since the drop-monitor code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72)  * abuses the API and thinks it can statically use group 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73)  * That group will typically conflict with other groups that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74)  * any proper users use.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75)  * Bit 16 is marked as used since it's used for generic netlink
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76)  * and the code no longer marks pre-reserved IDs as used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77)  * Bit 17 is marked as already used since the VFS quota code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78)  * also abused this API and relied on family == group ID, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79)  * cater to that by giving it a static family and group ID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80)  * Bit 18 is marked as already used since the PMCRAID driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81)  * did the same thing as the VFS quota code (maybe copied?)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 				      BIT(GENL_ID_VFS_DQUOT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 				      BIT(GENL_ID_PMCRAID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) static unsigned long *mc_groups = &mc_group_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) static unsigned long mc_groups_longs = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) static int genl_ctrl_event(int event, const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 			   const struct genl_multicast_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 			   int grp_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) static const struct genl_family *genl_family_find_byid(unsigned int id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	return idr_find(&genl_fam_idr, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) static const struct genl_family *genl_family_find_byname(char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	const struct genl_family *family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	idr_for_each_entry(&genl_fam_idr, family, id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 		if (strcmp(family->name, name) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 			return family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) static int genl_get_cmd_cnt(const struct genl_family *family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	return family->n_ops + family->n_small_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) static void genl_op_from_full(const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 			      unsigned int i, struct genl_ops *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	*op = family->ops[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	if (!op->maxattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 		op->maxattr = family->maxattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	if (!op->policy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 		op->policy = family->policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) static int genl_get_cmd_full(u32 cmd, const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 			     struct genl_ops *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	for (i = 0; i < family->n_ops; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 		if (family->ops[i].cmd == cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 			genl_op_from_full(family, i, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) static void genl_op_from_small(const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 			       unsigned int i, struct genl_ops *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	memset(op, 0, sizeof(*op));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	op->doit	= family->small_ops[i].doit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	op->dumpit	= family->small_ops[i].dumpit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	op->cmd		= family->small_ops[i].cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	op->internal_flags = family->small_ops[i].internal_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	op->flags	= family->small_ops[i].flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	op->validate	= family->small_ops[i].validate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	op->maxattr = family->maxattr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	op->policy = family->policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) static int genl_get_cmd_small(u32 cmd, const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 			      struct genl_ops *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	for (i = 0; i < family->n_small_ops; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		if (family->small_ops[i].cmd == cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 			genl_op_from_small(family, i, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) static int genl_get_cmd(u32 cmd, const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 			struct genl_ops *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	if (!genl_get_cmd_full(cmd, family, op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	return genl_get_cmd_small(cmd, family, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) static void genl_get_cmd_by_index(unsigned int i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 				  const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 				  struct genl_ops *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 	if (i < family->n_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 		genl_op_from_full(family, i, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	else if (i < family->n_ops + family->n_small_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		genl_op_from_small(family, i - family->n_ops, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 		WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) static int genl_allocate_reserve_groups(int n_groups, int *first_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	unsigned long *new_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	int start = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	bool fits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 		if (start == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 			id = find_first_zero_bit(mc_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 						 mc_groups_longs *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 						 BITS_PER_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 			id = find_next_zero_bit(mc_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 						mc_groups_longs * BITS_PER_LONG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 						start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 		fits = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 		for (i = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 		     i < min_t(int, id + n_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 			       mc_groups_longs * BITS_PER_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 		     i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 			if (test_bit(i, mc_groups)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 				start = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 				fits = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 		if (id + n_groups > mc_groups_longs * BITS_PER_LONG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 			unsigned long new_longs = mc_groups_longs +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 						  BITS_TO_LONGS(n_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 			size_t nlen = new_longs * sizeof(unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 			if (mc_groups == &mc_group_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 				new_groups = kzalloc(nlen, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 				if (!new_groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 					return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 				mc_groups = new_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 				*mc_groups = mc_group_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 				new_groups = krealloc(mc_groups, nlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 						      GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 				if (!new_groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 					return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 				mc_groups = new_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 				for (i = 0; i < BITS_TO_LONGS(n_groups); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 					mc_groups[mc_groups_longs + i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 			mc_groups_longs = new_longs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	} while (!fits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	for (i = id; i < id + n_groups; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 		set_bit(i, mc_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	*first_id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) static struct genl_family genl_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) static int genl_validate_assign_mc_groups(struct genl_family *family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	int first_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	int n_groups = family->n_mcgrps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	int err = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	bool groups_allocated = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	if (!n_groups)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	for (i = 0; i < n_groups; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 		const struct genl_multicast_group *grp = &family->mcgrps[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 		if (WARN_ON(grp->name[0] == '\0'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 		if (WARN_ON(memchr(grp->name, '\0', GENL_NAMSIZ) == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	/* special-case our own group and hacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	if (family == &genl_ctrl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		first_id = GENL_ID_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 		BUG_ON(n_groups != 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	} else if (strcmp(family->name, "NET_DM") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		first_id = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 		BUG_ON(n_groups != 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	} else if (family->id == GENL_ID_VFS_DQUOT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		first_id = GENL_ID_VFS_DQUOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		BUG_ON(n_groups != 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	} else if (family->id == GENL_ID_PMCRAID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		first_id = GENL_ID_PMCRAID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		BUG_ON(n_groups != 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 		groups_allocated = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 		err = genl_allocate_reserve_groups(n_groups, &first_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	family->mcgrp_offset = first_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 	/* if still initializing, can't and don't need to realloc bitmaps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	if (!init_net.genl_sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 	if (family->netnsok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 		netlink_table_grab();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		for_each_net_rcu(net) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 			err = __netlink_change_ngroups(net->genl_sock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 					mc_groups_longs * BITS_PER_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 			if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 				 * No need to roll back, can only fail if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 				 * memory allocation fails and then the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 				 * number of _possible_ groups has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 				 * increased on some sockets which is ok.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		netlink_table_ungrab();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 		err = netlink_change_ngroups(init_net.genl_sock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 					     mc_groups_longs * BITS_PER_LONG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	if (groups_allocated && err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 		for (i = 0; i < family->n_mcgrps; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 			clear_bit(family->mcgrp_offset + i, mc_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) static void genl_unregister_mc_groups(const struct genl_family *family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	netlink_table_grab();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	for_each_net_rcu(net) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 		for (i = 0; i < family->n_mcgrps; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 			__netlink_clear_multicast_users(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 				net->genl_sock, family->mcgrp_offset + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	netlink_table_ungrab();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	for (i = 0; i < family->n_mcgrps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		int grp_id = family->mcgrp_offset + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		if (grp_id != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 			clear_bit(grp_id, mc_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 		genl_ctrl_event(CTRL_CMD_DELMCAST_GRP, family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 				&family->mcgrps[i], grp_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) static int genl_validate_ops(const struct genl_family *family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	if (WARN_ON(family->n_ops && !family->ops) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	    WARN_ON(family->n_small_ops && !family->small_ops))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	for (i = 0; i < genl_get_cmd_cnt(family); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 		struct genl_ops op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 		genl_get_cmd_by_index(i, family, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 		if (op.dumpit == NULL && op.doit == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 		for (j = i + 1; j < genl_get_cmd_cnt(family); j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 			struct genl_ops op2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 			genl_get_cmd_by_index(j, family, &op2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 			if (op.cmd == op2.cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 				return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381)  * genl_register_family - register a generic netlink family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382)  * @family: generic netlink family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384)  * Registers the specified family after validating it first. Only one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385)  * family may be registered with the same family name or identifier.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387)  * The family's ops, multicast groups and module pointer must already
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388)  * be assigned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390)  * Return 0 on success or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) int genl_register_family(struct genl_family *family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	int start = GENL_START_ALLOC, end = GENL_MAX_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	err = genl_validate_ops(family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	genl_lock_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	if (genl_family_find_byname(family->name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		err = -EEXIST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		goto errout_locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	 * Sadly, a few cases need to be special-cased
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	 * due to them having previously abused the API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	 * and having used their family ID also as their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	 * multicast group ID, so we use reserved IDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	 * for both to be sure we can do that mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	if (family == &genl_ctrl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 		/* and this needs to be special for initial family lookups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 		start = end = GENL_ID_CTRL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	} else if (strcmp(family->name, "pmcraid") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		start = end = GENL_ID_PMCRAID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	} else if (strcmp(family->name, "VFS_DQUOT") == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		start = end = GENL_ID_VFS_DQUOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	family->id = idr_alloc_cyclic(&genl_fam_idr, family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 				      start, end + 1, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	if (family->id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		err = family->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 		goto errout_locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	err = genl_validate_assign_mc_groups(family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		goto errout_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	genl_unlock_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	/* send all events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 	genl_ctrl_event(CTRL_CMD_NEWFAMILY, family, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	for (i = 0; i < family->n_mcgrps; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		genl_ctrl_event(CTRL_CMD_NEWMCAST_GRP, family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 				&family->mcgrps[i], family->mcgrp_offset + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) errout_remove:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 	idr_remove(&genl_fam_idr, family->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) errout_locked:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 	genl_unlock_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) EXPORT_SYMBOL(genl_register_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454)  * genl_unregister_family - unregister generic netlink family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455)  * @family: generic netlink family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457)  * Unregisters the specified family.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459)  * Returns 0 on success or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) int genl_unregister_family(const struct genl_family *family)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	genl_lock_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	if (!genl_family_find_byid(family->id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		genl_unlock_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	genl_unregister_mc_groups(family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	idr_remove(&genl_fam_idr, family->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 	up_write(&cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 	wait_event(genl_sk_destructing_waitq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		   atomic_read(&genl_sk_destructing_cnt) == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 	genl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	genl_ctrl_event(CTRL_CMD_DELFAMILY, family, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) EXPORT_SYMBOL(genl_unregister_family);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486)  * genlmsg_put - Add generic netlink header to netlink message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487)  * @skb: socket buffer holding the message
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488)  * @portid: netlink portid the message is addressed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489)  * @seq: sequence number (usually the one of the sender)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490)  * @family: generic netlink family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491)  * @flags: netlink message flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492)  * @cmd: generic netlink command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494)  * Returns pointer to user specific header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		  const struct genl_family *family, int flags, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	struct nlmsghdr *nlh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 	struct genlmsghdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	nlh = nlmsg_put(skb, portid, seq, family->id, GENL_HDRLEN +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 			family->hdrsize, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	if (nlh == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	hdr = nlmsg_data(nlh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 	hdr->cmd = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	hdr->version = family->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	hdr->reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	return (char *) hdr + GENL_HDRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) EXPORT_SYMBOL(genlmsg_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) static struct genl_dumpit_info *genl_dumpit_info_alloc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	return kmalloc(sizeof(struct genl_dumpit_info), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) static void genl_dumpit_info_free(const struct genl_dumpit_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	kfree(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) static struct nlattr **
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) genl_family_rcv_msg_attrs_parse(const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 				struct nlmsghdr *nlh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 				struct netlink_ext_ack *extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 				const struct genl_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 				int hdrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 				enum genl_validate_flags no_strict_flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	enum netlink_validation validate = ops->validate & no_strict_flag ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 					   NL_VALIDATE_LIBERAL :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 					   NL_VALIDATE_STRICT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	struct nlattr **attrbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 	if (!ops->maxattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 	attrbuf = kmalloc_array(ops->maxattr + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 				sizeof(struct nlattr *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	if (!attrbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	err = __nlmsg_parse(nlh, hdrlen, attrbuf, ops->maxattr, ops->policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 			    validate, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		kfree(attrbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 		return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	return attrbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) static void genl_family_rcv_msg_attrs_free(struct nlattr **attrbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	kfree(attrbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) struct genl_start_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	const struct genl_family *family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	struct nlmsghdr *nlh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	struct netlink_ext_ack *extack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	const struct genl_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	int hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) static int genl_start(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	struct genl_start_context *ctx = cb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	const struct genl_ops *ops = ctx->ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	struct genl_dumpit_info *info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	struct nlattr **attrs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	if (ops->validate & GENL_DONT_VALIDATE_DUMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		goto no_attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	if (ctx->nlh->nlmsg_len < nlmsg_msg_size(ctx->hdrlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	attrs = genl_family_rcv_msg_attrs_parse(ctx->family, ctx->nlh, ctx->extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 						ops, ctx->hdrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 						GENL_DONT_VALIDATE_DUMP_STRICT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	if (IS_ERR(attrs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		return PTR_ERR(attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) no_attrs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	info = genl_dumpit_info_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 	if (!info) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		genl_family_rcv_msg_attrs_free(attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	info->family = ctx->family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	info->op = *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	info->attrs = attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 	cb->data = info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	if (ops->start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		if (!ctx->family->parallel_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 			genl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 		rc = ops->start(cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 		if (!ctx->family->parallel_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 			genl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 		genl_family_rcv_msg_attrs_free(info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		genl_dumpit_info_free(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 		cb->data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	const struct genl_ops *ops = &genl_dumpit_info(cb)->op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	genl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	rc = ops->dumpit(skb, cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	genl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) static int genl_lock_done(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	const struct genl_ops *ops = &info->op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	if (ops->done) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 		genl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		rc = ops->done(cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 		genl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	genl_family_rcv_msg_attrs_free(info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	genl_dumpit_info_free(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) static int genl_parallel_done(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 	const struct genl_ops *ops = &info->op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	if (ops->done)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 		rc = ops->done(cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	genl_family_rcv_msg_attrs_free(info->attrs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	genl_dumpit_info_free(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) static int genl_family_rcv_msg_dumpit(const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 				      struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 				      struct nlmsghdr *nlh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 				      struct netlink_ext_ack *extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 				      const struct genl_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 				      int hdrlen, struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	struct genl_start_context ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	if (!ops->dumpit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 	ctx.family = family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	ctx.nlh = nlh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	ctx.extack = extack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	ctx.ops = ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	ctx.hdrlen = hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	if (!family->parallel_ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		struct netlink_dump_control c = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 			.module = family->module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 			.data = &ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 			.start = genl_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 			.dump = genl_lock_dumpit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 			.done = genl_lock_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		genl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		err = __netlink_dump_start(net->genl_sock, skb, nlh, &c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		genl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		struct netlink_dump_control c = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 			.module = family->module,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 			.data = &ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 			.start = genl_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 			.dump = ops->dumpit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 			.done = genl_parallel_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		err = __netlink_dump_start(net->genl_sock, skb, nlh, &c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) static int genl_family_rcv_msg_doit(const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 				    struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 				    struct nlmsghdr *nlh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 				    struct netlink_ext_ack *extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 				    const struct genl_ops *ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 				    int hdrlen, struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	struct nlattr **attrbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	struct genl_info info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	if (!ops->doit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	attrbuf = genl_family_rcv_msg_attrs_parse(family, nlh, extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 						  ops, hdrlen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 						  GENL_DONT_VALIDATE_STRICT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	if (IS_ERR(attrbuf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 		return PTR_ERR(attrbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 	info.snd_seq = nlh->nlmsg_seq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 	info.snd_portid = NETLINK_CB(skb).portid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	info.nlhdr = nlh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	info.genlhdr = nlmsg_data(nlh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	info.attrs = attrbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	info.extack = extack;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	genl_info_net_set(&info, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	memset(&info.user_ptr, 0, sizeof(info.user_ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	if (family->pre_doit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		err = family->pre_doit(ops, skb, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	err = ops->doit(skb, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	if (family->post_doit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 		family->post_doit(ops, skb, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	genl_family_rcv_msg_attrs_free(attrbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) static int genl_family_rcv_msg(const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 			       struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 			       struct nlmsghdr *nlh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 			       struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	struct genlmsghdr *hdr = nlmsg_data(nlh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	struct genl_ops op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	int hdrlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	/* this family doesn't exist in this netns */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	if (!family->netnsok && !net_eq(net, &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	hdrlen = GENL_HDRLEN + family->hdrsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	if (genl_get_cmd(hdr->cmd, family, &op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	if ((op.flags & GENL_ADMIN_PERM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	    !netlink_capable(skb, CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	if ((op.flags & GENL_UNS_ADMIN_PERM) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	    !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 		return genl_family_rcv_msg_dumpit(family, skb, nlh, extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 						  &op, hdrlen, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		return genl_family_rcv_msg_doit(family, skb, nlh, extack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 						&op, hdrlen, net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 			struct netlink_ext_ack *extack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	const struct genl_family *family;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	family = genl_family_find_byid(nlh->nlmsg_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	if (family == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	if (!family->parallel_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		genl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	err = genl_family_rcv_msg(family, skb, nlh, extack);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	if (!family->parallel_ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 		genl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) static void genl_rcv(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	down_read(&cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	netlink_rcv_skb(skb, &genl_rcv_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	up_read(&cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) /**************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816)  * Controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817)  **************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) static struct genl_family genl_ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) static int ctrl_fill_info(const struct genl_family *family, u32 portid, u32 seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 			  u32 flags, struct sk_buff *skb, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	hdr = genlmsg_put(skb, portid, seq, &genl_ctrl, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	if (hdr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, family->name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 	    nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, family->id) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	    nla_put_u32(skb, CTRL_ATTR_VERSION, family->version) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	    nla_put_u32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	    nla_put_u32(skb, CTRL_ATTR_MAXATTR, family->maxattr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	if (genl_get_cmd_cnt(family)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 		struct nlattr *nla_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		nla_ops = nla_nest_start_noflag(skb, CTRL_ATTR_OPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		if (nla_ops == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 		for (i = 0; i < genl_get_cmd_cnt(family); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 			struct nlattr *nest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 			struct genl_ops op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 			u32 op_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 			genl_get_cmd_by_index(i, family, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 			op_flags = op.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 			if (op.dumpit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 				op_flags |= GENL_CMD_CAP_DUMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 			if (op.doit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 				op_flags |= GENL_CMD_CAP_DO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 			if (op.policy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 				op_flags |= GENL_CMD_CAP_HASPOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 			nest = nla_nest_start_noflag(skb, i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 			if (nest == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 			if (nla_put_u32(skb, CTRL_ATTR_OP_ID, op.cmd) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 			    nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, op_flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 			nla_nest_end(skb, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		nla_nest_end(skb, nla_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	if (family->n_mcgrps) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 		struct nlattr *nla_grps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		nla_grps = nla_nest_start_noflag(skb, CTRL_ATTR_MCAST_GROUPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 		if (nla_grps == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 		for (i = 0; i < family->n_mcgrps; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 			struct nlattr *nest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 			const struct genl_multicast_group *grp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 			grp = &family->mcgrps[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 			nest = nla_nest_start_noflag(skb, i + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 			if (nest == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 			if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 					family->mcgrp_offset + i) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 			    nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 					   grp->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 			nla_nest_end(skb, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		nla_nest_end(skb, nla_grps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) static int ctrl_fill_mcgrp_info(const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 				const struct genl_multicast_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 				int grp_id, u32 portid, u32 seq, u32 flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 				struct sk_buff *skb, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	struct nlattr *nla_grps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	struct nlattr *nest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	hdr = genlmsg_put(skb, portid, seq, &genl_ctrl, flags, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	if (hdr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	if (nla_put_string(skb, CTRL_ATTR_FAMILY_NAME, family->name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	    nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, family->id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	nla_grps = nla_nest_start_noflag(skb, CTRL_ATTR_MCAST_GROUPS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	if (nla_grps == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	nest = nla_nest_start_noflag(skb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	if (nest == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	if (nla_put_u32(skb, CTRL_ATTR_MCAST_GRP_ID, grp_id) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	    nla_put_string(skb, CTRL_ATTR_MCAST_GRP_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 			   grp->name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	nla_nest_end(skb, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	nla_nest_end(skb, nla_grps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	return -EMSGSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	int n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	struct genl_family *rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	struct net *net = sock_net(skb->sk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	int fams_to_skip = cb->args[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	unsigned int id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	idr_for_each_entry(&genl_fam_idr, rt, id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		if (!rt->netnsok && !net_eq(net, &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		if (n++ < fams_to_skip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 		if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 				   cb->nlh->nlmsg_seq, NLM_F_MULTI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 				   skb, CTRL_CMD_NEWFAMILY) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 			n--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 	cb->args[0] = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) static struct sk_buff *ctrl_build_family_msg(const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 					     u32 portid, int seq, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	if (skb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		return ERR_PTR(-ENOBUFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	err = ctrl_fill_info(family, portid, seq, 0, skb, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		nlmsg_free(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) static struct sk_buff *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) ctrl_build_mcgrp_msg(const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 		     const struct genl_multicast_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		     int grp_id, u32 portid, int seq, u8 cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	if (skb == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		return ERR_PTR(-ENOBUFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	err = ctrl_fill_mcgrp_info(family, grp, grp_id, portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 				   seq, 0, skb, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		nlmsg_free(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 		return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) static const struct nla_policy ctrl_policy_family[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 	[CTRL_ATTR_FAMILY_ID]	= { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	[CTRL_ATTR_FAMILY_NAME]	= { .type = NLA_NUL_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 				    .len = GENL_NAMSIZ - 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	const struct genl_family *res = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	int err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	if (info->attrs[CTRL_ATTR_FAMILY_ID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		u16 id = nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		res = genl_family_find_byid(id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	if (info->attrs[CTRL_ATTR_FAMILY_NAME]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 		name = nla_data(info->attrs[CTRL_ATTR_FAMILY_NAME]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 		res = genl_family_find_byname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) #ifdef CONFIG_MODULES
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 		if (res == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 			genl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 			up_read(&cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 			request_module("net-pf-%d-proto-%d-family-%s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 				       PF_NETLINK, NETLINK_GENERIC, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 			down_read(&cb_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 			genl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 			res = genl_family_find_byname(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 		err = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	if (res == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	if (!res->netnsok && !net_eq(genl_info_net(info), &init_net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		/* family doesn't exist here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	msg = ctrl_build_family_msg(res, info->snd_portid, info->snd_seq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 				    CTRL_CMD_NEWFAMILY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	if (IS_ERR(msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 		return PTR_ERR(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	return genlmsg_reply(msg, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static int genl_ctrl_event(int event, const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 			   const struct genl_multicast_group *grp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 			   int grp_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	struct sk_buff *msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	/* genl is still initialising */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	if (!init_net.genl_sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	case CTRL_CMD_NEWFAMILY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	case CTRL_CMD_DELFAMILY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 		WARN_ON(grp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 		msg = ctrl_build_family_msg(family, 0, 0, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	case CTRL_CMD_NEWMCAST_GRP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	case CTRL_CMD_DELMCAST_GRP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 		BUG_ON(!grp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 		msg = ctrl_build_mcgrp_msg(family, grp, grp_id, 0, 0, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	if (IS_ERR(msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 		return PTR_ERR(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	if (!family->netnsok) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		genlmsg_multicast_netns(&genl_ctrl, &init_net, msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 					0, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 		rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 		genlmsg_multicast_allns(&genl_ctrl, msg, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 					0, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) struct ctrl_dump_policy_ctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	struct netlink_policy_dump_state *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	const struct genl_family *rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	unsigned int opidx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	u32 op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	u16 fam_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	u8 policies:1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	   single_op:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) static const struct nla_policy ctrl_policy_policy[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	[CTRL_ATTR_FAMILY_ID]	= { .type = NLA_U16 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	[CTRL_ATTR_FAMILY_NAME]	= { .type = NLA_NUL_STRING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 				    .len = GENL_NAMSIZ - 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 	[CTRL_ATTR_OP]		= { .type = NLA_U32 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) static int ctrl_dumppolicy_start(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	struct nlattr **tb = info->attrs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	const struct genl_family *rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	struct genl_ops op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	if (!tb[CTRL_ATTR_FAMILY_ID] && !tb[CTRL_ATTR_FAMILY_NAME])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	if (tb[CTRL_ATTR_FAMILY_ID]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 		ctx->fam_id = nla_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 		rt = genl_family_find_byname(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 			nla_data(tb[CTRL_ATTR_FAMILY_NAME]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 		if (!rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 			return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		ctx->fam_id = rt->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	rt = genl_family_find_byid(ctx->fam_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	if (!rt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	ctx->rt = rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	if (tb[CTRL_ATTR_OP]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		ctx->single_op = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		ctx->op = nla_get_u32(tb[CTRL_ATTR_OP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		err = genl_get_cmd(ctx->op, rt, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 		if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 			NL_SET_BAD_ATTR(cb->extack, tb[CTRL_ATTR_OP]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 		if (!op.policy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 			return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 		return netlink_policy_dump_add_policy(&ctx->state, op.policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 						      op.maxattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	for (i = 0; i < genl_get_cmd_cnt(rt); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 		genl_get_cmd_by_index(i, rt, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 		if (op.policy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 			err = netlink_policy_dump_add_policy(&ctx->state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 							     op.policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 							     op.maxattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 			if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	if (!ctx->state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 		return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) static void *ctrl_dumppolicy_prep(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 				  struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 			  cb->nlh->nlmsg_seq, &genl_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 			  NLM_F_MULTI, CTRL_CMD_GETPOLICY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	if (nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, ctx->fam_id))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	return hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) static int ctrl_dumppolicy_put_op(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 				  struct netlink_callback *cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 			          struct genl_ops *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	struct nlattr *nest_pol, *nest_op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	/* skip if we have nothing to show */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	if (!op->policy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	if (!op->doit &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	    (!op->dumpit || op->validate & GENL_DONT_VALIDATE_DUMP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	hdr = ctrl_dumppolicy_prep(skb, cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	nest_pol = nla_nest_start(skb, CTRL_ATTR_OP_POLICY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	if (!nest_pol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	nest_op = nla_nest_start(skb, op->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	if (!nest_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	/* for now both do/dump are always the same */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	idx = netlink_policy_dump_get_policy_idx(ctx->state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 						 op->policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 						 op->maxattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	if (op->doit && nla_put_u32(skb, CTRL_ATTR_POLICY_DO, idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	if (op->dumpit && !(op->validate & GENL_DONT_VALIDATE_DUMP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 	    nla_put_u32(skb, CTRL_ATTR_POLICY_DUMP, idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	nla_nest_end(skb, nest_op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 	nla_nest_end(skb, nest_pol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	void *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	if (!ctx->policies) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 		while (ctx->opidx < genl_get_cmd_cnt(ctx->rt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 			struct genl_ops op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 			if (ctx->single_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 				int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 				err = genl_get_cmd(ctx->op, ctx->rt, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 				if (WARN_ON(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 					return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 				/* break out of the loop after this one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 				ctx->opidx = genl_get_cmd_cnt(ctx->rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 				genl_get_cmd_by_index(ctx->opidx, ctx->rt, &op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 			if (ctrl_dumppolicy_put_op(skb, cb, &op))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 				return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 			ctx->opidx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 		/* completed with the per-op policy index list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 		ctx->policies = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 	while (netlink_policy_dump_loop(ctx->state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 		struct nlattr *nest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 		hdr = ctrl_dumppolicy_prep(skb, cb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 		if (!hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 		nest = nla_nest_start(skb, CTRL_ATTR_POLICY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 		if (!nest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 		if (netlink_policy_dump_write(skb, ctx->state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 		nla_nest_end(skb, nest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 		genlmsg_end(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	genlmsg_cancel(skb, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	return skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) static int ctrl_dumppolicy_done(struct netlink_callback *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	netlink_policy_dump_free(ctx->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) static const struct genl_ops genl_ctrl_ops[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 		.cmd		= CTRL_CMD_GETFAMILY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 		.policy		= ctrl_policy_family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) 		.maxattr	= ARRAY_SIZE(ctrl_policy_family) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 		.doit		= ctrl_getfamily,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 		.dumpit		= ctrl_dumpfamily,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 		.cmd		= CTRL_CMD_GETPOLICY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 		.policy		= ctrl_policy_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 		.maxattr	= ARRAY_SIZE(ctrl_policy_policy) - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 		.start		= ctrl_dumppolicy_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 		.dumpit		= ctrl_dumppolicy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 		.done		= ctrl_dumppolicy_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) static const struct genl_multicast_group genl_ctrl_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	{ .name = "notify", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) static struct genl_family genl_ctrl __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 	.module = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	.ops = genl_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 	.n_ops = ARRAY_SIZE(genl_ctrl_ops),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	.mcgrps = genl_ctrl_groups,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	.n_mcgrps = ARRAY_SIZE(genl_ctrl_groups),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	.id = GENL_ID_CTRL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	.name = "nlctrl",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	.version = 0x2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	.netnsok = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static int __net_init genl_pernet_init(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 	struct netlink_kernel_cfg cfg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 		.input		= genl_rcv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 		.flags		= NL_CFG_F_NONROOT_RECV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	/* we'll bump the group number right afterwards */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 	net->genl_sock = netlink_kernel_create(net, NETLINK_GENERIC, &cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) 	if (!net->genl_sock && net_eq(net, &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) 		panic("GENL: Cannot initialize generic netlink\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) 	if (!net->genl_sock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) static void __net_exit genl_pernet_exit(struct net *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	netlink_kernel_release(net->genl_sock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	net->genl_sock = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) static struct pernet_operations genl_pernet_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	.init = genl_pernet_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 	.exit = genl_pernet_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) static int __init genl_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	err = genl_register_family(&genl_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 		goto problem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	err = register_pernet_subsys(&genl_pernet_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 		goto problem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) problem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	panic("GENL: Cannot register controller: %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) core_initcall(genl_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 			 gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 	struct sk_buff *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	struct net *net, *prev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	bool delivered = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	for_each_net_rcu(net) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 		if (prev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 			tmp = skb_clone(skb, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 			if (!tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 				err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 			err = nlmsg_multicast(prev->genl_sock, tmp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 					      portid, group, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 			if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 				delivered = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 			else if (err != -ESRCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 				goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 		prev = net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	err = nlmsg_multicast(prev->genl_sock, skb, portid, group, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 		delivered = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	else if (err != -ESRCH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	return delivered ? 0 : -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)  error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) int genlmsg_multicast_allns(const struct genl_family *family,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 			    struct sk_buff *skb, u32 portid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 			    unsigned int group, gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	if (WARN_ON_ONCE(group >= family->n_mcgrps))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	group = family->mcgrp_offset + group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	return genlmsg_mcast(skb, portid, group, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) EXPORT_SYMBOL(genlmsg_multicast_allns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) void genl_notify(const struct genl_family *family, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 		 struct genl_info *info, u32 group, gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	struct net *net = genl_info_net(info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	struct sock *sk = net->genl_sock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 	int report = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	if (info->nlhdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 		report = nlmsg_report(info->nlhdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	if (WARN_ON_ONCE(group >= family->n_mcgrps))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	group = family->mcgrp_offset + group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	nlmsg_notify(sk, skb, info->snd_portid, group, report, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) EXPORT_SYMBOL(genl_notify);