diff options
-rw-r--r-- | networking/libiproute/iproute.c | 143 | ||||
-rw-r--r-- | networking/libiproute/utils.c | 2 | ||||
-rw-r--r-- | networking/libiproute/utils.h | 2 |
3 files changed, 84 insertions, 63 deletions
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c index e7ad7d9c4..d5d9c1cfc 100644 --- a/networking/libiproute/iproute.c +++ b/networking/libiproute/iproute.c @@ -306,10 +306,23 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) struct rtattr * mxrta = (void*)mxbuf; unsigned mxlock = 0; char *d = NULL; - int gw_ok = 0; - int dst_ok = 0; - int proto_ok = 0; - int type_ok = 0; + enum { gw_ok = 1<<0, dst_ok = 1<<1, proto_ok = 1<<2, type_ok = 1<<3}; + smalluint ok = 0; + static const char * const keywords[] = { + "src", "via", "mtu", "lock", "protocol", "table", "dev", "oif", "to", + NULL + }; + enum { + ARG_src, + ARG_via, + ARG_mtu, PARM_lock, + ARG_protocol, + ARG_table, + ARG_dev, + ARG_oif, + ARG_to + }; + int arg; memset(&req, 0, sizeof(req)); @@ -330,69 +343,64 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) mxrta->rta_len = RTA_LENGTH(0); while (argc > 0) { - if (strcmp(*argv, "src") == 0) { + arg = index_in_substr_array(keywords, *argv); + if (arg == ARG_src) { inet_prefix addr; NEXT_ARG(); get_addr(&addr, *argv, req.r.rtm_family); - if (req.r.rtm_family == AF_UNSPEC) { + if (req.r.rtm_family == AF_UNSPEC) req.r.rtm_family = addr.family; - } addattr_l(&req.n, sizeof(req), RTA_PREFSRC, &addr.data, addr.bytelen); - } else if (strcmp(*argv, "via") == 0) { + } else if (arg == ARG_via) { inet_prefix addr; - gw_ok = 1; + ok |= gw_ok; NEXT_ARG(); get_addr(&addr, *argv, req.r.rtm_family); if (req.r.rtm_family == AF_UNSPEC) { req.r.rtm_family = addr.family; } addattr_l(&req.n, sizeof(req), RTA_GATEWAY, &addr.data, addr.bytelen); - } else if (strcmp(*argv, "mtu") == 0) { + } else if (arg == ARG_mtu) { unsigned mtu; NEXT_ARG(); - if (strcmp(*argv, "lock") == 0) { + if (index_in_str_array(keywords, *argv) == PARM_lock) { mxlock |= (1<<RTAX_MTU); NEXT_ARG(); } - if (get_unsigned(&mtu, *argv, 0)) { + if (get_unsigned(&mtu, *argv, 0)) invarg(*argv, "mtu"); - } rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu); - } else if (matches(*argv, "protocol") == 0) { + } else if (arg == ARG_protocol) { uint32_t prot; NEXT_ARG(); if (rtnl_rtprot_a2n(&prot, *argv)) invarg(*argv, "protocol"); req.r.rtm_protocol = prot; - proto_ok =1; -#if ENABLE_FEATURE_IP_RULE - } else if (matches(*argv, "table") == 0) { + ok |= proto_ok; + } else if (arg == ARG_table) { uint32_t tid; NEXT_ARG(); if (rtnl_rttable_a2n(&tid, *argv)) invarg(*argv, "table"); req.r.rtm_table = tid; -#endif - } else if (strcmp(*argv, "dev") == 0 || - strcmp(*argv, "oif") == 0) { + } else if (arg == ARG_dev || arg == ARG_oif) { NEXT_ARG(); d = *argv; } else { int type; inet_prefix dst; - if (strcmp(*argv, "to") == 0) { + if (arg == ARG_to) { NEXT_ARG(); } if ((**argv < '0' || **argv > '9') - && rtnl_rtntype_a2n(&type, *argv) == 0 - ) { + && rtnl_rtntype_a2n(&type, *argv) == 0) { NEXT_ARG(); req.r.rtm_type = type; - type_ok = 1; + ok |= type_ok; } - if (dst_ok) { + if (ok & dst_ok) { duparg2("to", *argv); } get_prefix(&dst, *argv, req.r.rtm_family); @@ -400,7 +408,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) req.r.rtm_family = dst.family; } req.r.rtm_dst_len = dst.bitlen; - dst_ok = 1; + ok |= dst_ok; if (dst.bytelen) { addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); } @@ -427,6 +435,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) } 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 || @@ -436,7 +445,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) 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 (!gw_ok) + else if (!(ok & gw_ok)) req.r.rtm_scope = RT_SCOPE_LINK; } @@ -504,7 +513,21 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) struct rtnl_handle rth; char *id = NULL; char *od = NULL; - + static const char * const keywords[] = { + "protocol", "all", "dev", "oif", "iif", "via", "table", "cache",/*all,*/ + "from", "root", "match", "exact", "to", /*root,match,exact*/ NULL + }; + enum { + ARG_proto, PARM_all, + ARG_dev, + ARG_oif, + ARG_iif, + ARG_via, + ARG_table, PARM_cache, /*PARM_all,*/ + ARG_from, PARM_root, PARM_match, PARM_exact, + ARG_to /*PARM_root, PARM_match, PARM_exact*/ + }; + int arg, parm; iproute_reset_filter(); filter.tb = RT_TABLE_MAIN; @@ -512,67 +535,66 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\""); while (argc > 0) { - if (matches(*argv, "protocol") == 0) { + arg = index_in_substr_array(keywords, *argv); + if (arg == ARG_proto) { uint32_t prot = 0; NEXT_ARG(); filter.protocolmask = -1; if (rtnl_rtprot_a2n(&prot, *argv)) { - if (strcmp(*argv, "all") != 0) { + if (index_in_str_array(keywords, *argv) != PARM_all) invarg(*argv, "protocol"); - } prot = 0; filter.protocolmask = 0; } filter.protocol = prot; - } else if (strcmp(*argv, "dev") == 0 || - strcmp(*argv, "oif") == 0) { + } else if (arg == ARG_dev || arg == ARG_oif) { NEXT_ARG(); od = *argv; - } else if (strcmp(*argv, "iif") == 0) { + } else if (arg == ARG_iif) { NEXT_ARG(); id = *argv; - } else if (matches(*argv, "from") == 0) { + } else if (arg == ARG_via) { NEXT_ARG(); - if (matches(*argv, "root") == 0) { + get_prefix(&filter.rvia, *argv, do_ipv6); + } else if (arg == ARG_table) { + NEXT_ARG(); + parm = index_in_substr_array(keywords, *argv); + if (parm == PARM_cache) + filter.tb = -1; + else if (parm == PARM_all) + filter.tb = 0; + else + invarg(*argv, "table"); + } else if (arg == ARG_from) { + NEXT_ARG(); + parm = index_in_substr_array(keywords, *argv); + if (parm == PARM_root) { NEXT_ARG(); get_prefix(&filter.rsrc, *argv, do_ipv6); - } else if (matches(*argv, "match") == 0) { + } else if (parm == PARM_match) { NEXT_ARG(); get_prefix(&filter.msrc, *argv, do_ipv6); } else { - if (matches(*argv, "exact") == 0) { + if (parm == PARM_exact) NEXT_ARG(); - } get_prefix(&filter.msrc, *argv, do_ipv6); filter.rsrc = filter.msrc; } } else { - if (matches(*argv, "to") == 0) { + /* parm = arg; // would be more plausible, we reuse arg here */ + if (arg == ARG_to) { NEXT_ARG(); + arg = index_in_substr_array(keywords, *argv); } - if (matches(*argv, "root") == 0) { + if (arg == PARM_root) { NEXT_ARG(); get_prefix(&filter.rdst, *argv, do_ipv6); - } else if (matches(*argv, "match") == 0) { + } else if (arg == PARM_match) { NEXT_ARG(); get_prefix(&filter.mdst, *argv, do_ipv6); - } else if (matches(*argv, "table") == 0) { - NEXT_ARG(); - if (matches(*argv, "cache") == 0) { - filter.tb = -1; -#if 0 && ENABLE_FEATURE_IP_RULE - -#else - } else if (matches(*argv, "main") != 0) { - invarg(*argv, "table"); - } -#endif - } else if (matches(*argv, "cache") == 0) { - filter.tb = -1; } else { - if (matches(*argv, "exact") == 0) { + if (arg == PARM_exact) NEXT_ARG(); - } get_prefix(&filter.mdst, *argv, do_ipv6); filter.rdst = filter.mdst; } @@ -655,8 +677,8 @@ static int iproute_get(int argc, char **argv) } req; char *idev = NULL; char *odev = NULL; - int connected = 0; - int from_ok = 0; + bool connected = 0; + bool from_ok = 0; static const char * const options[] = { "from", "iif", "oif", "dev", "notify", "connected", "to", 0 }; @@ -722,8 +744,7 @@ static int iproute_get(int argc, char **argv) } req.r.rtm_dst_len = addr.bitlen; } - argc--; - argv++; + argc--; argv++; } } diff --git a/networking/libiproute/utils.c b/networking/libiproute/utils.c index 601e45bb4..9605c39db 100644 --- a/networking/libiproute/utils.c +++ b/networking/libiproute/utils.c @@ -29,7 +29,7 @@ int get_integer(int *val, char *arg, int base) *val = res; return 0; } - +//XXX: FIXME: use some libbb function instead int get_unsigned(unsigned *val, char *arg, int base) { unsigned long res; diff --git a/networking/libiproute/utils.h b/networking/libiproute/utils.h index f76ad124d..3b6fef1e3 100644 --- a/networking/libiproute/utils.h +++ b/networking/libiproute/utils.h @@ -78,7 +78,7 @@ extern const char *rt_addr_n2a(int af, int len, void *addr, char *buf, int bufle void invarg(const char *, const char *) ATTRIBUTE_NORETURN; void duparg(const char *, const char *) ATTRIBUTE_NORETURN; void duparg2(const char *, const char *) ATTRIBUTE_NORETURN; -int /*ATTRIBUTE_DEPRECATED*/ matches(const char *arg, const char *pattern); +int ATTRIBUTE_DEPRECATED matches(const char *arg, const char *pattern); int inet_addr_match(inet_prefix *a, inet_prefix *b, int bits); const char *dnet_ntop(int af, const void *addr, char *str, size_t len); |