RT_TABLE_DEFAULT=253,
RT_TABLE_MAIN=254,
RT_TABLE_LOCAL=255,
- __RT_TABLE_MAX
+ RT_TABLE_MAX=0xFFFFFFFF,
};
-#define RT_TABLE_MAX (__RT_TABLE_MAX - 1)
RTA_CACHEINFO,
RTA_SESSION,
RTA_MP_ALGO,
+ RTA_TABLE,
__RTA_MAX
};
char* rtnl_rtprot_n2a(int id, char *buf, int len);
char* rtnl_rtscope_n2a(int id, char *buf, int len);
-char* rtnl_rttable_n2a(int id, char *buf, int len);
+char* rtnl_rttable_n2a(__u32 id, char *buf, int len);
char* rtnl_rtrealm_n2a(int id, char *buf, int len);
char* rtnl_dsfield_n2a(int id, char *buf, int len);
int rtnl_rtprot_a2n(__u32 *id, char *arg);
extern int do_multiroute(int argc, char **argv);
extern int do_xfrm(int argc, char **argv);
+static inline int rtm_get_table(struct rtmsg *r, struct rtattr **tb)
+{
+ __u32 table = r->rtm_table;
+ if (tb[RTA_TABLE])
+ table = *(__u32*) RTA_DATA(tb[RTA_TABLE]);
+ return table;
+}
+
extern struct rtnl_handle rth;
inet_prefix via;
int host_len = -1;
static int ip6_multiple_tables;
+ __u32 table;
SPRINT_BUF(b1);
else if (r->rtm_family == AF_IPX)
host_len = 80;
- if (r->rtm_family == AF_INET6 && r->rtm_table != RT_TABLE_MAIN)
+ parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
+ table = rtm_get_table(r, tb);
+
+ if (r->rtm_family == AF_INET6 && table != RT_TABLE_MAIN)
ip6_multiple_tables = 1;
if (r->rtm_family == AF_INET6 && !ip6_multiple_tables) {
}
}
} else {
- if (filter.tb > 0 && filter.tb != r->rtm_table)
+ if (filter.tb > 0 && filter.tb != table)
return 0;
}
if ((filter.protocol^r->rtm_protocol)&filter.protocolmask)
if (filter.rprefsrc.family && r->rtm_family != filter.rprefsrc.family)
return 0;
- parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
-
memset(&dst, 0, sizeof(dst));
dst.family = r->rtm_family;
if (tb[RTA_DST])
fprintf(fp, "dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF])));
if (!(r->rtm_flags&RTM_F_CLONED)) {
- if (r->rtm_table != RT_TABLE_MAIN && !filter.tb)
- fprintf(fp, " table %s ", rtnl_rttable_n2a(r->rtm_table, b1, sizeof(b1)));
+ if (table != RT_TABLE_MAIN && !filter.tb)
+ fprintf(fp, " table %s ", rtnl_rttable_n2a(table, b1, sizeof(b1)));
if (r->rtm_protocol != RTPROT_BOOT && filter.protocolmask != -1)
fprintf(fp, " proto %s ", rtnl_rtprot_n2a(r->rtm_protocol, b1, sizeof(b1)));
if (r->rtm_scope != RT_SCOPE_UNIVERSE && filter.scopemask != -1)
NEXT_ARG();
if (rtnl_rttable_a2n(&tid, *argv))
invarg("\"table\" value is invalid\n", *argv);
- req.r.rtm_table = tid;
+ if (tid < 256)
+ req.r.rtm_table = tid;
+ else {
+ req.r.rtm_table = RT_TABLE_UNSPEC;
+ addattr32(&req.n, sizeof(req), RTA_TABLE, tid);
+ }
table_ok = 1;
} else if (strcmp(*argv, "dev") == 0 ||
strcmp(*argv, "oif") == 0) {
#include "rt_names.h"
#include "utils.h"
+#include "ip_common.h"
extern struct rtnl_handle rth;
struct rtmsg *r = NLMSG_DATA(n);
int len = n->nlmsg_len;
int host_len = -1;
+ __u32 table;
struct rtattr * tb[RTA_MAX+1];
char abuf[256];
SPRINT_BUF(b1);
fprintf(fp, "iif %s ", (char*)RTA_DATA(tb[RTA_IIF]));
}
- if (r->rtm_table)
- fprintf(fp, "lookup %s ", rtnl_rttable_n2a(r->rtm_table, b1, sizeof(b1)));
+ table = rtm_get_table(r, tb);
+ if (table)
+ fprintf(fp, "lookup %s ", rtnl_rttable_n2a(table, b1, sizeof(b1)));
if (tb[RTA_FLOW]) {
__u32 to = *(__u32*)RTA_DATA(tb[RTA_FLOW]);
NEXT_ARG();
if (rtnl_rttable_a2n(&tid, *argv))
invarg("invalid table ID\n", *argv);
- req.r.rtm_table = tid;
+ if (tid < 256)
+ req.r.rtm_table = tid;
+ else {
+ req.r.rtm_table = RT_TABLE_UNSPEC;
+ addattr32(&req.n, sizeof(req), RTA_TABLE, tid);
+ }
table_ok = 1;
} else if (strcmp(*argv, "dev") == 0 ||
strcmp(*argv, "iif") == 0) {
rtnl_rttable_hash, 256);
}
-char * rtnl_rttable_n2a(int id, char *buf, int len)
+char * rtnl_rttable_n2a(__u32 id, char *buf, int len)
{
struct rtnl_hash_entry *entry;
static unsigned long res;
struct rtnl_hash_entry *entry;
char *end;
- int i;
+ __u32 i;
if (cache && strcmp(cache, arg) == 0) {
*id = res;