]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
ip netconf: Show all address families by default in dumps
authorDavid Ahern <dsa@cumulusnetworks.com>
Fri, 24 Mar 2017 02:51:21 +0000 (19:51 -0700)
committerStephen Hemminger <stephen@networkplumber.org>
Fri, 14 Apr 2017 23:00:15 +0000 (16:00 -0700)
Currently, 'ip netconf' only shows ipv4 and ipv6 netconf settings. If IPv6
is not enabled, the dump ends with
    RTNETLINK answers: Operation not supported

when IPv6 request is attempted. Further, if the mpls_router module is also
loaded a separate request is needed to get MPLS settings.

To make this better going forward, use the new PF_UNSPEC dump all option
if the kernel supports it. If the kernel does not, it sets NLMSG_ERROR and
returns EOPNOTSUPP which is trapped and we fall back to the existing output
to maintain compatibility with existing kernels.

Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
ip/ipnetconf.c

index af539f5e945c0bf84a79b3d31c5ac2bf9145731b..dc0851025223f957f2dcd29d4ce86a31058b0513 100644 (file)
@@ -19,6 +19,7 @@
 #include <sys/time.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
+#include <errno.h>
 
 #include "rt_names.h"
 #include "utils.h"
@@ -197,16 +198,26 @@ static int do_show(int argc, char **argv)
                }
                rtnl_listen(&rth, print_netconf, stdout);
        } else {
+               rth.flags = RTNL_HANDLE_F_SUPPRESS_NLERR;
 dump:
                if (rtnl_wilddump_request(&rth, filter.family, RTM_GETNETCONF) < 0) {
                        perror("Cannot send dump request");
                        exit(1);
                }
                if (rtnl_dump_filter(&rth, print_netconf2, stdout) < 0) {
+                       /* kernel does not support netconf dump on AF_UNSPEC;
+                        * fall back to requesting by family
+                        */
+                       if (errno == EOPNOTSUPP &&
+                           filter.family == AF_UNSPEC) {
+                               filter.family = AF_INET;
+                               goto dump;
+                       }
+                       perror("RTNETLINK answers");
                        fprintf(stderr, "Dump terminated\n");
                        exit(1);
                }
-               if (preferred_family == AF_UNSPEC) {
+               if (preferred_family == AF_UNSPEC && filter.family == AF_INET) {
                        preferred_family = AF_INET6;
                        filter.family = AF_INET6;
                        goto dump;