Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F171225519
D58775.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
D58775.diff
View Options
diff --git a/sbin/route/route_netlink.c b/sbin/route/route_netlink.c
--- a/sbin/route/route_netlink.c
+++ b/sbin/route/route_netlink.c
@@ -428,11 +428,11 @@
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 @@
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 @@
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 @@
return (e.error);
}
-
diff --git a/sys/netlink/netlink_snl.h b/sys/netlink/netlink_snl.h
--- a/sys/netlink/netlink_snl.h
+++ b/sys/netlink/netlink_snl.h
@@ -724,23 +724,60 @@
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 @@
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 @@
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 @@
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
--- a/sys/netlink/netlink_snl_generic.h
+++ b/sys/netlink/netlink_snl_generic.h
@@ -65,11 +65,6 @@
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 @@
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 @@
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
--- a/sys/netlink/netlink_snl_route_parsers.h
+++ b/sys/netlink/netlink_snl_route_parsers.h
@@ -93,21 +93,18 @@
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 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
--- a/tests/sys/netlink/test_rtnl_route.c
+++ b/tests/sys/netlink/test_rtnl_route.c
@@ -129,7 +129,7 @@
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_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_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_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_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
--- a/tests/sys/netlink/test_snl.c
+++ b/tests/sys/netlink/test_snl.c
@@ -37,6 +37,70 @@
}
+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_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
--- a/tests/sys/netlink/test_snl_generic.c
+++ b/tests/sys/netlink/test_snl_generic.c
@@ -90,9 +90,10 @@
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 @@
return (atf_no_error());
}
-
diff --git a/usr.bin/genl/genl.c b/usr.bin/genl/genl.c
--- a/usr.bin/genl/genl.c
+++ b/usr.bin/genl/genl.c
@@ -98,10 +98,6 @@
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 @@
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 @@
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 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 @@
}
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 @@
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 @@
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
--- a/usr.bin/netstat/route_netlink.c
+++ b/usr.bin/netstat/route_netlink.c
@@ -235,11 +235,12 @@
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 @@
return (true);
}
-
diff --git a/usr.sbin/arp/arp_netlink.c b/usr.sbin/arp/arp_netlink.c
--- a/usr.sbin/arp/arp_netlink.c
+++ b/usr.sbin/arp/arp_netlink.c
@@ -132,7 +132,7 @@
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 @@
return (e.error != 0);
}
-
diff --git a/usr.sbin/ndp/ndp_netlink.c b/usr.sbin/ndp/ndp_netlink.c
--- a/usr.sbin/ndp/ndp_netlink.c
+++ b/usr.sbin/ndp/ndp_netlink.c
@@ -164,7 +164,7 @@
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 @@
return (e.error != 0);
}
-
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Sep 10, 3:50 PM (16 h, 36 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
38600305
Default Alt Text
D58775.diff (18 KB)
Attached To
Mode
D58775: netlink: Parse repeated nested attributes
Attached
Detach File
Event Timeline
Log In to Comment