The branch stable/13 has been updated by melifaro:

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

commit d9211c8c7846381059c7bc73bf10489a2fc49ed1
Author:     Alexander V. Chernikov <melif...@freebsd.org>
AuthorDate: 2022-10-31 17:11:53 +0000
Commit:     Alexander V. Chernikov <melif...@freebsd.org>
CommitDate: 2023-01-23 22:04:02 +0000

    netlink: fix CTRL_CMD_GETFAMILY lookup/dumps.
    
    Reported by:    bapt
    
    (cherry picked from commit 728ca8506dff0f27e32a5994b68e9eea5c345e04)
---
 sys/netlink/netlink_generic.c | 48 +++++++++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 11 deletions(-)

diff --git a/sys/netlink/netlink_generic.c b/sys/netlink/netlink_generic.c
index 94baf12c874e..ffb9f8bcfb86 100644
--- a/sys/netlink/netlink_generic.c
+++ b/sys/netlink/netlink_generic.c
@@ -378,13 +378,25 @@ static const struct nlfield_parser nlf_p_generic[] = {
 };
 
 static struct nlattr_parser nla_p_generic[] = {
-       { .type = CTRL_ATTR_FAMILY_ID , .off = _OUT(family_id), .cb = 
nlattr_get_uint32 },
-       { .type = CTRL_ATTR_FAMILY_NAME , .off = _OUT(family_id), .cb = 
nlattr_get_string },
+       { .type = CTRL_ATTR_FAMILY_ID , .off = _OUT(family_id), .cb = 
nlattr_get_uint16 },
+       { .type = CTRL_ATTR_FAMILY_NAME , .off = _OUT(family_name), .cb = 
nlattr_get_string },
 };
 #undef _IN
 #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 != gf->family_id)
+               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)
 {
@@ -399,19 +411,33 @@ nlctrl_handle_getfamily(struct nlmsghdr *hdr, struct 
nl_pstate *npt)
                .cmd = CTRL_CMD_NEWFAMILY,
        };
 
+       if (attrs.family_id != 0 || attrs.family_name != NULL) {
+               /* Resolve request */
+               for (int i = 0; i < MAX_FAMILIES; i++) {
+                       struct genl_family *gf = &families[i];
+                       if (match_family(gf, &attrs)) {
+                               error = dump_family(hdr, &ghdr, gf, npt->nw);
+                               return (error);
+                       }
+               }
+               return (ENOENT);
+       }
+
+       hdr->nlmsg_flags = hdr->nlmsg_flags | NLM_F_MULTI;
        for (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 != gf->family_id)
-                       continue;
-               if (attrs.family_name != NULL && strcmp(attrs.family_name, 
gf->family_name))
-                       continue;
-               error = dump_family(hdr, &ghdr, &families[i], npt->nw);
-               if (error != 0)
-                       break;
+               if (match_family(gf, &attrs)) {
+                       error = dump_family(hdr, &ghdr, gf, npt->nw);
+                       if (error != 0)
+                               break;
+               }
        }
 
+       if (!nlmsg_end_dump(npt->nw, error, hdr)) {
+                NL_LOG(LOG_DEBUG, "Unable to finalize the dump");
+                return (ENOMEM);
+        }
+
        return (error);
 }
 

Reply via email to