static void usage(void)
{
- fprintf(stderr, "Usage: ip mroute show [ [ to ] PREFIX ] [ from PREFIX ] [ iif DEVICE ]\n");
- fprintf(stderr, " [ table TABLE_ID ]\n");
- fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n");
+ fprintf(stderr,
+ "Usage: ip mroute show [ [ to ] PREFIX ] [ from PREFIX ] [ iif DEVICE ]\n"
+ " [ table TABLE_ID ]\n"
+ "TABLE_ID := [ local | main | default | all | NUMBER ]\n"
#if 0
- fprintf(stderr, "Usage: ip mroute [ add | del ] DESTINATION from SOURCE [ iif DEVICE ] [ oif DEVICE ]\n");
+ "Usage: ip mroute [ add | del ] DESTINATION from SOURCE [ iif DEVICE ] [ oif DEVICE ]\n"
#endif
+ );
exit(-1);
}
-struct rtfilter {
+static struct rtfilter {
int tb;
int af;
int iif;
inet_prefix msrc;
} filter;
-int print_mroute(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+int print_mroute(struct nlmsghdr *n, void *arg)
{
struct rtmsg *r = NLMSG_DATA(n);
int len = n->nlmsg_len;
struct rtattr *tb[RTA_MAX+1];
+ FILE *fp = arg;
const char *src, *dst;
SPRINT_BUF(b1);
SPRINT_BUF(b2);
print_string(PRINT_FP, NULL, "\n", NULL);
close_json_object();
+ fflush(fp);
return 0;
}
filter.iif = ifindex;
}
+static int iproute_dump_filter(struct nlmsghdr *nlh, int reqlen)
+{
+ int err;
+
+ if (filter.tb) {
+ err = addattr32(nlh, reqlen, RTA_TABLE, filter.tb);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
static int mroute_list(int argc, char **argv)
{
char *id = NULL;
- int family;
+ int family = preferred_family;
ipmroute_reset_filter(0);
- if (preferred_family == AF_UNSPEC)
- family = AF_INET;
- else
- family = AF_INET6;
- if (family == AF_INET) {
+ if (family == AF_INET || family == AF_UNSPEC) {
+ family = RTNL_FAMILY_IPMR;
filter.af = RTNL_FAMILY_IPMR;
filter.tb = RT_TABLE_DEFAULT; /* for backward compatibility */
- } else
+ } else if (family == AF_INET6) {
+ family = RTNL_FAMILY_IP6MR;
filter.af = RTNL_FAMILY_IP6MR;
+ } else {
+ /* family does not have multicast routing */
+ return 0;
+ }
filter.msrc.family = filter.mdst.family = family;
filter.iif = idx;
}
- if (rtnl_wilddump_request(&rth, filter.af, RTM_GETROUTE) < 0) {
+ if (rtnl_routedump_req(&rth, filter.af, iproute_dump_filter) < 0) {
perror("Cannot send dump request");
return 1;
}