]> git.ipfire.org Git - thirdparty/libnl.git/commitdiff
route/link: return -NLE_OPNOTSUPP in rtnl_link_get_kernel() for old kernels
authorThomas Haller <thaller@redhat.com>
Wed, 26 Nov 2014 17:17:16 +0000 (18:17 +0100)
committerThomas Haller <thaller@redhat.com>
Thu, 27 Nov 2014 09:34:57 +0000 (10:34 +0100)
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>
include/netlink/utils.h
lib/route/link.c
lib/utils.c

index 6b4b7874e3eaa9e3aa0e9973d31087d4b6bab004..431502f0ce6fa3b4d23375bf7d8b5fb739ca3589 100644 (file)
@@ -113,6 +113,14 @@ enum {
        NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE = 4,
 #define NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE NL_CAPABILITY_NL_CONNECT_RETRY_GENERATE_PORT_ON_ADDRINUSE
 
+       /**
+        * Indicate that rtnl_link_get_kernel() fails with -NLE_OPNOTSUPP in case
+        * of older kernals not supporting lookup by ifname. This changes behavior
+        * from returning -NLE_INVAL to return -NLE_OPNOTSUPP.
+        */
+       NL_CAPABILITY_ROUTE_LINK_GET_KERNEL_FAIL_OPNOTSUPP = 5,
+#define NL_CAPABILITY_ROUTE_LINK_GET_KERNEL_FAIL_OPNOTSUPP NL_CAPABILITY_ROUTE_LINK_GET_KERNEL_FAIL_OPNOTSUPP
+
        __NL_CAPABILITY_MAX
 #define NL_CAPABILITY_MAX                               (__NL_CAPABILITY_MAX - 1)
 };
index 7a53532b23c34386e1a822193f5172c7f06c1565..0b3238f82783103f95febdf6e4b87b254e22cc64 100644 (file)
@@ -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;
index 67612bd763e39909beb14b9b0c4930a67db7b365..795eeb780e11765010a9330a98fee8454846c000 100644 (file)
@@ -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),