diff options
author | Alexander V. Chernikov <melifaro@FreeBSD.org> | 2023-03-27 10:48:24 +0000 |
---|---|---|
committer | Alexander V. Chernikov <melifaro@FreeBSD.org> | 2023-03-27 10:48:24 +0000 |
commit | 544f1492c026f358507d812b63943eea08d3155d (patch) | |
tree | 4c9e8a54246e31ddb8b1700be3cb31a3c0f32d5e /sys/netlink | |
parent | e8988d60d24b05e98919e912329880a54cdfdd70 (diff) | |
download | src-544f1492c026f358507d812b63943eea08d3155d.tar.gz src-544f1492c026f358507d812b63943eea08d3155d.zip |
netlink: ensure genetlink control family always registers under the same ID.
MFC after: 2 weeks
Diffstat (limited to 'sys/netlink')
-rw-r--r-- | sys/netlink/netlink_generic.c | 52 |
1 files changed, 36 insertions, 16 deletions
diff --git a/sys/netlink/netlink_generic.c b/sys/netlink/netlink_generic.c index a2bd624f99d9..16b49d5aa9ce 100644 --- a/sys/netlink/netlink_generic.c +++ b/sys/netlink/netlink_generic.c @@ -47,6 +47,8 @@ __FBSDID("$FreeBSD$"); #include <netlink/netlink_debug.h> _DECLARE_DEBUG(LOG_DEBUG); +#define CTRL_FAMILY_NAME "nlctrl" + #define MAX_FAMILIES 20 #define MAX_GROUPS 64 @@ -96,6 +98,28 @@ find_family(const char *family_name) return (NULL); } +static struct genl_family * +find_empty_family_id(const char *family_name) +{ + struct genl_family *gf = NULL; + + if (!strcmp(family_name, CTRL_FAMILY_NAME)) { + gf = &families[0]; + gf->family_id = GENL_MIN_ID; + } else { + /* Index 0 is reserved for the control family */ + for (int i = 1; i < MAX_FAMILIES; i++) { + struct genl_family *gf = &families[i]; + if (gf->family_name == NULL) { + gf->family_id = GENL_MIN_ID + i; + break; + } + } + } + + return (gf); +} + uint32_t genl_register_family(const char *family_name, size_t hdrsize, int family_version, int max_attr_idx) @@ -107,21 +131,18 @@ genl_register_family(const char *family_name, size_t hdrsize, int family_version return (0); GENL_LOCK(); - for (int i = 0; i < MAX_FAMILIES; i++) { - struct genl_family *gf = &families[i]; - if (gf->family_name == NULL) { - gf->family_name = family_name; - gf->family_version = family_version; - gf->family_hdrsize = hdrsize; - gf->family_attr_max = max_attr_idx; - gf->family_id = i + GENL_MIN_ID; - NL_LOG(LOG_DEBUG2, "Registered family %s id %d", - gf->family_name, gf->family_id); - family_id = gf->family_id; - nlctrl_notify(gf, CTRL_CMD_NEWFAMILY); - break; - } - } + + struct genl_family *gf = find_empty_family_id(family_name); + MPASS(gf != NULL); + + gf->family_name = family_name; + gf->family_version = family_version; + gf->family_hdrsize = hdrsize; + gf->family_attr_max = max_attr_idx; + NL_LOG(LOG_DEBUG2, "Registered family %s id %d", gf->family_name, gf->family_id); + family_id = gf->family_id; + nlctrl_notify(gf, CTRL_CMD_NEWFAMILY); + GENL_UNLOCK(); return (family_id); @@ -377,7 +398,6 @@ enomem: /* Declare ourself as a user */ -#define CTRL_FAMILY_NAME "nlctrl" static uint32_t ctrl_family_id; static uint32_t ctrl_group_id; |