summaryrefslogtreecommitdiff
authorLukasz Nowak <lnowak@tycoint.com>2016-12-13 12:58:31 (GMT)
committer Denys Vlasenko <vda.linux@googlemail.com>2016-12-18 17:56:49 (GMT)
commitb42107f21538e39d9a344376372f8261aed589b2 (patch)
tree34f0f4e836067be6c19a931e16d661eb47db162a
parente184a883567ee3fd735644416e4bd683f1894ac5 (diff)
downloadbusybox-b42107f21538e39d9a344376372f8261aed589b2.zip
busybox-b42107f21538e39d9a344376372f8261aed589b2.tar.gz
busybox-b42107f21538e39d9a344376372f8261aed589b2.tar.bz2
libiproute: handle table ids larger than 255
Linux kernel, starting from 2.6.19 allows ip table ids to have 32-bit values. In order to preserve compatibility, the old 8-bit field: rtm_table is still in use when table id is lower than 256. Add support for the 32-bit table id (RTA_TABLE attribute) in: - ip route print - ip route modify - ip rule print - ip rule modify Add printing of table ids to ip route. Changes are compatible with the mainline iproute2 utilities. These changes are required for compatibility with ConnMan, which by default uses table ids greater than 255. function old new delta print_route 1588 1637 +49 do_iproute 2187 2222 +35 do_iprule 955 987 +32 print_rule 617 630 +13 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/0 up/down: 129/0) Total: 129 bytes Signed-off-by: Lukasz Nowak <lnowak@tycoint.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat
-rw-r--r--networking/libiproute/iproute.c24
-rw-r--r--networking/libiproute/iprule.c11
2 files changed, 29 insertions, 6 deletions
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index 48dc6e3..0f2b896 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -66,6 +66,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
inet_prefix dst;
inet_prefix src;
int host_len = -1;
+ uint32_t tid;
if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) {
fprintf(stderr, "Not a route: %08x %08x %08x\n",
@@ -78,6 +79,14 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
if (len < 0)
bb_error_msg_and_die("wrong nlmsg len %d", len);
+ memset(tb, 0, sizeof(tb));
+ parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
+
+ if (tb[RTA_TABLE])
+ tid = *(uint32_t *)RTA_DATA(tb[RTA_TABLE]);
+ else
+ tid = r->rtm_table;
+
if (r->rtm_family == AF_INET6)
host_len = 128;
else if (r->rtm_family == AF_INET)
@@ -107,7 +116,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
}
}
} else {
- if (G_filter.tb > 0 && G_filter.tb != r->rtm_table) {
+ if (G_filter.tb > 0 && G_filter.tb != tid) {
return 0;
}
}
@@ -136,10 +145,8 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
return 0;
}
- memset(tb, 0, sizeof(tb));
memset(&src, 0, sizeof(src));
memset(&dst, 0, sizeof(dst));
- parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
if (tb[RTA_SRC]) {
src.bitlen = r->rtm_src_len;
@@ -258,6 +265,10 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
if (tb[RTA_OIF]) {
printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF])));
}
+#if ENABLE_FEATURE_IP_RULE
+ if (tid && tid != RT_TABLE_MAIN && !G_filter.tb)
+ printf("table %s ", rtnl_rttable_n2a(tid));
+#endif
/* Todo: parse & show "proto kernel", "scope link" here */
@@ -419,7 +430,12 @@ IF_FEATURE_IP_RULE(ARG_table,)
NEXT_ARG();
if (rtnl_rttable_a2n(&tid, *argv))
invarg_1_to_2(*argv, "table");
- 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);
+ }
#endif
} else if (arg == ARG_dev || arg == ARG_oif) {
NEXT_ARG();
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c
index c486834..8f3f862 100644
--- a/networking/libiproute/iprule.c
+++ b/networking/libiproute/iprule.c
@@ -114,7 +114,9 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM,
printf("iif %s ", (char*)RTA_DATA(tb[RTA_IIF]));
}
- if (r->rtm_table)
+ if (tb[RTA_TABLE])
+ printf("lookup %s ", rtnl_rttable_n2a(*(uint32_t*)RTA_DATA(tb[RTA_TABLE])));
+ else if (r->rtm_table)
printf("lookup %s ", rtnl_rttable_n2a(r->rtm_table));
if (tb[RTA_FLOW]) {
@@ -256,7 +258,12 @@ static int iprule_modify(int cmd, char **argv)
NEXT_ARG();
if (rtnl_rttable_a2n(&tid, *argv))
invarg_1_to_2(*argv, "table ID");
- 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 (key == ARG_dev ||
key == ARG_iif