The branch main has been updated by glebius:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ee507b70f150855cfff0ef1080c38a3c70c1e7cd

commit ee507b70f150855cfff0ef1080c38a3c70c1e7cd
Author:     Gleb Smirnoff <gleb...@freebsd.org>
AuthorDate: 2025-02-05 18:09:06 +0000
Commit:     Gleb Smirnoff <gleb...@freebsd.org>
CommitDate: 2025-02-05 18:09:06 +0000

    netlink: refactor KPI for generic Netlink modules
    
    Now that the family and group are completely private to netlink_generic.c,
    provide a simple and robust KPI, that would require very simple guarantees
    from both KPI and the module:
    
    * Strings are used only for family and group registration, that return ID:
      uint16_t genl_register_family(const char *name, ...
      uint32_t genl_register_group(uint16_t family, const char *name, ...
    * Once created families and groups are guaranteed to not disappear and
      be addressable by their ID.
    * All subsequent calls, including deregistration shall use ID.
    
    Reviewed by:            kp
    Differential Revision:  https://reviews.freebsd.org/D48845
---
 sys/netinet/ip_carp.c          |  11 +-
 sys/netlink/netlink_ctl.h      |  15 +--
 sys/netlink/netlink_generic.c  | 254 ++++++++++++++++-------------------------
 sys/netlink/netlink_sysevent.c |   7 +-
 sys/netlink/netlink_var.h      |   4 -
 sys/netpfil/pf/pf_nl.c         |   6 +-
 sys/netpfil/pf/pflow.c         |  10 +-
 sys/rpc/clnt_nl.c              |   5 +-
 sys/tests/ktest.c              |   7 +-
 9 files changed, 124 insertions(+), 195 deletions(-)

diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
index 871638adb048..5bec8fce3fcb 100644
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -2969,26 +2969,25 @@ static const struct genl_cmd carp_cmds[] = {
        },
 };
 
+static uint16_t carp_family_id;
 static void
 carp_nl_register(void)
 {
        bool ret __diagused;
-       int family_id __diagused;
 
        NL_VERIFY_PARSERS(all_parsers);
-       family_id = genl_register_family(CARP_NL_FAMILY_NAME, 0, 2,
+       carp_family_id = genl_register_family(CARP_NL_FAMILY_NAME, 0, 2,
            CARP_NL_CMD_MAX);
-       MPASS(family_id != 0);
+       MPASS(carp_family_id != 0);
 
-       ret = genl_register_cmds(CARP_NL_FAMILY_NAME, carp_cmds,
-           nitems(carp_cmds));
+       ret = genl_register_cmds(carp_family_id, carp_cmds, nitems(carp_cmds));
        MPASS(ret);
 }
 
 static void
 carp_nl_unregister(void)
 {
-       genl_unregister_family(CARP_NL_FAMILY_NAME);
+       genl_unregister_family(carp_family_id);
 }
 
 static void
diff --git a/sys/netlink/netlink_ctl.h b/sys/netlink/netlink_ctl.h
index 895f70322a29..e7566552ea32 100644
--- a/sys/netlink/netlink_ctl.h
+++ b/sys/netlink/netlink_ctl.h
@@ -93,16 +93,13 @@ struct genl_cmd {
 
 uint16_t genl_register_family(const char *family_name, size_t hdrsize,
     uint16_t family_version, uint16_t max_attr_idx);
-bool genl_unregister_family(const char *family_name);
-bool genl_register_cmds(const char *family_name, const struct genl_cmd *cmds,
-    int count);
-uint32_t genl_register_group(const char *family_name, const char *group_name);
+void genl_unregister_family(uint16_t family);
+bool genl_register_cmds(uint16_t family, const struct genl_cmd *cmds,
+    u_int count);
+uint32_t genl_register_group(uint16_t family, const char *group_name);
 
-struct genl_family;
-const char *genl_get_family_name(const struct genl_family *gf);
-uint16_t genl_get_family_id(const struct genl_family *gf);
-
-typedef void (*genl_family_event_handler_t)(void *arg, const struct 
genl_family *gf, int action);
+typedef void (*genl_family_event_handler_t)(void *arg, const char *family_name,
+    uint16_t family_id, u_int action);
 EVENTHANDLER_DECLARE(genl_family_event, genl_family_event_handler_t);
 
 struct thread;
diff --git a/sys/netlink/netlink_generic.c b/sys/netlink/netlink_generic.c
index 30c73133134b..0714f22382cb 100644
--- a/sys/netlink/netlink_generic.c
+++ b/sys/netlink/netlink_generic.c
@@ -89,6 +89,24 @@ static struct genl_group {
        },
 };
 
+static inline struct genl_family *
+genl_family(uint16_t family_id)
+{
+       struct genl_family *gf;
+
+       gf = &families[family_id - GENL_MIN_ID];
+       KASSERT(family_id - GENL_MIN_ID < MAX_FAMILIES &&
+           gf->family_name != NULL, ("family %u does not exist", family_id));
+       return (gf);
+}
+
+static inline uint16_t
+genl_family_id(const struct genl_family *gf)
+{
+       MPASS(gf >= &families[0] && gf < &families[MAX_FAMILIES]);
+       return ((uint16_t)(gf - &families[0]) + GENL_MIN_ID);
+}
+
 /*
  * Handler called by netlink subsystem when matching netlink message is 
received
  */
@@ -96,22 +114,26 @@ static int
 genl_handle_message(struct nlmsghdr *hdr, struct nl_pstate *npt)
 {
        struct nlpcb *nlp = npt->nlp;
-       struct genl_family *gf = NULL;
+       struct genl_family *gf;
+       uint16_t family_id;
        int error = 0;
 
-       int family_id = (int)hdr->nlmsg_type - GENL_MIN_ID;
-
-       if (__predict_false(family_id < 0 || (gf = genl_get_family(family_id)) 
== NULL)) {
-               NLP_LOG(LOG_DEBUG, nlp, "invalid message type: %d", 
hdr->nlmsg_type);
-               return (ENOTSUP);
-       }
-
        if (__predict_false(hdr->nlmsg_len < sizeof(struct nlmsghdr) +
            GENL_HDRLEN)) {
-               NLP_LOG(LOG_DEBUG, nlp, "invalid message size: %d", 
hdr->nlmsg_len);
+               NLP_LOG(LOG_DEBUG, nlp, "invalid message size: %d",
+                   hdr->nlmsg_len);
                return (EINVAL);
        }
 
+       family_id = hdr->nlmsg_type - GENL_MIN_ID;
+       gf = &families[family_id];
+       if (__predict_false(family_id >= MAX_FAMILIES ||
+           gf->family_name == NULL)) {
+               NLP_LOG(LOG_DEBUG, nlp, "invalid message type: %d",
+                   hdr->nlmsg_type);
+               return (ENOTSUP);
+       }
+
        struct genlmsghdr *ghdr = (struct genlmsghdr *)(hdr + 1);
 
        if (ghdr->cmd >= gf->family_cmd_size || 
gf->family_cmds[ghdr->cmd].cmd_cb == NULL) {
@@ -158,7 +180,7 @@ dump_family(struct nlmsghdr *hdr, struct genlmsghdr *ghdr,
        ghdr_new->reserved = 0;
 
         nlattr_add_string(nw, CTRL_ATTR_FAMILY_NAME, gf->family_name);
-        nlattr_add_u16(nw, CTRL_ATTR_FAMILY_ID, genl_get_family_id(gf));
+        nlattr_add_u16(nw, CTRL_ATTR_FAMILY_ID, genl_family_id(gf));
         nlattr_add_u32(nw, CTRL_ATTR_VERSION, gf->family_version);
         nlattr_add_u32(nw, CTRL_ATTR_HDRSIZE, gf->family_hdrsize);
         nlattr_add_u32(nw, CTRL_ATTR_MAXATTR, gf->family_attr_max);
@@ -185,9 +207,10 @@ dump_family(struct nlmsghdr *hdr, struct genlmsghdr *ghdr,
                int off = nlattr_add_nested(nw, CTRL_ATTR_MCAST_GROUPS);
                if (off == 0)
                        goto enomem;
-               for (int i = 0, cnt = 0; i < MAX_GROUPS; i++) {
-                       struct genl_group *gg = genl_get_group(i);
-                       if (gg == NULL || gg->group_family != gf)
+               for (u_int i = 0, cnt = 0; i < MAX_GROUPS; i++) {
+                       struct genl_group *gg = &groups[i];
+
+                       if (gg->group_family != gf)
                                continue;
 
                        int cmd_off = nlattr_add_nested(nw, ++cnt);
@@ -207,14 +230,9 @@ enomem:
        return (ENOMEM);
 }
 
-
-/* Declare ourself as a user */
-static void nlctrl_notify(void *arg, const struct genl_family *gf, int action);
-static eventhandler_tag family_event_tag;
-
 struct nl_parsed_family {
-       uint32_t        family_id;
        char            *family_name;
+       uint16_t        family_id;
        uint8_t         version;
 };
 
@@ -232,18 +250,6 @@ static struct nlattr_parser nla_p_generic[] = {
 #undef _OUT
 NL_DECLARE_PARSER(genl_parser, struct genlmsghdr, nlf_p_generic, 
nla_p_generic);
 
-static bool
-match_family(const struct genl_family *gf, const struct nl_parsed_family 
*attrs)
-{
-       if (gf->family_name == NULL)
-               return (false);
-       if (attrs->family_id != 0 && attrs->family_id != genl_get_family_id(gf))
-               return (false);
-       if (attrs->family_name != NULL && strcmp(attrs->family_name, 
gf->family_name))
-               return (false);
-       return (true);
-}
-
 static int
 nlctrl_handle_getfamily(struct nlmsghdr *hdr, struct nl_pstate *npt)
 {
@@ -259,21 +265,27 @@ nlctrl_handle_getfamily(struct nlmsghdr *hdr, struct 
nl_pstate *npt)
        };
 
        if (attrs.family_id != 0 || attrs.family_name != NULL) {
-               /* Resolve request */
-               for (int i = 0; i < MAX_FAMILIES; i++) {
-                       struct genl_family *gf = genl_get_family(i);
-                       if (gf != NULL && match_family(gf, &attrs)) {
-                               error = dump_family(hdr, &ghdr, gf, npt->nw);
-                               return (error);
-                       }
+               for (u_int i = 0; i < MAX_FAMILIES; i++) {
+                       struct genl_family *gf = &families[i];
+
+                       if (gf->family_name == NULL)
+                               continue;
+                       if (attrs.family_id != 0 &&
+                           attrs.family_id != genl_family_id(gf))
+                               continue;
+                       if (attrs.family_name != NULL &&
+                           strcmp(attrs.family_name, gf->family_name) != 0)
+                               continue;
+                       return (dump_family(hdr, &ghdr, gf, npt->nw));
                }
                return (ENOENT);
        }
 
        hdr->nlmsg_flags = hdr->nlmsg_flags | NLM_F_MULTI;
-       for (int i = 0; i < MAX_FAMILIES; i++) {
-               struct genl_family *gf = genl_get_family(i);
-               if (gf != NULL && match_family(gf, &attrs)) {
+       for (u_int i = 0; i < MAX_FAMILIES; i++) {
+               struct genl_family *gf = &families[i];
+
+               if (gf->family_name != NULL) {
                        error = dump_family(hdr, &ghdr, gf, npt->nw);
                        if (error != 0)
                                break;
@@ -289,12 +301,15 @@ nlctrl_handle_getfamily(struct nlmsghdr *hdr, struct 
nl_pstate *npt)
 }
 
 static void
-nlctrl_notify(void *arg __unused, const struct genl_family *gf, int cmd)
+nlctrl_notify(void *arg __unused, const char *family_name __unused,
+    uint16_t family_id, u_int cmd)
 {
        struct nlmsghdr hdr = {.nlmsg_type = NETLINK_GENERIC };
        struct genlmsghdr ghdr = { .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

Reply via email to