cmd = cmd }; + struct genl_family *gf; struct nl_writer nw; + gf = genl_family(family_id); if (!nl_writer_group(&nw, NLMSG_SMALL, NETLINK_GENERIC, CTRL_GROUP_ID, 0, false)) { NL_LOG(LOG_DEBUG, "error allocating group writer"); @@ -306,6 +321,7 @@ nlctrl_notify(void *arg __unused, const struct genl_family *gf, int cmd) } static const struct nlhdr_parser *all_parsers[] = { &genl_parser }; +static eventhandler_tag family_event_tag; static void genl_load_all(void *u __unused) @@ -338,30 +354,6 @@ SX_SYSINIT(genl_lock, &sx_lock, "genetlink lock"); #define GENL_ASSERT_LOCKED() sx_assert(&sx_lock, SA_LOCKED) #define GENL_ASSERT_XLOCKED() sx_assert(&sx_lock, SA_XLOCKED) -static struct genl_family * -find_family(const char *family_name) -{ - GENL_ASSERT_LOCKED(); - for (u_int i = 0; i < MAX_FAMILIES; i++) - if (families[i].family_name != NULL && - strcmp(families[i].family_name, family_name) == 0) - return (&families[i]); - - return (NULL); -} - -static struct genl_family * -find_empty_family_id(const char *family_name) -{ - GENL_ASSERT_LOCKED(); - /* Microoptimization: index 0 is reserved for the control family */ - for (u_int i = 1; i < MAX_FAMILIES; i++) - if (families[i].family_name == NULL) - return (&families[i]); - - return (NULL); -} - uint16_t genl_register_family(const char *family_name, size_t hdrsize, uint16_t family_version, uint16_t max_attr_idx) @@ -369,13 +361,21 @@ genl_register_family(const char *family_name, size_t hdrsize, struct genl_family *gf; uint16_t family_id; + MPASS(family_name != NULL); + GENL_LOCK(); - if (find_family(family_name) != NULL) { - GENL_UNLOCK(); - return (0); - } + for (u_int i = 0; i < MAX_FAMILIES; i++) + if (families[i].family_name != NULL && + strcmp(families[i].family_name, family_name) == 0) + return (0); - gf = find_empty_family_id(family_name); + /* Microoptimization: index 0 is reserved for the control family. */ + gf = NULL; + for (u_int i = 1; i < MAX_FAMILIES; i++) + if (families[i].family_name == NULL) { + gf = &families[i]; + break; + } KASSERT(gf, ("%s: maximum of %u generic netlink families allocated", __func__, MAX_FAMILIES)); @@ -385,30 +385,27 @@ genl_register_family(const char *family_name, size_t hdrsize, .family_hdrsize = hdrsize, .family_attr_max = max_attr_idx, }; - family_id = genl_get_family_id(gf); + family_id = genl_family_id(gf); GENL_UNLOCK(); NL_LOG(LOG_DEBUG2, "Registered family %s id %d", gf->family_name, family_id); - EVENTHANDLER_INVOKE(genl_family_event, gf, CTRL_CMD_NEWFAMILY); + EVENTHANDLER_INVOKE(genl_family_event, gf->family_name, family_id, + CTRL_CMD_NEWFAMILY); return (family_id); } -static void -free_family(struct genl_family *gf) +void +genl_unregister_family(uint16_t family_id) { - if (gf->family_cmds != NULL) - free(gf->family_cmds, M_NETLINK); -} + struct genl_family *gf; -/* - * unregister groups of a given family - */ -static void -unregister_groups(const struct genl_family *gf) -{ + GENL_LOCK(); + gf = genl_family(family_id); + EVENTHANDLER_INVOKE(genl_family_event, gf->family_name, + family_id, CTRL_CMD_DELFAMILY); for (u_int i = 0; i < MAX_GROUPS; i++) { struct genl_group *gg = &groups[i]; if (gg->group_family == gf && gg->group_name != NULL) { @@ -416,44 +413,21 @@ unregister_groups(const struct genl_family *gf) gg->group_name = NULL; } } -} - -/* - * Can sleep, I guess - */ -bool -genl_unregister_family(const char *family_name) -{ - bool found = false; - - GENL_LOCK(); - struct genl_family *gf = find_family(family_name); - - if (gf != NULL) { - EVENTHANDLER_INVOKE(genl_family_event, gf, CTRL_CMD_DELFAMILY); - found = true; - unregister_groups(gf); - /* TODO: zero pointer first */ - free_family(gf); - bzero(gf, sizeof(*gf)); - } + if (gf->family_cmds != NULL) + free(gf->family_cmds, M_NETLINK); + bzero(gf, sizeof(*gf)); GENL_UNLOCK(); - - return (found); } bool -genl_register_cmds(const char *family_name, const struct genl_cmd *cmds, - int count) +genl_register_cmds(uint16_t family_id, const struct genl_cmd *cmds, + u_int count) { struct genl_family *gf; uint16_t cmd_size; GENL_LOCK(); - if ((gf = find_family(family_name)) == NULL) { - GENL_UNLOCK(); - return (false); - } + gf = genl_family(family_id); cmd_size = gf->family_cmd_size; @@ -490,33 +464,23 @@ genl_register_cmds(const char *family_name, const struct genl_cmd *cmds, return (true); } -static struct genl_group * -find_group(const struct genl_family *gf, const char *group_name) -{ - for (u_int i = 0; i < MAX_GROUPS; i++) { - struct genl_group *gg = &groups[i]; - if (gg->group_family == gf && - !strcmp(gg->group_name, group_name)) - return (gg); - } - return (NULL); -} - uint32_t -genl_register_group(const char *family_name, const char *group_name) +genl_register_group(uint16_t family_id, const char *group_name) { struct genl_family *gf; uint32_t group_id = 0; - MPASS(family_name != NULL); MPASS(group_name != NULL); GENL_LOCK(); - if ((gf = find_family(family_name)) == NULL || - find_group(gf, group_name) != NULL) { - GENL_UNLOCK(); - return (0); - } + gf = genl_family(family_id); + + for (u_int i = 0; i < MAX_GROUPS; i++) + if (groups[i].group_family == gf && + strcmp(groups[i].group_name, group_name) == 0) { + GENL_UNLOCK(); + return (0); + } /* Microoptimization: index 0 is reserved for the control family */ for (u_int i = 1; i < MAX_GROUPS; i++) { @@ -533,29 +497,3 @@ genl_register_group(const char *family_name, const char *group_name) return (group_id); } - -/* accessors */ -struct genl_family * -genl_get_family(uint16_t family_id) -{ - return ((family_id < MAX_FAMILIES) ? &families[family_id] : NULL); -} - -const char * -genl_get_family_name(const struct genl_family *gf) -{ - return (gf->family_name); -} - -uint16_t -genl_get_family_id(const struct genl_family *gf) -{ - MPASS(gf >= &families[0] && gf < &families[MAX_FAMILIES]); - return ((uint16_t)(gf - &families[0]) + GENL_MIN_ID); -} - -struct genl_group * -genl_get_group(uint32_t group_id) -{ - return ((group_id < MAX_GROUPS) ? &groups[group_id] : NULL); -} diff --git a/sys/netlink/netlink_sysevent.c b/sys/netlink/netlink_sysevent.c index c955ce2e8b45..09e7e50a7409 100644 --- a/sys/netlink/netlink_sysevent.c +++ b/sys/netlink/netlink_sysevent.c @@ -45,7 +45,7 @@ _DECLARE_DEBUG(LOG_INFO); MALLOC_DEFINE(M_NLSE, "nlsysevent", "Memory used for Netlink sysevent"); #define NLSE_FAMILY_NAME "nlsysevent" -static uint32_t ctrl_family_id; +static uint16_t ctrl_family_id; #define MAX_SYSEVENT_GROUPS 64 static struct sysevent_group { @@ -118,7 +118,8 @@ sysevent_new_group(size_t index, const char *name) return; } sysevent_groups[index].name = strdup(name, M_NLSE); - sysevent_groups[index].id = genl_register_group(NLSE_FAMILY_NAME, sysevent_groups[index].name); + sysevent_groups[index].id = genl_register_group(ctrl_family_id, + sysevent_groups[index].name); } static struct sysevent_group * @@ -171,7 +172,7 @@ static void nlsysevent_unload(void) { devctl_unset_notify_hook(); - genl_unregister_family(NLSE_FAMILY_NAME); + genl_unregister_family(ctrl_family_id); for (size_t i = 0; i < MAX_SYSEVENT_GROUPS; i++) { if (sysevent_groups[i].name == NULL) break; diff --git a/sys/netlink/netlink_var.h b/sys/netlink/netlink_var.h index ce10a303f9f7..a59cb2efecd0 100644 --- a/sys/netlink/netlink_var.h +++ b/sys/netlink/netlink_var.h @@ -138,10 +138,6 @@ void nl_set_source_metadata(struct mbuf *m, int num_messages); struct nl_buf *nl_buf_alloc(size_t len, int mflag); void nl_buf_free(struct nl_buf *nb); -/* netlink_generic.c */ -struct genl_family *genl_get_family(uint16_t family_id); -struct genl_group *genl_get_group(uint32_t group_id); - #define MAX_FAMILIES 20 #define MAX_GROUPS 64 diff --git a/sys/netpfil/pf/pf_nl.c b/sys/netpfil/pf/pf_nl.c index c0f722b1fd18..737e9cf8cab8 100644 --- a/sys/netpfil/pf/pf_nl.c +++ b/sys/netpfil/pf/pf_nl.c @@ -1858,7 +1858,7 @@ static const struct nlhdr_parser *all_parsers[] = { &table_parser, }; -static int family_id; +static uint16_t family_id; static const struct genl_cmd pf_cmds[] = { { @@ -2051,11 +2051,11 @@ pf_nl_register(void) NL_VERIFY_PARSERS(all_parsers); family_id = genl_register_family(PFNL_FAMILY_NAME, 0, 2, PFNL_CMD_MAX); - genl_register_cmds(PFNL_FAMILY_NAME, pf_cmds, nitems(pf_cmds)); + genl_register_cmds(family_id, pf_cmds, nitems(pf_cmds)); } void pf_nl_unregister(void) { - genl_unregister_family(PFNL_FAMILY_NAME); + genl_unregister_family(family_id); } diff --git a/sys/netpfil/pf/pflow.c b/sys/netpfil/pf/pflow.c index 8741d55b622c..ae9d162bb6bf 100644 --- a/sys/netpfil/pf/pflow.c +++ b/sys/netpfil/pf/pflow.c @@ -1783,11 +1783,11 @@ static const struct nlhdr_parser *all_parsers[] = { static unsigned pflow_do_osd_jail_slot; +static uint16_t family_id; static int pflow_init(void) { bool ret; - int family_id __diagused; NL_VERIFY_PARSERS(all_parsers); @@ -1796,10 +1796,10 @@ pflow_init(void) }; pflow_do_osd_jail_slot = osd_jail_register(NULL, methods); - family_id = genl_register_family(PFLOWNL_FAMILY_NAME, 0, 2, PFLOWNL_CMD_MAX); + family_id = genl_register_family(PFLOWNL_FAMILY_NAME, 0, 2, + PFLOWNL_CMD_MAX); MPASS(family_id != 0); - ret = genl_register_cmds(PFLOWNL_FAMILY_NAME, pflow_cmds, - nitems(pflow_cmds)); + ret = genl_register_cmds(family_id, pflow_cmds, nitems(pflow_cmds)); return (ret ? 0 : ENODEV); } @@ -1808,7 +1808,7 @@ static void pflow_uninit(void) { osd_jail_deregister(pflow_do_osd_jail_slot); - genl_unregister_family(PFLOWNL_FAMILY_NAME); + genl_unregister_family(family_id); } static int diff --git a/sys/rpc/clnt_nl.c b/sys/rpc/clnt_nl.c index 177566232cb5..90d159907d3c 100644 --- a/sys/rpc/clnt_nl.c +++ b/sys/rpc/clnt_nl.c @@ -167,8 +167,7 @@ rpcnl_init(void) rpcnl_family_id = genl_register_family(rpcnl_family_name, 0, 1, 1); MPASS(rpcnl_family_id != 0); - rv = genl_register_cmds(rpcnl_family_name, clnt_cmds, - nitems(clnt_cmds)); + rv = genl_register_cmds(rpcnl_family_id, clnt_cmds, nitems(clnt_cmds)); MPASS(rv); rw_init(&rpcnl_global_lock, rpcnl_family_name); } @@ -185,7 +184,7 @@ client_nl_create(const char *name, const rpcprog_t program, uint32_t group; bool rv __diagused; - if ((group = genl_register_group(rpcnl_family_name, name)) == 0) + if ((group = genl_register_group(rpcnl_family_id, name)) == 0) return (NULL); nl = malloc(sizeof(*nl), M_RPC, M_WAITOK); diff --git a/sys/tests/ktest.c b/sys/tests/ktest.c index 694e1f4229b5..640710f2b89e 100644 --- a/sys/tests/ktest.c +++ b/sys/tests/ktest.c @@ -360,18 +360,17 @@ static const struct genl_cmd ktest_cmds[] = { }, }; +static int family_id; static void ktest_nl_register(void) { bool ret __diagused; - int family_id __diagused; NL_VERIFY_PARSERS(all_parsers); family_id = genl_register_family(KTEST_FAMILY_NAME, 0, 1, KTEST_CMD_MAX); MPASS(family_id != 0); - ret = genl_register_cmds(KTEST_FAMILY_NAME, ktest_cmds, - nitems(ktest_cmds)); + ret = genl_register_cmds(family_id, ktest_cmds, nitems(ktest_cmds)); MPASS(ret); } @@ -380,7 +379,7 @@ ktest_nl_unregister(void) { MPASS(TAILQ_EMPTY(&module_list)); - genl_unregister_family(KTEST_FAMILY_NAME); + genl_unregister_family(family_id); } static int