diff --git a/include/utils.h b/include/utils.h index 82f1aa7d..1b4f939c 100644 --- a/include/utils.h +++ b/include/utils.h @@ -249,5 +249,6 @@ int do_each_netns(int (*func)(char *nsname, void *arg), void *arg, char *int_to_str(int val, char *buf); int get_guid(__u64 *guid, const char *arg); +int get_real_family(int rtm_type, int rtm_family); #endif /* __UTILS_H__ */ diff --git a/ip/ipmroute.c b/ip/ipmroute.c index 5d6922a2..133367a2 100644 --- a/ip/ipmroute.c +++ b/ip/ipmroute.c @@ -112,7 +112,7 @@ int print_mroute(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) return 0; } - family = r->rtm_family == RTNL_FAMILY_IPMR ? AF_INET : AF_INET6; + family = get_real_family(r->rtm_type, r->rtm_family); if (n->nlmsg_type == RTM_DELROUTE) fprintf(fp, "Deleted "); diff --git a/ip/iproute.c b/ip/iproute.c index 4d7da023..0bc01368 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -311,7 +311,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) struct rtmsg *r = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[RTA_MAX+1]; - int host_len; + int host_len, family; __u32 table; SPRINT_BUF(b1); @@ -363,13 +363,14 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) fprintf(fp, "%s ", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1))); if (tb[RTA_DST]) { + family = get_real_family(r->rtm_type, r->rtm_family); if (r->rtm_dst_len != host_len) { fprintf(fp, "%s/%u ", - rt_addr_n2a_rta(r->rtm_family, tb[RTA_DST]), + rt_addr_n2a_rta(family, tb[RTA_DST]), r->rtm_dst_len); } else { fprintf(fp, "%s ", - format_host_rta(r->rtm_family, tb[RTA_DST])); + format_host_rta(family, tb[RTA_DST])); } } else if (r->rtm_dst_len) { fprintf(fp, "0/%d ", r->rtm_dst_len); @@ -377,13 +378,14 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) fprintf(fp, "default "); } if (tb[RTA_SRC]) { + family = get_real_family(r->rtm_type, r->rtm_family); if (r->rtm_src_len != host_len) { fprintf(fp, "from %s/%u ", - rt_addr_n2a_rta(r->rtm_family, tb[RTA_SRC]), + rt_addr_n2a_rta(family, tb[RTA_SRC]), r->rtm_src_len); } else { fprintf(fp, "from %s ", - format_host_rta(r->rtm_family, tb[RTA_SRC])); + format_host_rta(family, tb[RTA_SRC])); } } else if (r->rtm_src_len) { fprintf(fp, "from 0/%u ", r->rtm_src_len); diff --git a/lib/utils.c b/lib/utils.c index 96604746..9ada7737 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -1156,3 +1156,12 @@ int get_guid(__u64 *guid, const char *arg) return 0; } + +/* This is a necessary workaround for multicast route dumps */ +int get_real_family(int rtm_type, int rtm_family) +{ + if (rtm_type != RTN_MULTICAST) + return rtm_family; + + return rtm_family == RTNL_FAMILY_IPMR ? AF_INET : AF_INET6; +}