diff mbox

[iproute2,net-next,v2,2/3] ip netconf: Show all address families by default in dumps

Message ID 1490323882-11609-3-git-send-email-dsa@cumulusnetworks.com
State Accepted, archived
Delegated to: stephen hemminger
Headers show

Commit Message

David Ahern March 24, 2017, 2:51 a.m. UTC
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 | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)
diff mbox

Patch

diff --git a/ip/ipnetconf.c b/ip/ipnetconf.c
index af539f5e945c..dc0851025223 100644
--- a/ip/ipnetconf.c
+++ b/ip/ipnetconf.c
@@ -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;