1303 files changed, 32187 insertions, 57138 deletions
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index 03425fa..e28c67c 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c @@ -11,6 +11,7 @@ */ #include "ip_common.h" /* #include "libbb.h" is inside */ +#include "common_bufsiz.h" #include "rt_names.h" #include "utils.h" @@ -43,7 +44,8 @@ struct filter_t { } FIX_ALIASING; typedef struct filter_t filter_t; -#define G_filter (*(filter_t*)&bb_common_bufsiz1) +#define G_filter (*(filter_t*)bb_common_bufsiz1) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static int flush_update(void) { @@ -55,39 +57,16 @@ static int flush_update(void) return 0; } -static unsigned get_hz(void) -{ - static unsigned hz_internal; - FILE *fp; - - if (hz_internal) - return hz_internal; - - fp = fopen_for_read("/proc/net/psched"); - if (fp) { - unsigned nom, denom; - - if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2) - if (nom == 1000000) - hz_internal = denom; - fclose(fp); - } - if (!hz_internal) - hz_internal = sysconf(_SC_CLK_TCK); - return hz_internal; -} - static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, struct nlmsghdr *n, void *arg UNUSED_PARAM) { struct rtmsg *r = NLMSG_DATA(n); int len = n->nlmsg_len; struct rtattr *tb[RTA_MAX+1]; - char abuf[256]; inet_prefix dst; inet_prefix src; int host_len = -1; - SPRINT_BUF(b1); + uint32_t tid; if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) { fprintf(stderr, "Not a route: %08x %08x %08x\n", @@ -100,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) @@ -129,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; } } @@ -158,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; @@ -218,7 +203,7 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, if ((int) (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len) > G_filter.flushe) { if (flush_update()) - bb_error_msg_and_die("flush"); + xfunc_die(); } fn = (void*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp)); memcpy(fn, n, n->nlmsg_len); @@ -236,22 +221,20 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, printf("Deleted "); } if (r->rtm_type != RTN_UNICAST /* && !G_filter.type - always 0 */) { - printf("%s ", rtnl_rtntype_n2a(r->rtm_type, b1)); + printf("%s ", rtnl_rtntype_n2a(r->rtm_type)); } if (tb[RTA_DST]) { if (r->rtm_dst_len != host_len) { - printf("%s/%u ", rt_addr_n2a(r->rtm_family, - RTA_DATA(tb[RTA_DST]), - abuf, sizeof(abuf)), - r->rtm_dst_len - ); + printf("%s/%u ", + rt_addr_n2a(r->rtm_family, RTA_DATA(tb[RTA_DST])), + r->rtm_dst_len + ); } else { printf("%s ", format_host(r->rtm_family, RTA_PAYLOAD(tb[RTA_DST]), - RTA_DATA(tb[RTA_DST]), - abuf, sizeof(abuf)) - ); + RTA_DATA(tb[RTA_DST])) + ); } } else if (r->rtm_dst_len) { printf("0/%d ", r->rtm_dst_len); @@ -260,17 +243,15 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, } if (tb[RTA_SRC]) { if (r->rtm_src_len != host_len) { - printf("from %s/%u ", rt_addr_n2a(r->rtm_family, - RTA_DATA(tb[RTA_SRC]), - abuf, sizeof(abuf)), - r->rtm_src_len - ); + printf("from %s/%u ", + rt_addr_n2a(r->rtm_family, RTA_DATA(tb[RTA_SRC])), + r->rtm_src_len + ); } else { printf("from %s ", format_host(r->rtm_family, RTA_PAYLOAD(tb[RTA_SRC]), - RTA_DATA(tb[RTA_SRC]), - abuf, sizeof(abuf)) - ); + RTA_DATA(tb[RTA_SRC])) + ); } } else if (r->rtm_src_len) { printf("from 0/%u ", r->rtm_src_len); @@ -278,12 +259,16 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, if (tb[RTA_GATEWAY] && G_filter.rvia.bitlen != host_len) { printf("via %s ", format_host(r->rtm_family, RTA_PAYLOAD(tb[RTA_GATEWAY]), - RTA_DATA(tb[RTA_GATEWAY]), - abuf, sizeof(abuf))); + RTA_DATA(tb[RTA_GATEWAY])) + ); } 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 */ @@ -292,12 +277,24 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, and symbolic name will not be useful. */ printf(" src %s ", rt_addr_n2a(r->rtm_family, - RTA_DATA(tb[RTA_PREFSRC]), - abuf, sizeof(abuf))); + RTA_DATA(tb[RTA_PREFSRC]))); } if (tb[RTA_PRIORITY]) { printf(" metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY])); } + if (r->rtm_flags & RTNH_F_DEAD) { + printf("dead "); + } + if (r->rtm_flags & RTNH_F_ONLINK) { + printf("onlink "); + } + if (r->rtm_flags & RTNH_F_PERVASIVE) { + printf("pervasive "); + } + if (r->rtm_flags & RTM_F_NOTIFY) { + printf("notify "); + } + if (r->rtm_family == AF_INET6) { struct rta_cacheinfo *ci = NULL; if (tb[RTA_CACHEINFO]) { @@ -329,18 +326,20 @@ static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM, static int iproute_modify(int cmd, unsigned flags, char **argv) { static const char keywords[] ALIGN1 = - "src\0""via\0""mtu\0""lock\0""protocol\0"IF_FEATURE_IP_RULE("table\0") - "dev\0""oif\0""to\0""metric\0"; + "src\0""via\0""mtu\0""lock\0""scope\0""protocol\0"IF_FEATURE_IP_RULE("table\0") + "dev\0""oif\0""to\0""metric\0""onlink\0"; enum { ARG_src, ARG_via, ARG_mtu, PARM_lock, + ARG_scope, ARG_protocol, IF_FEATURE_IP_RULE(ARG_table,) ARG_dev, ARG_oif, ARG_to, ARG_metric, + ARG_onlink, }; enum { gw_ok = 1 << 0, @@ -359,6 +358,7 @@ IF_FEATURE_IP_RULE(ARG_table,) unsigned mxlock = 0; char *d = NULL; smalluint ok = 0; + smalluint scope_ok = 0; int arg; memset(&req, 0, sizeof(req)); @@ -367,15 +367,17 @@ IF_FEATURE_IP_RULE(ARG_table,) req.n.nlmsg_flags = NLM_F_REQUEST | flags; req.n.nlmsg_type = cmd; req.r.rtm_family = preferred_family; - if (RT_TABLE_MAIN) /* if it is zero, memset already did it */ + if (RT_TABLE_MAIN != 0) /* if it is zero, memset already did it */ req.r.rtm_table = RT_TABLE_MAIN; - if (RT_SCOPE_NOWHERE) + if (RT_SCOPE_NOWHERE != 0) req.r.rtm_scope = RT_SCOPE_NOWHERE; if (cmd != RTM_DELROUTE) { - req.r.rtm_protocol = RTPROT_BOOT; req.r.rtm_scope = RT_SCOPE_UNIVERSE; - req.r.rtm_type = RTN_UNICAST; + if (RTPROT_BOOT != 0) + req.r.rtm_protocol = RTPROT_BOOT; + if (RTN_UNICAST != 0) + req.r.rtm_type = RTN_UNICAST; } mxrta->rta_type = RTA_METRICS; @@ -408,11 +410,18 @@ IF_FEATURE_IP_RULE(ARG_table,) } mtu = get_unsigned(*argv, "mtu"); rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu); + } else if (arg == ARG_scope) { + uint32_t scope; + NEXT_ARG(); + if (rtnl_rtscope_a2n(&scope, *argv)) + invarg_1_to_2(*argv, "scope"); + req.r.rtm_scope = scope; + scope_ok = 1; } else if (arg == ARG_protocol) { uint32_t prot; NEXT_ARG(); if (rtnl_rtprot_a2n(&prot, *argv)) - invarg(*argv, "protocol"); + invarg_1_to_2(*argv, "protocol"); req.r.rtm_protocol = prot; ok |= proto_ok; #if ENABLE_FEATURE_IP_RULE @@ -420,8 +429,13 @@ IF_FEATURE_IP_RULE(ARG_table,) uint32_t tid; NEXT_ARG(); if (rtnl_rttable_a2n(&tid, *argv)) - invarg(*argv, "table"); - req.r.rtm_table = tid; + invarg_1_to_2(*argv, "table"); + 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(); @@ -431,6 +445,8 @@ IF_FEATURE_IP_RULE(ARG_table,) NEXT_ARG(); metric = get_u32(*argv, "metric"); addattr32(&req.n, sizeof(req), RTA_PRIORITY, metric); + } else if (arg == ARG_onlink) { + req.r.rtm_flags |= RTNH_F_ONLINK; } else { int type; inet_prefix dst; @@ -482,20 +498,22 @@ IF_FEATURE_IP_RULE(ARG_table,) addattr_l(&req.n, sizeof(req), RTA_METRICS, RTA_DATA(mxrta), RTA_PAYLOAD(mxrta)); } - if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT) - req.r.rtm_scope = RT_SCOPE_HOST; - else - if (req.r.rtm_type == RTN_BROADCAST - || req.r.rtm_type == RTN_MULTICAST - || req.r.rtm_type == RTN_ANYCAST - ) { - req.r.rtm_scope = RT_SCOPE_LINK; - } - else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) { - if (cmd == RTM_DELROUTE) - req.r.rtm_scope = RT_SCOPE_NOWHERE; - else if (!(ok & gw_ok)) + if (!scope_ok) { + if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT) + req.r.rtm_scope = RT_SCOPE_HOST; + else + if (req.r.rtm_type == RTN_BROADCAST + || req.r.rtm_type == RTN_MULTICAST + || req.r.rtm_type == RTN_ANYCAST + ) { req.r.rtm_scope = RT_SCOPE_LINK; + } + else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) { + if (cmd == RTM_DELROUTE) + req.r.rtm_scope = RT_SCOPE_NOWHERE; + else if (!(ok & gw_ok)) + req.r.rtm_scope = RT_SCOPE_LINK; + } } if (req.r.rtm_family == AF_UNSPEC) { @@ -604,7 +622,7 @@ static int iproute_list_or_flush(char **argv, int flush) //G_filter.protocolmask = -1; if (rtnl_rtprot_a2n(&prot, *argv)) { if (index_in_strings(keywords, *argv) != KW_all) - invarg(*argv, "protocol"); + invarg_1_to_2(*argv, "protocol"); prot = 0; //G_filter.protocolmask = 0; } @@ -629,10 +647,10 @@ static int iproute_list_or_flush(char **argv, int flush) #if ENABLE_FEATURE_IP_RULE uint32_t tid; if (rtnl_rttable_a2n(&tid, *argv)) - invarg(*argv, "table"); + invarg_1_to_2(*argv, "table"); G_filter.tb = tid; #else - invarg(*argv, "table"); + invarg_1_to_2(*argv, "table"); #endif } } else if (arg == KW_cache) { @@ -901,6 +919,8 @@ int FAST_FUNC do_iproute(char **argv) unsigned flags = 0; int cmd = RTM_NEWROUTE; + INIT_G(); + if (!*argv) return iproute_list_or_flush(argv, 0); @@ -939,7 +959,7 @@ int FAST_FUNC do_iproute(char **argv) case 11: /* flush */ return iproute_list_or_flush(argv+1, 1); default: - bb_error_msg_and_die("unknown command %s", *argv); + invarg_1_to_2(*argv, applet_name); } return iproute_modify(cmd, flags, argv+1); |