git: 60c0a075472c - main - netlink: Parse repeated nested attributes
Kevin Bowling <[email protected]>
| Newsgroups | gmane.os.freebsd.devel.cvs.src |
|---|---|
| Message-ID | <6a864055.419c1.41f86686__5473.13043368689$1787183230$gmane$org@gitrepo.freebsd.org> |
The branch main has been updated by kbowling: URL: https://cgit.FreeBSD.org/src/commit/?id=60c0a075472cabd0ac7f54411f6a65626169984a commit 60c0a075472cabd0ac7f54411f6a65626169984a Author: Kevin Bowling <[email protected]> AuthorDate: 2026-08-10 21:34:12 +0000 Commit: Kevin Bowling <[email protected]> CommitDate: 2026-08-19 23:44:55 +0000 netlink: Parse repeated nested attributes Modern Netlink arrays encode their elements as repeated attributes of the same type rather than as children of an additional array container. Add an SNL callback that parses one nested element for each occurrence and appends it to a geometrically grown parser array. Retain the existing parray callback for protocols that use the legacy container form. Store the growth capacity in struct snl_parray, appended after its existing public count and items fields so their offsets remain stable on LP64 and ILP32. Require parser targets to be real snl_parray objects, and convert bitset, generic Netlink, and route multipath arrays accordingly. This avoids relying on layout aliases for private growth state. Add regression coverage for a nested bit array that grows beyond its initial allocation, while preserving replacement semantics when a legacy array target is reused. Reviewed by: melifaro, pouria Sponsored by: BBOX.io Differential Revision: https://reviews.freebsd.org/D58775 --- sbin/route/route_netlink.c | 22 +++---- sys/netlink/netlink_snl.h | 106 +++++++++++++++++++++++--------- sys/netlink/netlink_snl_generic.h | 18 +++--- sys/netlink/netlink_snl_route_parsers.h | 11 ++-- tests/sys/netlink/test_rtnl_route.c | 10 +-- tests/sys/netlink/test_snl.c | 65 ++++++++++++++++++++ tests/sys/netlink/test_snl_generic.c | 6 +- usr.bin/genl/genl.c | 59 +++++++++--------- usr.bin/netstat/route_netlink.c | 8 +-- usr.sbin/arp/arp_netlink.c | 3 +- usr.sbin/ndp/ndp_netlink.c | 3 +- 11 files changed, 211 insertions(+), 100 deletions(-) diff --git a/sbin/route/route_netlink.c b/sbin/route/route_netlink.c index f145771ebb12..ce67cc71c3e8 100644 --- a/sbin/route/route_netlink.c +++ b/sbin/route/route_netlink.c @@ -428,11 +428,11 @@ print_nhop_getmsg(struct nl_helper *h, struct nlmsghdr *hdr, struct sockaddr *ds printf(" fib: %u\n", (unsigned int)r.rta_table); printf(" flags: "); printb(r.rta_rtflags, routeflags); - printf("\n nhops: %u\n", r.rta_multipath.num_nhops); - if (r.rta_multipath.num_nhops != 0) { + printf("\n nhops: %u\n", r.rta_multipath.count); + if (r.rta_multipath.count != 0) { bool first = true; - for (uint32_t i = 0; i < r.rta_multipath.num_nhops; i++) { - struct rta_mpath_nh *nh = r.rta_multipath.nhops[i]; + for (uint32_t i = 0; i < r.rta_multipath.count; i++) { + struct rta_mpath_nh *nh = r.rta_multipath.items[i]; printf("\tvia "); print_nlmsg_route_nhop(h, &r, nh, first); @@ -601,14 +601,14 @@ print_nlmsg_route(struct nl_helper *h, struct nlmsghdr *hdr, return; } - if (r.rta_multipath.num_nhops != 0) { + if (r.rta_multipath.count != 0) { bool first = true; memset(buf, ' ', sizeof(buf)); buf[len] = '\0'; - for (uint32_t i = 0; i < r.rta_multipath.num_nhops; i++) { - struct rta_mpath_nh *nh = r.rta_multipath.nhops[i]; + for (uint32_t i = 0; i < r.rta_multipath.count; i++) { + struct rta_mpath_nh *nh = r.rta_multipath.items[i]; if (!first) printf("%s", buf); @@ -903,9 +903,10 @@ flushroute_one(struct nl_helper *h, struct snl_parsed_route *r) print_nlmsg(h, hdr, &attrs); } else { - if (r->rta_multipath.num_nhops != 0) { - for (uint32_t i = 0; i < r->rta_multipath.num_nhops; i++) { - struct rta_mpath_nh *nh = r->rta_multipath.nhops[i]; + if (r->rta_multipath.count != 0) { + for (uint32_t i = 0; i < r->rta_multipath.count; i++) { + struct rta_mpath_nh *nh = + r->rta_multipath.items[i]; print_flushed_route(r, nh->gw); } @@ -975,4 +976,3 @@ flushroutes_fib_nl(int fib, int af) return (e.error); } - diff --git a/sys/netlink/netlink_snl.h b/sys/netlink/netlink_snl.h index 34a0f3791af2..ecc980387fa8 100644 --- a/sys/netlink/netlink_snl.h +++ b/sys/netlink/netlink_snl.h @@ -724,23 +724,60 @@ snl_attr_get_nested(struct snl_state *ss, struct nlattr *nla, const void *arg, v struct snl_parray { uint32_t count; void **items; + uint32_t _capacity; }; +static inline bool +snl_parray_append(struct snl_state *ss, struct snl_parray *array, void *item, + uint32_t start_size) +{ + void **new_items; + size_t alloc_size; + uint32_t new_size; + + if (start_size == 0) + return (false); + if (array->_capacity == 0) { + new_size = start_size; + if (__builtin_mul_overflow((size_t)new_size, + sizeof(*new_items), &alloc_size)) + return (false); + array->items = (void **)snl_allocz(ss, alloc_size); + if (array->items == NULL) + return (false); + array->_capacity = new_size; + } else if (array->count == array->_capacity) { + if (array->_capacity > UINT32_MAX / 2) + return (false); + new_size = array->_capacity * 2; + if (__builtin_mul_overflow((size_t)new_size, + sizeof(*new_items), &alloc_size)) + return (false); + new_items = (void **)snl_allocz(ss, alloc_size); + if (new_items == NULL) + return (false); + memcpy(new_items, array->items, + array->count * sizeof(*new_items)); + array->items = new_items; + array->_capacity = new_size; + } + array->items[array->count++] = item; + return (true); +} + static inline bool snl_attr_get_parray_sz(struct snl_state *ss, struct nlattr *container_nla, - uint32_t start_size, const void *arg, void *target) + uint32_t start_size, const void *arg, struct snl_parray *array) { const struct snl_hdr_parser *p = (const struct snl_hdr_parser *)arg; - struct snl_parray *array = (struct snl_parray *)target; struct nlattr *nla; - uint32_t count = 0, size = start_size; - if (p->out_size == 0) - return (false); - - array->items = (void **)snl_allocz(ss, size * sizeof(void *)); - if (array->items == NULL) + if (p->out_size == 0 || start_size == 0) return (false); + /* A container attribute replaces, rather than extends, its output. */ + array->count = 0; + array->items = NULL; + array->_capacity = 0; /* * If the provided parser is an attribute parser, assume that each @@ -766,31 +803,49 @@ snl_attr_get_parray_sz(struct snl_state *ss, struct nlattr *container_nla, if (!(snl_parse_header(ss, data, data_len, p, item))) return (false); - if (count == size) { - uint32_t new_size = size * 2; - void **new_array = (void **)snl_allocz(ss, new_size *sizeof(void *)); - - memcpy(new_array, array->items, size * sizeof(void *)); - array->items = new_array; - size = new_size; - } - array->items[count++] = item; + if (!snl_parray_append(ss, array, item, start_size)) + return (false); } - array->count = count; return (true); } /* * Parses and stores the unknown-size array. - * Assumes each array item is a container and the NLAs in the container are parsable - * by the parser provided in @arg. - * Assumes @target is struct snl_parray + * Assumes each array item is a container and the NLAs in the container are + * parsable by the parser provided in @arg. + * @target must point to an actual struct snl_parray. Do not substitute a + * layout-compatible structure: the parser array includes private growth state. */ static inline bool snl_attr_get_parray(struct snl_state *ss, struct nlattr *nla, const void *arg, void *target) { - return (snl_attr_get_parray_sz(ss, nla, 8, arg, target)); + return (snl_attr_get_parray_sz(ss, nla, 8, arg, + (struct snl_parray *)target)); +} + +/* + * Append one repeated nested attribute to an array. Unlike + * snl_attr_get_parray(), the attribute itself is one array member rather + * than a container holding an entire array. Use this for modern Netlink + * multi-attributes. @target must point to an actual struct snl_parray. + */ +static inline bool +snl_attr_get_multi(struct snl_state *ss, struct nlattr *nla, const void *arg, + void *target) +{ + const struct snl_hdr_parser *p = arg; + struct snl_parray *array = target; + void *item; + + if (p->out_size == 0) + return (false); + item = snl_allocz(ss, p->out_size); + if (item == NULL) + return (false); + if (!snl_parse_header(ss, NLA_DATA(nla), NLA_DATA_LEN(nla), p, item)) + return (false); + return (snl_parray_append(ss, array, item, 8)); } static inline bool @@ -849,11 +904,6 @@ struct snl_attr_bit { int bit_value; }; -struct snl_attr_bits { - uint32_t num_bits; - struct snl_attr_bit **bits; -}; - #define _OUT(_field) offsetof(struct snl_attr_bit, _field) static const struct snl_attr_parser _nla_p_bit[] = { { .type = NLA_BITSET_BIT_INDEX, .off = _OUT(bit_index), .cb = snl_attr_get_uint32 }, @@ -867,7 +917,7 @@ struct snl_attr_bitset { uint32_t nla_bitset_size; uint32_t *nla_bitset_mask; uint32_t *nla_bitset_value; - struct snl_attr_bits bits; + struct snl_parray bits; }; #define _OUT(_field) offsetof(struct snl_attr_bitset, _field) diff --git a/sys/netlink/netlink_snl_generic.h b/sys/netlink/netlink_snl_generic.h index 10e98a0266e0..8a8e99813086 100644 --- a/sys/netlink/netlink_snl_generic.h +++ b/sys/netlink/netlink_snl_generic.h @@ -65,11 +65,6 @@ struct _snl_genl_ctrl_mcast_group { const char *mcast_grp_name; }; -struct _snl_genl_ctrl_mcast_groups { - uint32_t num_groups; - struct _snl_genl_ctrl_mcast_group **groups; -}; - #define _OUT(_field) offsetof(struct _snl_genl_ctrl_mcast_group, _field) static struct snl_attr_parser _nla_p_getmc[] = { { @@ -90,7 +85,7 @@ SNL_DECLARE_ATTR_PARSER_EXT(_genl_ctrl_mc_parser, struct _getfamily_attrs { uint16_t family_id; const char *family_name; - struct _snl_genl_ctrl_mcast_groups mcast_groups; + struct snl_parray mcast_groups; }; #define _IN(_field) offsetof(struct genlmsghdr, _field) @@ -165,10 +160,13 @@ snl_get_genl_mcast_group(struct snl_state *ss, const char *family_name, return (0); if (family_id != NULL) *family_id = attrs.family_id; - for (u_int i = 0; i < attrs.mcast_groups.num_groups; i++) - if (strcmp(attrs.mcast_groups.groups[i]->mcast_grp_name, - group_name) == 0) - return (attrs.mcast_groups.groups[i]->mcast_grp_id); + for (u_int i = 0; i < attrs.mcast_groups.count; i++) { + struct _snl_genl_ctrl_mcast_group *group; + + group = attrs.mcast_groups.items[i]; + if (strcmp(group->mcast_grp_name, group_name) == 0) + return (group->mcast_grp_id); + } return (0); } diff --git a/sys/netlink/netlink_snl_route_parsers.h b/sys/netlink/netlink_snl_route_parsers.h index f0849884ec97..10698ca987f3 100644 --- a/sys/netlink/netlink_snl_route_parsers.h +++ b/sys/netlink/netlink_snl_route_parsers.h @@ -93,21 +93,18 @@ SNL_DECLARE_PARSER_EXT(_mpath_nh_parser, sizeof(struct rtnexthop), sizeof(struct rta_mpath_nh), _fp_p_mp_nh, _nla_p_mp_nh, _cb_p_mp_nh); -struct rta_mpath { - uint32_t num_nhops; - struct rta_mpath_nh **nhops; -}; - static bool nlattr_get_multipath(struct snl_state *ss, struct nlattr *nla, const void *arg __unused, void *target) { + struct snl_parray *mpath = target; uint32_t start_size = 4; while (start_size < NLA_DATA_LEN(nla) / sizeof(struct rtnexthop)) start_size *= 2; - return (snl_attr_get_parray_sz(ss, nla, start_size, &_mpath_nh_parser, target)); + return (snl_attr_get_parray_sz(ss, nla, start_size, + &_mpath_nh_parser, mpath)); } struct snl_parsed_route { @@ -115,7 +112,7 @@ struct snl_parsed_route { struct sockaddr *rta_gw; struct sockaddr *rta_pref_src; struct nlattr *rta_metrics; - struct rta_mpath rta_multipath; + struct snl_parray rta_multipath; uint32_t rta_oif; uint32_t rta_expire; uint32_t rta_table; diff --git a/tests/sys/netlink/test_rtnl_route.c b/tests/sys/netlink/test_rtnl_route.c index 334d1fea9fe9..9a1bf0d3b117 100644 --- a/tests/sys/netlink/test_rtnl_route.c +++ b/tests/sys/netlink/test_rtnl_route.c @@ -129,7 +129,7 @@ ATF_TC_BODY(rtnl_nhgrp, tc) ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); ATF_CHECK(snl_parse_nlmsg(&ss, rx_hdr, &snl_rtm_route_parser, &r)); ATF_CHECK(r.rta_knh_id != 0); - ATF_CHECK_INTEQ(r.rta_multipath.num_nhops, 2); + ATF_CHECK_INTEQ(r.rta_multipath.count, 2); cleanup_route_by_dst(&ss, &nw, "192.0.2.0"); } @@ -179,7 +179,7 @@ ATF_TC_BODY(rtnl_nhop_merge, tc) ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); ATF_CHECK(snl_parse_nlmsg(&ss, rx_hdr, &snl_rtm_route_parser, &r)); ATF_CHECK(r.rta_knh_id != 0); - ATF_CHECK_INTEQ(r.rta_multipath.num_nhops, 0); + ATF_CHECK_INTEQ(r.rta_multipath.count, 0); /* Append anoher nhop */ snl_init_writer(&ss, &nw); @@ -202,7 +202,7 @@ ATF_TC_BODY(rtnl_nhop_merge, tc) ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); ATF_CHECK(snl_parse_nlmsg(&ss, rx_hdr, &snl_rtm_route_parser, &r)); ATF_CHECK(r.rta_knh_id != 0); - ATF_CHECK_INTEQ(r.rta_multipath.num_nhops, 2); + ATF_CHECK_INTEQ(r.rta_multipath.count, 2); cleanup_route_by_dst(&ss, &nw, "198.51.100.0"); } @@ -293,7 +293,7 @@ ATF_TC_BODY(rtnl_nhgrp_expire, tc) ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); ATF_CHECK(snl_parse_nlmsg(&ss, rx_hdr, &snl_rtm_route_parser, &r)); ATF_CHECK(r.rta_knh_id != 0); - ATF_CHECK_INTEQ(r.rta_multipath.num_nhops, 3); + ATF_CHECK_INTEQ(r.rta_multipath.count, 3); /* wait for 2 seconds and try again */ sleep(2); @@ -306,7 +306,7 @@ ATF_TC_BODY(rtnl_nhgrp_expire, tc) ATF_REQUIRE(snl_send_message(&ss, hdr)); ATF_REQUIRE((rx_hdr = snl_read_reply(&ss, hdr->nlmsg_seq)) != NULL); ATF_CHECK(snl_parse_nlmsg(&ss, rx_hdr, &snl_rtm_route_parser, &r)); - ATF_CHECK_INTEQ(r.rta_multipath.num_nhops, 2); + ATF_CHECK_INTEQ(r.rta_multipath.count, 2); cleanup_route_by_dst(&ss, &nw, "203.0.113.0"); } diff --git a/tests/sys/netlink/test_snl.c b/tests/sys/netlink/test_snl.c index c2bbc4aff949..15160367299a 100644 --- a/tests/sys/netlink/test_snl.c +++ b/tests/sys/netlink/test_snl.c @@ -37,6 +37,70 @@ ATF_TC_BODY(snl_verify_core_parsers, tc) } +ATF_TC(snl_parse_bitset_array); +ATF_TC_HEAD(snl_parse_bitset_array, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Tests snl(3) parsing a growing nested bit array"); + atf_tc_set_md_var(tc, "require.kmods", "netlink"); +} + +ATF_TC_BODY(snl_parse_bitset_array, tc) +{ + struct snl_attr_bit *bit; + struct snl_parsed_link link = {}; + struct snl_state ss; + struct snl_writer nw; + struct nlmsghdr *hdr; + uint32_t mask, value; + char name[16]; + int bits_off, entry_off, fbsd_off, caps_off; + + ATF_REQUIRE(snl_init(&ss, NETLINK_ROUTE)); + snl_init_writer(&ss, &nw); + hdr = snl_create_msg_request(&nw, RTM_NEWLINK); + ATF_REQUIRE(hdr != NULL); + ATF_REQUIRE(snl_reserve_msg_object(&nw, struct ifinfomsg) != NULL); + + fbsd_off = snl_add_msg_attr_nested(&nw, IFLA_FREEBSD); + ATF_REQUIRE(fbsd_off != 0); + caps_off = snl_add_msg_attr_nested(&nw, IFLAF_CAPS); + ATF_REQUIRE(caps_off != 0); + ATF_REQUIRE(snl_add_msg_attr_u32(&nw, NLA_BITSET_SIZE, 32)); + mask = 0x1ff; + value = 0x155; + ATF_REQUIRE(snl_add_msg_attr(&nw, NLA_BITSET_MASK, sizeof(mask), + &mask)); + ATF_REQUIRE(snl_add_msg_attr(&nw, NLA_BITSET_VALUE, sizeof(value), + &value)); + bits_off = snl_add_msg_attr_nested(&nw, NLA_BITSET_BITS); + ATF_REQUIRE(bits_off != 0); + for (uint32_t i = 0; i < 9; i++) { + entry_off = snl_add_msg_attr_nested(&nw, i + 1); + ATF_REQUIRE(entry_off != 0); + ATF_REQUIRE(snl_add_msg_attr_u32(&nw, + NLA_BITSET_BIT_INDEX, i)); + snprintf(name, sizeof(name), "bit-%u", i); + ATF_REQUIRE(snl_add_msg_attr_string(&nw, + NLA_BITSET_BIT_NAME, name)); + if ((i & 1) == 0) + ATF_REQUIRE(snl_add_msg_attr_flag(&nw, + NLA_BITSET_BIT_VALUE)); + snl_end_attr_nested(&nw, entry_off); + } + snl_end_attr_nested(&nw, bits_off); + snl_end_attr_nested(&nw, caps_off); + snl_end_attr_nested(&nw, fbsd_off); + hdr = snl_finalize_msg(&nw); + ATF_REQUIRE(hdr != NULL); + + ATF_REQUIRE(snl_parse_nlmsg(&ss, hdr, &snl_rtm_link_parser, &link)); + ATF_REQUIRE_EQ(link.iflaf_caps.bits.count, 9); + bit = link.iflaf_caps.bits.items[8]; + ATF_CHECK_EQ(bit->bit_index, 8); + ATF_CHECK_STREQ(bit->bit_name, "bit-8"); + ATF_CHECK_EQ(bit->bit_value, 1); +} ATF_TC(snl_verify_route_parsers); ATF_TC_HEAD(snl_verify_route_parsers, tc) { @@ -230,6 +294,7 @@ ATF_TC_BODY(snl_list_ifaces, tc) ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, snl_verify_core_parsers); + ATF_TP_ADD_TC(tp, snl_parse_bitset_array); ATF_TP_ADD_TC(tp, snl_verify_route_parsers); ATF_TP_ADD_TC(tp, snl_parse_errmsg_capped); ATF_TP_ADD_TC(tp, snl_parse_errmsg_capped_extack); diff --git a/tests/sys/netlink/test_snl_generic.c b/tests/sys/netlink/test_snl_generic.c index 8613bf04a45c..67515c006d37 100644 --- a/tests/sys/netlink/test_snl_generic.c +++ b/tests/sys/netlink/test_snl_generic.c @@ -90,9 +90,10 @@ ATF_TC_BODY(test_snl_get_genl_family_groups, tc) struct _getfamily_attrs attrs = {}; ATF_CHECK(snl_parse_nlmsg(&ss, hdr, &_genl_ctrl_getfam_parser, &attrs)); - ATF_CHECK_EQ(attrs.mcast_groups.num_groups, 1); + ATF_CHECK_EQ(attrs.mcast_groups.count, 1); - struct _snl_genl_ctrl_mcast_group *group = attrs.mcast_groups.groups[0]; + struct _snl_genl_ctrl_mcast_group *group = + attrs.mcast_groups.items[0]; ATF_CHECK(group->mcast_grp_id > 0); ATF_CHECK(!strcmp(group->mcast_grp_name, "notify")); @@ -107,4 +108,3 @@ ATF_TP_ADD_TCS(tp) return (atf_no_error()); } - diff --git a/usr.bin/genl/genl.c b/usr.bin/genl/genl.c index 4d2c252dab98..2107c154ee78 100644 --- a/usr.bin/genl/genl.c +++ b/usr.bin/genl/genl.c @@ -98,10 +98,6 @@ struct genl_ctrl_op { uint32_t id; uint32_t flags; }; -struct genl_ctrl_ops { - uint32_t num_ops; - struct genl_ctrl_op **ops; -}; static struct snl_attr_parser nla_p_getops[] = { #define _OUT(_field) offsetof(struct genl_ctrl_op, _field) { @@ -123,10 +119,6 @@ struct genl_mcast_group { uint32_t id; const char *name; }; -struct genl_mcast_groups { - uint32_t num_groups; - struct genl_mcast_group **groups; -}; static struct snl_attr_parser nla_p_getmc[] = { #define _OUT(_field) offsetof(struct genl_mcast_group, _field) { @@ -150,8 +142,8 @@ struct genl_family { uint32_t version; uint32_t hdrsize; uint32_t max_attr; - struct genl_mcast_groups mcast_groups; - struct genl_ctrl_ops ops; + struct snl_parray mcast_groups; + struct snl_parray ops; }; static struct snl_attr_parser nla_p_getfamily[] = { @@ -208,19 +200,21 @@ static struct op_capability { }; static void -dump_operations(struct genl_ctrl_ops *ops) +dump_operations(struct snl_parray *ops) { - if (ops->num_ops == 0) + struct genl_ctrl_op *op; + + if (ops->count == 0) return; printf("\tsupported operations: \n"); - for (uint32_t i = 0; i < ops->num_ops; i++) { + for (uint32_t i = 0; i < ops->count; i++) { bool p = true; + op = ops->items[i]; printf("\t - ID: %#02x, Capabilities: %#02x", - ops->ops[i]->id, - ops->ops[i]->flags); + op->id, op->flags); for (size_t j = 0; j < nitems(op_caps); j++) - if ((ops->ops[i]->flags & op_caps[j].flag) == + if ((op->flags & op_caps[j].flag) == op_caps[j].flag) { printf("%s%s", p ? " (" : "; ", op_caps[j].str); @@ -231,15 +225,18 @@ dump_operations(struct genl_ctrl_ops *ops) } static void -dump_mcast_groups(struct genl_mcast_groups *mcast_groups) +dump_mcast_groups(struct snl_parray *mcast_groups) { - if (mcast_groups->num_groups == 0) + struct genl_mcast_group *group; + + if (mcast_groups->count == 0) return; printf("\tmulticast groups: \n"); - for (uint32_t i = 0; i < mcast_groups->num_groups; i++) + for (uint32_t i = 0; i < mcast_groups->count; i++) { + group = mcast_groups->items[i]; printf("\t - ID: %#02x, Name: %s\n", - mcast_groups->groups[i]->id, - mcast_groups->groups[i]->name); + group->id, group->name); + } } static void @@ -298,9 +295,13 @@ static struct genl_family attrs; const char * group_name(uint32_t id) { - for (u_int i = 0; i < attrs.mcast_groups.num_groups; i++) - if (attrs.mcast_groups.groups[i]->id == id) - return (attrs.mcast_groups.groups[i]->name); + struct genl_mcast_group *group; + + for (u_int i = 0; i < attrs.mcast_groups.count; i++) { + group = attrs.mcast_groups.items[i]; + if (group->id == id) + return (group->name); + } return ("???"); } @@ -340,14 +341,16 @@ monitor_mcast(int argc, char **argv) if (argc == 1) all = true; - for (u_int i = 0; i < attrs.mcast_groups.num_groups; i++) { + for (u_int i = 0; i < attrs.mcast_groups.count; i++) { + struct genl_mcast_group *group; + + group = attrs.mcast_groups.items[i]; if (all || - strcmp(attrs.mcast_groups.groups[i]->name, argv[1]) == 0) { + strcmp(group->name, argv[1]) == 0) { found = true; if (setsockopt(ss.fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, - &attrs.mcast_groups.groups[i]->id, - sizeof(attrs.mcast_groups.groups[i]->id)) + &group->id, sizeof(group->id)) == -1) err(EXIT_FAILURE, "Cannot subscribe to command " "notify"); diff --git a/usr.bin/netstat/route_netlink.c b/usr.bin/netstat/route_netlink.c index f7349650f4c6..a7b1a546e285 100644 --- a/usr.bin/netstat/route_netlink.c +++ b/usr.bin/netstat/route_netlink.c @@ -235,11 +235,12 @@ p_rtentry_netlink(struct snl_state *ss, const char *name, struct nlmsghdr *hdr) if (rt.rtax_weight == 0) rt.rtax_weight = rt_default_weight; - if (rt.rta_multipath.num_nhops != 0) { + if (rt.rta_multipath.count != 0) { uint32_t orig_rtflags = rt.rta_rtflags; uint32_t orig_mtu = rt.rtax_mtu; - for (uint32_t i = 0; i < rt.rta_multipath.num_nhops; i++) { - struct rta_mpath_nh *nhop = rt.rta_multipath.nhops[i]; + for (uint32_t i = 0; i < rt.rta_multipath.count; i++) { + struct rta_mpath_nh *nhop = + rt.rta_multipath.items[i]; rt.rta_gw = nhop->gw; rt.rta_oif = nhop->ifindex; @@ -341,4 +342,3 @@ p_rtable_netlink(int fibnum, int af) return (true); } - diff --git a/usr.sbin/arp/arp_netlink.c b/usr.sbin/arp/arp_netlink.c index 34f21cf96f4f..e998579d78cb 100644 --- a/usr.sbin/arp/arp_netlink.c +++ b/usr.sbin/arp/arp_netlink.c @@ -132,7 +132,7 @@ guess_ifindex(struct snl_state *ss, uint32_t fibnum, struct in_addr addr) if (!snl_parse_nlmsg(ss, hdr, &snl_rtm_route_parser, &r)) return (0); - if (r.rta_multipath.num_nhops > 0 || (r.rta_rtflags & RTF_GATEWAY)) + if (r.rta_multipath.count > 0 || (r.rta_rtflags & RTF_GATEWAY)) return (0); /* Check if the interface is of supported type */ @@ -448,4 +448,3 @@ set_nl(struct sockaddr_in *dst, struct sockaddr_dl *sdl, char *host) return (e.error != 0); } - diff --git a/usr.sbin/ndp/ndp_netlink.c b/usr.sbin/ndp/ndp_netlink.c index 7bd3252f0943..cd443bda635a 100644 --- a/usr.sbin/ndp/ndp_netlink.c +++ b/usr.sbin/ndp/ndp_netlink.c @@ -164,7 +164,7 @@ guess_ifindex(struct snl_state *ss, uint32_t fibnum, const struct sockaddr_in6 * if (!snl_parse_nlmsg(ss, hdr, &snl_rtm_route_parser, &r)) return (0); - if (r.rta_multipath.num_nhops > 0 || (r.rta_rtflags & RTF_GATEWAY)) + if (r.rta_multipath.count > 0 || (r.rta_rtflags & RTF_GATEWAY)) return (0); /* Check if the interface is of supported type */ @@ -521,4 +521,3 @@ set_nl(uint32_t ifindex, struct sockaddr_in6 *dst, struct sockaddr_dl *sdl, char return (e.error != 0); } -