Bug 9141 - ip: RTNETLINK answers: Invalid argument
Summary: ip: RTNETLINK answers: Invalid argument
Status: RESOLVED FIXED
Alias: None
Product: Busybox
Classification: Unclassified
Component: Networking (show other bugs)
Version: unspecified
Hardware: All Linux
: P5 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-08-06 03:59 UTC by Neil MacLeod
Modified: 2016-08-16 13:29 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:


Attachments
OpenVPN working log (3.33 KB, text/plain)
2016-08-06 03:59 UTC, Neil MacLeod
Details
OpenVPN not working log (3.91 KB, text/plain)
2016-08-06 03:59 UTC, Neil MacLeod
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Neil MacLeod 2016-08-06 03:59:07 UTC
Created attachment 6581 [details]
OpenVPN working log

https://git.busybox.net/busybox/commit/?id=ce4bc1ed048233e89ee4cb95830bf6f01d523d1e

Prior to the above commit, the following OpenVPN network changes are working:

/sbin/ip route add 212.129.33.61/32 via 192.168.0.1
/sbin/ip route add 0.0.0.0/1 via 10.12.0.153
/sbin/ip route add 128.0.0.0/1 via 10.12.0.153
/sbin/ip route add 10.12.0.1/32 via 10.12.0.153

(full log attached - working.txt)

However after the commit, which fixes https://bugs.busybox.net/show_bug.cgi?id=8561, they no longer work:

/sbin/ip route add 212.129.33.61/32 via 192.168.0.1
ip: RTNETLINK answers: Invalid argument
/sbin/ip route add 0.0.0.0/1 via 10.12.0.109
ip: RTNETLINK answers: Invalid argument
/sbin/ip route add 128.0.0.0/1 via 10.12.0.109
ip: RTNETLINK answers: Invalid argument
/sbin/ip route add 10.12.0.1/32 via 10.12.0.109
ip: RTNETLINK answers: Invalid argument

(full log attached - notworking.txt)

As a result, OpenVPN is not working with Busybox 1.25.0, but is working with 1.24.2.
Comment 1 Neil MacLeod 2016-08-06 03:59:47 UTC
Created attachment 6586 [details]
OpenVPN not working log
Comment 2 Neil MacLeod 2016-08-06 17:37:15 UTC
The problem seems to be this part of the change:

https://github.com/mirror/busybox/commit/ce4bc1ed048233e89ee4cb95830bf6f01d523d1e#diff-17b20e94edc19bc0556a07b3f860041eR365

+		if (RT_SCOPE_UNIVERSE != 0)
+			req.r.rtm_scope = RT_SCOPE_UNIVERSE;

On Linux, RT_SCOPE_UNIVERSE is 0 so req.r.rtm_scope is never assigned a usable value unless it comes from the command line (ie. "scope 0"). If req.r.rtm_scope is not assigned a value then a default value of 255 (RT_SCOPE_NOWHERE) is used.

Remove the "if" condition so that req.r.rtm_scope is set unconditionally and the problems reported in this bug are resolved.

If the "scope 0" argument is added on the command line then there is also no problem, however third party programs such as OpenVPN don't supply the scope argument so they fail with Busybox 1.25.0.

Presumably the default scope should be "scope 0" but that's not working after this change, and "scope #" is now mandatory which is a major break in terms of compatibility.
Comment 3 Neil MacLeod 2016-08-06 18:10:51 UTC
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index e674e9a..8d83b1f 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -364,7 +364,7 @@ IF_FEATURE_IP_RULE(ARG_table,)
        if (cmd != RTM_DELROUTE) {
                if (RTPROT_BOOT != 0)
                        req.r.rtm_protocol = RTPROT_BOOT;
-               if (RT_SCOPE_UNIVERSE != 0)
+               if (RT_SCOPE_UNIVERSE != 0 || req.r.rtm_scope == RT_SCOPE_NOWHERE)
                        req.r.rtm_scope = RT_SCOPE_UNIVERSE;
                if (RTN_UNICAST != 0)
                        req.r.rtm_type = RTN_UNICAST;

also works fine.
Comment 4 Neil MacLeod 2016-08-06 18:21:35 UTC
Alternatively the problem might here:

https://github.com/mirror/busybox/commit/ce4bc1ed048233e89ee4cb95830bf6f01d523d1e#diff-17b20e94edc19bc0556a07b3f860041eR484

Using the example "route add" commands, in the "if (!scope_ok) {" block req.r.rtm_type is RTN_UNICAST while req.r.rtm_scope is RT_SCOPE_NOWHERE, which means the code falls through to https://github.com/mirror/busybox/commit/ce4bc1ed048233e89ee4cb95830bf6f01d523d1e#diff-17b20e94edc19bc0556a07b3f860041eR497 which fails as "(!(ok & gw_ok))" is not true, so req.r.rtm_scope remains set to RT_SCOPE_NOWHERE.

The following patch works for me, I've but no idea if this is what is needed for others.

diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index e674e9a..42f8bda 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -498,6 +498,8 @@ IF_FEATURE_IP_RULE(ARG_table,)
                                req.r.rtm_scope = RT_SCOPE_NOWHERE;
                        else if (!(ok & gw_ok))
                                req.r.rtm_scope = RT_SCOPE_LINK;
+                       else
+                               req.r.rtm_scope = RT_SCOPE_UNIVERSE;
                }
        }
Comment 5 Denys Vlasenko 2016-08-16 13:29:40 UTC
Fixed in git.