diff options
author | Thomas Haller <thaller@redhat.com> | 2014-11-26 17:17:16 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2014-11-27 09:34:57 (GMT) |
commit | b54775d3169b56d9c0aee47d6937b0358a5443e0 (patch) | |
tree | c50289c17a86575fe9cbafb87e278608ca137cef /lib | |
parent | 8b023fd441c3fd96aad2acca31d2702b1aa1f21e (diff) | |
download | libnl-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')
-rw-r--r-- | lib/route/link.c | 18 | ||||
-rw-r--r-- | lib/utils.c | 2 |
2 files changed, 18 insertions, 2 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; diff --git a/lib/utils.c b/lib/utils.c index 67612bd..795eeb7 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -1148,7 +1148,7 @@ int nl_has_capability (int capability) NL_CAPABILITY_ROUTE_LINK_VETH_GET_PEER_OWN_REFERENCE, NL_CAPABILITY_ROUTE_LINK_CLS_ADD_ACT_OWN_REFERENCE, NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE, - 0, + NL_CAPABILITY_ROUTE_LINK_GET_KERNEL_FAIL_OPNOTSUPP, 0, 0, 0), |