mirror of
https://github.com/freebsd/freebsd-src
synced 2024-09-06 09:10:28 +00:00
netlink: use newly-added snl(3) array parsing for handling multipath
routes. MFC after: 2 weeks
This commit is contained in:
parent
5f19f790b3
commit
656a39c1a0
|
@ -533,14 +533,14 @@ print_nlmsg_route(struct nl_helper *h, struct nlmsghdr *hdr,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r.rta_multipath != NULL) {
|
if (r.rta_multipath.num_nhops != 0) {
|
||||||
bool first = true;
|
bool first = true;
|
||||||
|
|
||||||
memset(buf, ' ', sizeof(buf));
|
memset(buf, ' ', sizeof(buf));
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
|
|
||||||
for (int i = 0; i < r.rta_multipath->num_nhops; i++) {
|
for (uint32_t i = 0; i < r.rta_multipath.num_nhops; i++) {
|
||||||
struct rta_mpath_nh *nh = &r.rta_multipath->nhops[i];
|
struct rta_mpath_nh *nh = r.rta_multipath.nhops[i];
|
||||||
|
|
||||||
if (!first)
|
if (!first)
|
||||||
printf("%s", buf);
|
printf("%s", buf);
|
||||||
|
@ -834,9 +834,9 @@ flushroute_one(struct nl_helper *h, struct snl_parsed_route *r)
|
||||||
print_nlmsg(h, hdr, &attrs);
|
print_nlmsg(h, hdr, &attrs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (r->rta_multipath != NULL) {
|
if (r->rta_multipath.num_nhops != 0) {
|
||||||
for (int i = 0; i < r->rta_multipath->num_nhops; i++) {
|
for (uint32_t i = 0; i < r->rta_multipath.num_nhops; i++) {
|
||||||
struct rta_mpath_nh *nh = &r->rta_multipath->nhops[i];
|
struct rta_mpath_nh *nh = r->rta_multipath.nhops[i];
|
||||||
|
|
||||||
print_flushed_route(r, nh->gw);
|
print_flushed_route(r, nh->gw);
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,48 +90,27 @@ SNL_DECLARE_PARSER_EXT(_mpath_nh_parser, sizeof(struct rtnexthop),
|
||||||
_cb_p_mp_nh);
|
_cb_p_mp_nh);
|
||||||
|
|
||||||
struct rta_mpath {
|
struct rta_mpath {
|
||||||
int num_nhops;
|
uint32_t num_nhops;
|
||||||
struct rta_mpath_nh nhops[0];
|
struct rta_mpath_nh **nhops;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
nlattr_get_multipath(struct snl_state *ss, struct nlattr *nla, const void *arg __unused,
|
nlattr_get_multipath(struct snl_state *ss, struct nlattr *nla, const void *arg,
|
||||||
void *target)
|
void *target)
|
||||||
{
|
{
|
||||||
int data_len = nla->nla_len - sizeof(struct nlattr);
|
uint32_t start_size = 4;
|
||||||
struct rtnexthop *rtnh;
|
|
||||||
|
|
||||||
int max_nhops = data_len / sizeof(struct rtnexthop);
|
while (start_size < NLA_DATA_LEN(nla) / sizeof(struct rtnexthop))
|
||||||
size_t sz = (max_nhops + 2) * sizeof(struct rta_mpath_nh);
|
start_size *= 2;
|
||||||
|
|
||||||
struct rta_mpath *mp = snl_allocz(ss, sz);
|
return (snl_attr_get_parray_sz(ss, nla, start_size, &_mpath_nh_parser, target));
|
||||||
if (mp == NULL)
|
|
||||||
return (false);
|
|
||||||
mp->num_nhops = 0;
|
|
||||||
|
|
||||||
for (rtnh = (struct rtnexthop *)(void *)(nla + 1); data_len > 0; ) {
|
|
||||||
struct rta_mpath_nh *mpnh = &mp->nhops[mp->num_nhops++];
|
|
||||||
|
|
||||||
if (!snl_parse_header(ss, rtnh, rtnh->rtnh_len, &_mpath_nh_parser, mpnh))
|
|
||||||
return (false);
|
|
||||||
|
|
||||||
int len = NL_ITEM_ALIGN(rtnh->rtnh_len);
|
|
||||||
data_len -= len;
|
|
||||||
rtnh = (struct rtnexthop *)(void *)((char *)rtnh + len);
|
|
||||||
}
|
|
||||||
if (data_len != 0 || mp->num_nhops == 0) {
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
|
|
||||||
*((struct rta_mpath **)target) = mp;
|
|
||||||
return (true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct snl_parsed_route {
|
struct snl_parsed_route {
|
||||||
struct sockaddr *rta_dst;
|
struct sockaddr *rta_dst;
|
||||||
struct sockaddr *rta_gw;
|
struct sockaddr *rta_gw;
|
||||||
struct nlattr *rta_metrics;
|
struct nlattr *rta_metrics;
|
||||||
struct rta_mpath *rta_multipath;
|
struct rta_mpath rta_multipath;
|
||||||
uint32_t rta_expires;
|
uint32_t rta_expires;
|
||||||
uint32_t rta_oif;
|
uint32_t rta_oif;
|
||||||
uint32_t rta_expire;
|
uint32_t rta_expire;
|
||||||
|
|
|
@ -237,11 +237,11 @@ p_rtentry_netlink(struct snl_state *ss, const char *name, struct nlmsghdr *hdr)
|
||||||
if (rt.rtax_weight == 0)
|
if (rt.rtax_weight == 0)
|
||||||
rt.rtax_weight = rt_default_weight;
|
rt.rtax_weight = rt_default_weight;
|
||||||
|
|
||||||
if (rt.rta_multipath != NULL) {
|
if (rt.rta_multipath.num_nhops != 0) {
|
||||||
uint32_t orig_rtflags = rt.rta_rtflags;
|
uint32_t orig_rtflags = rt.rta_rtflags;
|
||||||
uint32_t orig_mtu = rt.rtax_mtu;
|
uint32_t orig_mtu = rt.rtax_mtu;
|
||||||
for (int i = 0; i < rt.rta_multipath->num_nhops; i++) {
|
for (uint32_t i = 0; i < rt.rta_multipath.num_nhops; i++) {
|
||||||
struct rta_mpath_nh *nhop = &rt.rta_multipath->nhops[i];
|
struct rta_mpath_nh *nhop = rt.rta_multipath.nhops[i];
|
||||||
|
|
||||||
rt.rta_gw = nhop->gw;
|
rt.rta_gw = nhop->gw;
|
||||||
rt.rta_oif = nhop->ifindex;
|
rt.rta_oif = nhop->ifindex;
|
||||||
|
|
Loading…
Reference in a new issue