summaryrefslogtreecommitdiffstats
path: root/lib/route/link.c
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2014-11-26 17:17:16 (GMT)
committerThomas Haller <thaller@redhat.com>2014-11-27 09:34:57 (GMT)
commitb54775d3169b56d9c0aee47d6937b0358a5443e0 (patch)
treec50289c17a86575fe9cbafb87e278608ca137cef /lib/route/link.c
parent8b023fd441c3fd96aad2acca31d2702b1aa1f21e (diff)
downloadlibnl-b54775d3169b56d9c0aee47d6937b0358a5443e0.zip
libnl-b54775d3169b56d9c0aee47d6937b0358a5443e0.tar.gz
libnl-b54775d3169b56d9c0aee47d6937b0358a5443e0.tar.bz2
route/link: return -NLE_OPNOTSUPP in rtnl_link_get_kernel() for old kernels
Older kernels without patch a3d1289126e7b14307074b76bf1677015ea5036f do not support rtnl_getlink() by ifname. Detect this situation and fail with -NLE_OPNOTSUPP instead of -NLE_INVAL. This changes behavior in returning a different error code for this case. Acked-by: Thomas Graf <tgraf@suug.ch> Signed-off-by: Thomas Haller <thaller@redhat.com>
Diffstat (limited to 'lib/route/link.c')
-rw-r--r--lib/route/link.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/lib/route/link.c b/lib/route/link.c
index 7a53532..0b3238f 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -1160,6 +1160,11 @@ nla_put_failure:
* pointer or -NLE_OBJ_NOTFOUND is returned if no matching link was
* found.
*
+ * Older kernels do not support lookup by name. In that case, libnl
+ * will fail with -NLE_OPNOTSUPP. Note that previous version of libnl
+ * failed in this case with -NLE_INVAL. You can check libnl behavior
+ * using NL_CAPABILITY_ROUTE_LINK_GET_KERNEL_FAIL_OPNOTSUPP capability.
+ *
* @route_doc{link_direct_lookup, Lookup Single Link (Direct Lookup)}
* @return 0 on success or a negative error code.
*/
@@ -1169,6 +1174,7 @@ int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name,
struct nl_msg *msg = NULL;
struct nl_object *obj;
int err;
+ int syserr;
if ((err = rtnl_link_build_get_request(ifindex, name, &msg)) < 0)
return err;
@@ -1178,8 +1184,18 @@ int rtnl_link_get_kernel(struct nl_sock *sk, int ifindex, const char *name,
if (err < 0)
return err;
- if ((err = nl_pickup(sk, link_msg_parser, &obj)) < 0)
+ if ((err = nl_pickup_keep_syserr(sk, link_msg_parser, &obj, &syserr)) < 0) {
+ if (syserr == -EINVAL &&
+ ifindex <= 0 &&
+ name && *name) {
+ /* Older kernels do not support lookup by ifname. This was added
+ * by commit kernel a3d1289126e7b14307074b76bf1677015ea5036f .
+ * Detect this error case and return NLE_OPNOTSUPP instead of
+ * NLE_INVAL. */
+ return -NLE_OPNOTSUPP;
+ }
return err;
+ }
/* We have used link_msg_parser(), object is definitely a link */
*result = (struct rtnl_link *) obj;