rtnl_route_build_msg() should allow the user to set the route scope
explicitly to RT_SCOPE_NOWHERE.
This is useful for IPv4 routes, because when deleting a route,
the kernel requires the scope to match, unless the scope is set to
RT_SCOPE_NOWHERE. Thus by setting the scope to RT_SCOPE_NOWHERE,
the user can delete a route, even without knowing its scope.
rtnl_route_build_msg() should only try to guess the scope, if it was
not explicitly specified.
Signed-off-by: Thomas Haller <thaller@redhat.com>
Acked-by: Thomas Graf <tgraf@suug.ch>
The kernel allows multiple entries in the main table which differ in the
priority value. In libnl currently, since priority is not part of the base
netlink route message, it is not used as part of the key. This patch
includes priority in the key/oo_id_attrs and defaults the value to zero
for messages where priority is not included.
One point to note is that the actual selection of route from multiple
options is done implicitly in the kernel by storing the routes in sort
priority order, but there is no explicit communication to a client of libnl
of that.
Signed-off-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
There are two ways kernel handles ipv6 equal cost multipath routes
depending on which kernel version you are looking at.
older kernels without ipv6 ECMP support, accept the below ECMP routes,
#ip -6 route add 2001::/16 nexthop via fe80:2::2 dev swp1
#ip -6 route add 2001::/16 nexthop via fe80:2::3 dev swp1
store them as separate routes and pick the last one during lookup.
Newer kernels, after the support for equal cost multipath routes
was added http://patchwork.ozlabs.org/patch/188562/,
now accept multipath routes added individually using the
above 'ip -6 route' format OR
sent using RTA_MULTIPATH with the below command
#ip -6 route add 2001::/16 nexthop via fe80:2::2 dev swp1 nexthop via fe80:2::3 dev swp1
And the kernel now stores and treats them as equal cost multipath routes
during lookups.
However in all cases above, netlink notifications to ipv6 ECMP route adds and deletes
come separately for each next hop.
Example libnl notification in the above case with both old and new kernels:
inet6 2001::/16 table main type unicast
scope global priority 0x400 protocol boot
nexthop via fe80:2::2 dev swp1
inet6 2001::/16 table main type unicast
scope global priority 0x400 protocol boot
nexthop via fe80:2::3 dev swp1
Since they are separate route notifications for objects with same key,
libnl replaces the existing ones and hence only the last route update sticks.
This patch uses the oo_update feature to not replace but update an
existing route if its a ipv6 equal cost multipath route.
The object after an update looks like the below (similar to ipv4 ECMP routes):
inet6 2001::/16 table main type unicast
scope global priority 0x400 protocol boot
nexthop via fe80:2::2 dev swp1
nexthop via fe80:2::3 dev swp1
Signed-off-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
Reviewed-by: Nolan Leake <nolan@cumulusnetworks.com>
Reviewed-by: Wilson Kok <wkok@cumulusnetworks.com>
Signed-off-by: Thomas Graf <tgraf@suug.ch>
This makes runtime removal of cache operations possible if non-safe
API is not in use by application. The non-safe API will be removed
in the next major version.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
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.
1. Fix some places where unsigned value compared < 0
2. Fix obsolete %Z specifier to more portable %z
3. Some erroneous types substitution
4. nl_msec2str() - 64-bit msec is now properly used,
Only safe changes. I mean int <--> uint32_t and signed/unsigned fixes.
Some functinos require size_t argument instead of int, but changes of
signatures of that functions is terrible thing.
Also, I do not pretend for a full list of fixes.
Just to shut up clang -Wall -Wextra
One more thing. ifindex. I don't change that because changes will
be too big for simple fix.
I found a small bug in libnl, about extended table id ( above 256 ).
Signed-off-by: Romary Sonrier <romary@sonrier.com>
Signed-off-by: Thomas Graf <tgraf@redhat.com>
Only use the MULTIPATH attribute when adding routes with more than one
next hop.
This solves issues with two scenarios:
1. Adding an IPv4 route to a kernel configured without
CONFIG_IP_ROUTE_MULTIPATH=y.
2. Adding an IPv6 route in general, since the MULTIPATH attribute is not
supported there.
Signed-off-by: Michael Altizer <xiche@verizon.net>
Dumping objects as environment variables has never been implemented
completely and only increases the size of the library for no real
purpose. Integration into scripts is better achieved by implementing
a python module anyway.
don't try to give the kernel an empty RTA_DST attribute. this would
previously happening on trying to delete the default route as returned
from the kernel. the kernel doesn't add a RTA_DST atttribute, so libnl
does nl_addr_alloc(0) and inserts a zero-length RTA_DST attribute into
the deletion request, which the kernel then refuses with ERANGE.
Signed-off-by: David Lamparter <equinox@diac24.net>
Replaces obsolete calls to nla_get_addr() and nla_get_data()
with nl_addr_alloc_attr() respectively nl_data_alloc_attr().
Also fixes missing error handling while parsing routing multipath
configuration.
In order for the interface to become more thread safe, the error
handling was revised to no longer depend on a static errno and
error string buffer.
This patch converts all error paths to return a libnl specific
error code which can be translated to a error message using
nl_geterror(int error). The functions nl_error() and
nl_get_errno() are therefore obsolete.
This change required various sets of function prototypes to be
changed in order to return an error code, the most prominent
are:
struct nl_cache *foo_alloc_cache(...);
changed to:
int foo_alloc_cache(..., struct nl_cache **);
struct nl_msg *foo_build_request(...);
changed to:
int foo_build_request(..., struct nl_msg **);
struct foo *foo_parse(...);
changed to:
int foo_parse(..., struct foo **);
This pretty much only leaves trivial allocation functions to
still return a pointer object which can still return NULL to
signal out of memory.
This change is a serious API and ABI breaker, sorry!
Added rtnl_route_foreach_nexthop() to walk the list of nexthops invoking a
caller-provided callback for each nexthop entry, and added rtnl_route_nexthop_n()
to retrieve the Nth nexthop entry in the list.
Using rtnl_route_get_metric() for route comparison became a bottleneck
because each metric which was not available resulted in the generation
of an error message. This changeset avoids this by accessing rt_metrics
and rt_metrics_mask directly while comparing route objects.
Adds all missing routing attributes and brings the routing
related code to a working state. In the process the API
was broken several times with the justification that nobody
is using this code yet.
The changes include new example code which is also a prototype
for how plain CLI tools could look like to control routes.
So far the destination address for default routes was NULL
which complicated the handling of routes in general. By
assigning a address of length zero they can be compared
to each other.
This allows the cache manager to properly handle default
routes.