summaryrefslogtreecommitdiffstats
path: root/lib/route
diff options
context:
space:
mode:
authorJustin Mayfield <jmayfield@cradlepoint.com>2012-08-17 01:03:48 (GMT)
committerThomas Graf <tgraf@redhat.com>2012-08-29 10:27:06 (GMT)
commitb62e019afad652748bcda0205f96611640bcd6d5 (patch)
tree1659076186c661f5c003360780bb0575f44df13c /lib/route
parentde28daf2269a5c7d55e6f1f50f1c1eff4db27a15 (diff)
downloadlibnl-b62e019afad652748bcda0205f96611640bcd6d5.zip
libnl-b62e019afad652748bcda0205f96611640bcd6d5.tar.gz
libnl-b62e019afad652748bcda0205f96611640bcd6d5.tar.bz2
single nexthop flags bug
I ran into a bug today related to how Linux handles a route's nexthop flags when there is just one nexthop. Namely Linux expects the flags to be OR'd into the rtm_flags field when there is only one nexthop and so rtnl_route_build_msg needs to check the number of nexthops and store the nexthops flags into this field prior to calling nlmsg_append(...&rtmsg). Conversely the rtnl_route_parse function needs to pull these lower 0xff bits when a single nexthop is detected. Attached is my patch. I don't like the slight duplication of doing the rtnl_route_get_nnexthops check twice but it seemed to be the least turmoil of any solution I thought of.
Diffstat (limited to 'lib/route')
-rw-r--r--lib/route/route_obj.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/lib/route/route_obj.c b/lib/route/route_obj.c
index 62669a9..7ea4fff 100644
--- a/lib/route/route_obj.c
+++ b/lib/route/route_obj.c
@@ -986,6 +986,7 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
}
if (old_nh) {
+ rtnl_route_nh_set_flags(old_nh, rtm->rtm_flags & 0xff);
if (route->rt_nr_nh == 0) {
/* If no nexthops have been provided via RTA_MULTIPATH
* we add it as regular nexthop to maintain backwards
@@ -1045,10 +1046,15 @@ int rtnl_route_build_msg(struct nl_msg *msg, struct rtnl_route *route)
if (route->rt_src)
rtmsg.rtm_src_len = nl_addr_get_prefixlen(route->rt_src);
-
if (rtmsg.rtm_scope == RT_SCOPE_NOWHERE)
rtmsg.rtm_scope = rtnl_route_guess_scope(route);
+ if (rtnl_route_get_nnexthops(route) == 1) {
+ struct rtnl_nexthop *nh;
+ nh = rtnl_route_nexthop_n(route, 0);
+ rtmsg.rtm_flags |= nh->rtnh_flags;
+ }
+
if (nlmsg_append(msg, &rtmsg, sizeof(rtmsg), NLMSG_ALIGNTO) < 0)
goto nla_put_failure;