Ignore:
Timestamp:
Feb 25, 2011, 9:26:54 PM (13 years ago)
Author:
Bruno Cornec
Message:
  • Update mindi-busybox to 1.18.3 to avoid problems with the tar command which is now failing on recent versions with busybox 1.7.3
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.2.9/mindi-busybox/networking/libiproute/iproute.c

    r1765 r2725  
    11/* vi: set sw=4 ts=4: */
    22/*
    3  * iproute.c        "ip route".
     3 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
    44 *
    5  * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
    6  *
    7  * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    8  *
     5 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
    96 *
    107 * Changes:
    118 *
    12  * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
     9 * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
    1310 * Kunihiro Ishiguro <kunihiro@zebra.org> 001102: rtnh_ifindex was not initialized
    1411 */
    1512
    16 #include "ip_common.h"  /* #include "libbb.h" is inside */
     13#include "ip_common.h"  /* #include "libbb.h" is inside */
    1714#include "rt_names.h"
    1815#include "utils.h"
     
    2320
    2421
    25 typedef struct filter_t {
     22struct filter_t {
    2623    int tb;
    27     int flushed;
     24    smallint flushed;
    2825    char *flushb;
    2926    int flushp;
    3027    int flushe;
    3128    struct rtnl_handle *rth;
    32     int protocol, protocolmask;
    33     int scope, scopemask;
    34     int type, typemask;
    35     int tos, tosmask;
     29    //int protocol, protocolmask; - write-only fields?!
     30    //int scope, scopemask; - unused
     31    //int type; - read-only
     32    //int typemask; - unused
     33    //int tos, tosmask; - unused
    3634    int iif, iifmask;
    3735    int oif, oifmask;
    38     int realm, realmmask;
    39     inet_prefix rprefsrc;
     36    //int realm, realmmask; - unused
     37    //inet_prefix rprefsrc; - read-only
    4038    inet_prefix rvia;
    4139    inet_prefix rdst;
     
    4341    inet_prefix rsrc;
    4442    inet_prefix msrc;
    45 } filter_t;
    46 
    47 #define filter (*(filter_t*)&bb_common_bufsiz1)
     43} FIX_ALIASING;
     44typedef struct filter_t filter_t;
     45
     46#define G_filter (*(filter_t*)&bb_common_bufsiz1)
    4847
    4948static int flush_update(void)
    5049{
    51     if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
    52         bb_perror_msg("failed to send flush request");
     50    if (rtnl_send(G_filter.rth, G_filter.flushb, G_filter.flushp) < 0) {
     51        bb_perror_msg("can't send flush request");
    5352        return -1;
    5453    }
    55     filter.flushp = 0;
     54    G_filter.flushp = 0;
    5655    return 0;
    5756}
     
    6564        return hz_internal;
    6665
    67     fp = fopen("/proc/net/psched", "r");
     66    fp = fopen_for_read("/proc/net/psched");
    6867    if (fp) {
    6968        unsigned nom, denom;
     
    7978}
    8079
    81 static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
    82         struct nlmsghdr *n, void *arg)
     80static int FAST_FUNC print_route(const struct sockaddr_nl *who UNUSED_PARAM,
     81        struct nlmsghdr *n, void *arg UNUSED_PARAM)
    8382{
    84     FILE *fp = (FILE*)arg;
    8583    struct rtmsg *r = NLMSG_DATA(n);
    8684    int len = n->nlmsg_len;
     
    9290    SPRINT_BUF(b1);
    9391
    94 
    9592    if (n->nlmsg_type != RTM_NEWROUTE && n->nlmsg_type != RTM_DELROUTE) {
    9693        fprintf(stderr, "Not a route: %08x %08x %08x\n",
     
    9895        return 0;
    9996    }
    100     if (filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
     97    if (G_filter.flushb && n->nlmsg_type != RTM_NEWROUTE)
    10198        return 0;
    10299    len -= NLMSG_LENGTH(sizeof(*r));
     
    110107
    111108    if (r->rtm_family == AF_INET6) {
    112         if (filter.tb) {
    113             if (filter.tb < 0) {
    114                 if (!(r->rtm_flags&RTM_F_CLONED)) {
     109        if (G_filter.tb) {
     110            if (G_filter.tb < 0) {
     111                if (!(r->rtm_flags & RTM_F_CLONED)) {
    115112                    return 0;
    116113                }
    117114            } else {
    118                 if (r->rtm_flags&RTM_F_CLONED) {
     115                if (r->rtm_flags & RTM_F_CLONED) {
    119116                    return 0;
    120117                }
    121                 if (filter.tb == RT_TABLE_LOCAL) {
     118                if (G_filter.tb == RT_TABLE_LOCAL) {
    122119                    if (r->rtm_type != RTN_LOCAL) {
    123120                        return 0;
    124121                    }
    125                 } else if (filter.tb == RT_TABLE_MAIN) {
     122                } else if (G_filter.tb == RT_TABLE_MAIN) {
    126123                    if (r->rtm_type == RTN_LOCAL) {
    127124                        return 0;
     
    133130        }
    134131    } else {
    135         if (filter.tb > 0 && filter.tb != r->rtm_table) {
     132        if (G_filter.tb > 0 && G_filter.tb != r->rtm_table) {
    136133            return 0;
    137134        }
    138135    }
    139     if (filter.rdst.family &&
    140         (r->rtm_family != filter.rdst.family || filter.rdst.bitlen > r->rtm_dst_len)) {
    141         return 0;
    142     }
    143     if (filter.mdst.family &&
    144         (r->rtm_family != filter.mdst.family ||
    145          (filter.mdst.bitlen >= 0 && filter.mdst.bitlen < r->rtm_dst_len))) {
    146         return 0;
    147     }
    148     if (filter.rsrc.family &&
    149         (r->rtm_family != filter.rsrc.family || filter.rsrc.bitlen > r->rtm_src_len)) {
    150         return 0;
    151     }
    152     if (filter.msrc.family &&
    153         (r->rtm_family != filter.msrc.family ||
    154          (filter.msrc.bitlen >= 0 && filter.msrc.bitlen < r->rtm_src_len))) {
     136    if (G_filter.rdst.family
     137     && (r->rtm_family != G_filter.rdst.family || G_filter.rdst.bitlen > r->rtm_dst_len)
     138    ) {
     139        return 0;
     140    }
     141    if (G_filter.mdst.family
     142     && (r->rtm_family != G_filter.mdst.family
     143        || (G_filter.mdst.bitlen >= 0 && G_filter.mdst.bitlen < r->rtm_dst_len)
     144        )
     145    ) {
     146        return 0;
     147    }
     148    if (G_filter.rsrc.family
     149     && (r->rtm_family != G_filter.rsrc.family || G_filter.rsrc.bitlen > r->rtm_src_len)
     150    ) {
     151        return 0;
     152    }
     153    if (G_filter.msrc.family
     154     && (r->rtm_family != G_filter.msrc.family
     155        || (G_filter.msrc.bitlen >= 0 && G_filter.msrc.bitlen < r->rtm_src_len)
     156        )
     157    ) {
    155158        return 0;
    156159    }
     
    159162    parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);
    160163
    161     if (filter.rdst.family && inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen))
    162         return 0;
    163     if (filter.mdst.family && filter.mdst.bitlen >= 0 &&
    164         inet_addr_match(&dst, &filter.mdst, r->rtm_dst_len))
    165         return 0;
    166 
    167     if (filter.rsrc.family && inet_addr_match(&src, &filter.rsrc, filter.rsrc.bitlen))
    168         return 0;
    169     if (filter.msrc.family && filter.msrc.bitlen >= 0 &&
    170         inet_addr_match(&src, &filter.msrc, r->rtm_src_len))
    171         return 0;
    172 
    173     if (filter.flushb &&
    174         r->rtm_family == AF_INET6 &&
    175         r->rtm_dst_len == 0 &&
    176         r->rtm_type == RTN_UNREACHABLE &&
    177         tb[RTA_PRIORITY] &&
    178         *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1)
    179         return 0;
    180 
    181     if (filter.flushb) {
     164    if (G_filter.rdst.family
     165     && inet_addr_match(&dst, &G_filter.rdst, G_filter.rdst.bitlen)
     166    ) {
     167        return 0;
     168    }
     169    if (G_filter.mdst.family
     170     && G_filter.mdst.bitlen >= 0
     171     && inet_addr_match(&dst, &G_filter.mdst, r->rtm_dst_len)
     172    ) {
     173        return 0;
     174    }
     175    if (G_filter.rsrc.family
     176     && inet_addr_match(&src, &G_filter.rsrc, G_filter.rsrc.bitlen)
     177    ) {
     178        return 0;
     179    }
     180    if (G_filter.msrc.family && G_filter.msrc.bitlen >= 0
     181     && inet_addr_match(&src, &G_filter.msrc, r->rtm_src_len)
     182    ) {
     183        return 0;
     184    }
     185    if (G_filter.flushb
     186     && r->rtm_family == AF_INET6
     187     && r->rtm_dst_len == 0
     188     && r->rtm_type == RTN_UNREACHABLE
     189     && tb[RTA_PRIORITY]
     190     && *(int*)RTA_DATA(tb[RTA_PRIORITY]) == -1
     191    ) {
     192        return 0;
     193    }
     194
     195    if (G_filter.flushb) {
    182196        struct nlmsghdr *fn;
    183         if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
     197        if (NLMSG_ALIGN(G_filter.flushp) + n->nlmsg_len > G_filter.flushe) {
    184198            if (flush_update())
    185199                bb_error_msg_and_die("flush");
    186200        }
    187         fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
     201        fn = (struct nlmsghdr*)(G_filter.flushb + NLMSG_ALIGN(G_filter.flushp));
    188202        memcpy(fn, n, n->nlmsg_len);
    189203        fn->nlmsg_type = RTM_DELROUTE;
    190204        fn->nlmsg_flags = NLM_F_REQUEST;
    191         fn->nlmsg_seq = ++filter.rth->seq;
    192         filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb;
    193         filter.flushed++;
     205        fn->nlmsg_seq = ++G_filter.rth->seq;
     206        G_filter.flushp = (((char*)fn) + n->nlmsg_len) - G_filter.flushb;
     207        G_filter.flushed = 1;
    194208        return 0;
    195209    }
    196210
    197211    if (n->nlmsg_type == RTM_DELROUTE) {
    198         fprintf(fp, "Deleted ");
    199     }
    200     if (r->rtm_type != RTN_UNICAST && !filter.type) {
    201         fprintf(fp, "%s ", rtnl_rtntype_n2a(r->rtm_type, b1, sizeof(b1)));
     212        printf("Deleted ");
     213    }
     214    if (r->rtm_type != RTN_UNICAST /* && !G_filter.type - always 0 */) {
     215        printf("%s ", rtnl_rtntype_n2a(r->rtm_type, b1));
    202216    }
    203217
    204218    if (tb[RTA_DST]) {
    205219        if (r->rtm_dst_len != host_len) {
    206             fprintf(fp, "%s/%u ", rt_addr_n2a(r->rtm_family,
    207                              RTA_PAYLOAD(tb[RTA_DST]),
    208                              RTA_DATA(tb[RTA_DST]),
    209                              abuf, sizeof(abuf)),
    210                 r->rtm_dst_len
    211                 );
     220            printf("%s/%u ", rt_addr_n2a(r->rtm_family,
     221                        RTA_DATA(tb[RTA_DST]),
     222                        abuf, sizeof(abuf)),
     223                    r->rtm_dst_len
     224                    );
    212225        } else {
    213             fprintf(fp, "%s ", format_host(r->rtm_family,
    214                                RTA_PAYLOAD(tb[RTA_DST]),
    215                                RTA_DATA(tb[RTA_DST]),
    216                                abuf, sizeof(abuf))
    217                 );
     226            printf("%s ", format_host(r->rtm_family,
     227                        RTA_PAYLOAD(tb[RTA_DST]),
     228                        RTA_DATA(tb[RTA_DST]),
     229                        abuf, sizeof(abuf))
     230                    );
    218231        }
    219232    } else if (r->rtm_dst_len) {
    220         fprintf(fp, "0/%d ", r->rtm_dst_len);
     233        printf("0/%d ", r->rtm_dst_len);
    221234    } else {
    222         fprintf(fp, "default ");
     235        printf("default ");
    223236    }
    224237    if (tb[RTA_SRC]) {
    225238        if (r->rtm_src_len != host_len) {
    226             fprintf(fp, "from %s/%u ", rt_addr_n2a(r->rtm_family,
    227                              RTA_PAYLOAD(tb[RTA_SRC]),
    228                              RTA_DATA(tb[RTA_SRC]),
    229                              abuf, sizeof(abuf)),
    230                 r->rtm_src_len
    231                 );
     239            printf("from %s/%u ", rt_addr_n2a(r->rtm_family,
     240                        RTA_DATA(tb[RTA_SRC]),
     241                        abuf, sizeof(abuf)),
     242                    r->rtm_src_len
     243                    );
    232244        } else {
    233             fprintf(fp, "from %s ", format_host(r->rtm_family,
    234                                RTA_PAYLOAD(tb[RTA_SRC]),
    235                                RTA_DATA(tb[RTA_SRC]),
    236                                abuf, sizeof(abuf))
    237                 );
     245            printf("from %s ", format_host(r->rtm_family,
     246                        RTA_PAYLOAD(tb[RTA_SRC]),
     247                        RTA_DATA(tb[RTA_SRC]),
     248                        abuf, sizeof(abuf))
     249                    );
    238250        }
    239251    } else if (r->rtm_src_len) {
    240         fprintf(fp, "from 0/%u ", r->rtm_src_len);
    241     }
    242     if (tb[RTA_GATEWAY] && filter.rvia.bitlen != host_len) {
    243         fprintf(fp, "via %s ",
    244             format_host(r->rtm_family,
    245                     RTA_PAYLOAD(tb[RTA_GATEWAY]),
    246                     RTA_DATA(tb[RTA_GATEWAY]),
    247                     abuf, sizeof(abuf)));
    248     }
    249     if (tb[RTA_OIF] && filter.oifmask != -1) {
    250         fprintf(fp, "dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF])));
    251     }
    252 
    253     if (tb[RTA_PREFSRC] && filter.rprefsrc.bitlen != host_len) {
     252        printf("from 0/%u ", r->rtm_src_len);
     253    }
     254    if (tb[RTA_GATEWAY] && G_filter.rvia.bitlen != host_len) {
     255        printf("via %s ", format_host(r->rtm_family,
     256                    RTA_PAYLOAD(tb[RTA_GATEWAY]),
     257                    RTA_DATA(tb[RTA_GATEWAY]),
     258                    abuf, sizeof(abuf)));
     259    }
     260    if (tb[RTA_OIF] && G_filter.oifmask != -1) {
     261        printf("dev %s ", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_OIF])));
     262    }
     263
     264    if (tb[RTA_PREFSRC] && /*G_filter.rprefsrc.bitlen - always 0*/ 0 != host_len) {
    254265        /* Do not use format_host(). It is our local addr
    255266           and symbolic name will not be useful.
    256267         */
    257         fprintf(fp, " src %s ",
    258             rt_addr_n2a(r->rtm_family,
    259                     RTA_PAYLOAD(tb[RTA_PREFSRC]),
    260                     RTA_DATA(tb[RTA_PREFSRC]),
    261                     abuf, sizeof(abuf)));
     268        printf(" src %s ", rt_addr_n2a(r->rtm_family,
     269                    RTA_DATA(tb[RTA_PREFSRC]),
     270                    abuf, sizeof(abuf)));
    262271    }
    263272    if (tb[RTA_PRIORITY]) {
    264         fprintf(fp, " metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY]));
     273        printf(" metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY]));
    265274    }
    266275    if (r->rtm_family == AF_INET6) {
     
    271280        if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) {
    272281            if (r->rtm_flags & RTM_F_CLONED) {
    273                 fprintf(fp, "%c    cache ", _SL_);
     282                printf("%c    cache ", _SL_);
    274283            }
    275284            if (ci->rta_expires) {
    276                 fprintf(fp, " expires %dsec", ci->rta_expires / get_hz());
     285                printf(" expires %dsec", ci->rta_expires / get_hz());
    277286            }
    278287            if (ci->rta_error != 0) {
    279                 fprintf(fp, " error %d", ci->rta_error);
     288                printf(" error %d", ci->rta_error);
    280289            }
    281290        } else if (ci) {
    282291            if (ci->rta_error != 0)
    283                 fprintf(fp, " error %d", ci->rta_error);
    284         }
    285     }
    286     if (tb[RTA_IIF] && filter.iifmask != -1) {
    287         fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF])));
    288     }
    289     fputc('\n', fp);
    290     fflush(fp);
     292                printf(" error %d", ci->rta_error);
     293        }
     294    }
     295    if (tb[RTA_IIF] && G_filter.iifmask != -1) {
     296        printf(" iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF])));
     297    }
     298    bb_putchar('\n');
    291299    return 0;
    292300}
    293301
    294302/* Return value becomes exitcode. It's okay to not return at all */
    295 static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
     303static int iproute_modify(int cmd, unsigned flags, char **argv)
    296304{
    297305    static const char keywords[] ALIGN1 =
    298         "src\0""via\0""mtu\0""lock\0""protocol\0"USE_FEATURE_IP_RULE("table\0")
    299         "dev\0""oif\0""to\0";
     306        "src\0""via\0""mtu\0""lock\0""protocol\0"IF_FEATURE_IP_RULE("table\0")
     307        "dev\0""oif\0""to\0""metric\0";
    300308    enum {
    301309        ARG_src,
     
    303311        ARG_mtu, PARM_lock,
    304312        ARG_protocol,
    305 USE_FEATURE_IP_RULE(ARG_table,)
     313IF_FEATURE_IP_RULE(ARG_table,)
    306314        ARG_dev,
    307315        ARG_oif,
    308         ARG_to
     316        ARG_to,
     317        ARG_metric,
    309318    };
    310319    enum {
     
    316325    struct rtnl_handle rth;
    317326    struct {
    318         struct nlmsghdr     n;
    319         struct rtmsg        r;
    320         char            buf[1024];
     327        struct nlmsghdr n;
     328        struct rtmsg    r;
     329        char            buf[1024];
    321330    } req;
    322331    char mxbuf[256];
     
    330339
    331340    req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
    332     req.n.nlmsg_flags = NLM_F_REQUEST|flags;
     341    req.n.nlmsg_flags = NLM_F_REQUEST | flags;
    333342    req.n.nlmsg_type = cmd;
    334343    req.r.rtm_family = preferred_family;
    335     req.r.rtm_table = RT_TABLE_MAIN;
    336     req.r.rtm_scope = RT_SCOPE_NOWHERE;
     344    if (RT_TABLE_MAIN) /* if it is zero, memset already did it */
     345        req.r.rtm_table = RT_TABLE_MAIN;
     346    if (RT_SCOPE_NOWHERE)
     347        req.r.rtm_scope = RT_SCOPE_NOWHERE;
    337348
    338349    if (cmd != RTM_DELROUTE) {
     
    345356    mxrta->rta_len = RTA_LENGTH(0);
    346357
    347     while (argc > 0) {
     358    while (*argv) {
    348359        arg = index_in_substrings(keywords, *argv);
    349360        if (arg == ARG_src) {
     
    367378            NEXT_ARG();
    368379            if (index_in_strings(keywords, *argv) == PARM_lock) {
    369                 mxlock |= (1<<RTAX_MTU);
    370                 NEXT_ARG();
    371             }
    372             if (get_unsigned(&mtu, *argv, 0))
    373                 invarg(*argv, "mtu");
     380                mxlock |= (1 << RTAX_MTU);
     381                NEXT_ARG();
     382            }
     383            mtu = get_unsigned(*argv, "mtu");
    374384            rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu);
    375385        } else if (arg == ARG_protocol) {
     
    391401            NEXT_ARG();
    392402            d = *argv;
     403        } else if (arg == ARG_metric) {
     404            uint32_t metric;
     405            NEXT_ARG();
     406            metric = get_u32(*argv, "metric");
     407            addattr32(&req.n, sizeof(req), RTA_PRIORITY, metric);
    393408        } else {
    394409            int type;
     
    399414            }
    400415            if ((**argv < '0' || **argv > '9')
    401                 && rtnl_rtntype_a2n(&type, *argv) == 0) {
     416             && rtnl_rtntype_a2n(&type, *argv) == 0) {
    402417                NEXT_ARG();
    403418                req.r.rtm_type = type;
     
    418433            }
    419434        }
    420         argc--; argv++;
     435        argv++;
    421436    }
    422437
     
    443458    if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT)
    444459        req.r.rtm_scope = RT_SCOPE_HOST;
    445     else if (req.r.rtm_type == RTN_BROADCAST ||
    446             req.r.rtm_type == RTN_MULTICAST ||
    447             req.r.rtm_type == RTN_ANYCAST)
     460    else
     461    if (req.r.rtm_type == RTN_BROADCAST
     462     || req.r.rtm_type == RTN_MULTICAST
     463     || req.r.rtm_type == RTN_ANYCAST
     464    ) {
    448465        req.r.rtm_scope = RT_SCOPE_LINK;
     466    }
    449467    else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) {
    450468        if (cmd == RTM_DELROUTE)
     
    478496
    479497    req.nlh.nlmsg_len = sizeof(req);
    480     req.nlh.nlmsg_type = RTM_GETROUTE;
    481     req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_REQUEST;
    482     req.nlh.nlmsg_pid = 0;
     498    if (RTM_GETROUTE)
     499        req.nlh.nlmsg_type = RTM_GETROUTE;
     500    if (NLM_F_ROOT | NLM_F_REQUEST)
     501        req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST;
     502    /*req.nlh.nlmsg_pid = 0; - memset did it already */
    483503    req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
    484504    req.rtm.rtm_family = family;
    485     req.rtm.rtm_flags |= RTM_F_CLONED;
     505    if (RTM_F_CLONED)
     506        req.rtm.rtm_flags = RTM_F_CLONED;
    486507
    487508    return xsendto(rth->fd, (void*)&req, sizeof(req), (struct sockaddr*)&nladdr, sizeof(nladdr));
     
    498519
    499520    if (write(flush_fd, "-1", 2) < 2) {
    500         bb_perror_msg("cannot flush routing cache");
     521        bb_perror_msg("can't flush routing cache");
    501522        return;
    502523    }
     
    506527static void iproute_reset_filter(void)
    507528{
    508     memset(&filter, 0, sizeof(filter));
    509     filter.mdst.bitlen = -1;
    510     filter.msrc.bitlen = -1;
     529    memset(&G_filter, 0, sizeof(G_filter));
     530    G_filter.mdst.bitlen = -1;
     531    G_filter.msrc.bitlen = -1;
    511532}
    512533
    513534/* Return value becomes exitcode. It's okay to not return at all */
    514 static int iproute_list_or_flush(int argc, char **argv, int flush)
     535static int iproute_list_or_flush(char **argv, int flush)
    515536{
    516537    int do_ipv6 = preferred_family;
     
    519540    char *od = NULL;
    520541    static const char keywords[] ALIGN1 =
    521         "protocol\0""all\0""dev\0""oif\0""iif\0""via\0""table\0""cache\0" /*all*/
    522         "from\0""root\0""match\0""exact\0""to\0"/*root match exact*/;
     542        /* "ip route list/flush" parameters: */
     543        "protocol\0" "dev\0"   "oif\0"   "iif\0"
     544        "via\0"      "table\0" "cache\0"
     545        "from\0"     "to\0"
     546        /* and possible further keywords */
     547        "all\0"
     548        "root\0"
     549        "match\0"
     550        "exact\0"
     551        "main\0"
     552        ;
    523553    enum {
    524         ARG_proto, PARM_all,
    525         ARG_dev,
    526         ARG_oif,
    527         ARG_iif,
    528         ARG_via,
    529         ARG_table, PARM_cache, /*PARM_all,*/
    530         ARG_from, PARM_root, PARM_match, PARM_exact,
    531         ARG_to  /*PARM_root, PARM_match, PARM_exact*/
     554        KW_proto, KW_dev,   KW_oif,  KW_iif,
     555        KW_via,   KW_table, KW_cache,
     556        KW_from,  KW_to,
     557        /* */
     558        KW_all,
     559        KW_root,
     560        KW_match,
     561        KW_exact,
     562        KW_main,
    532563    };
    533564    int arg, parm;
     565
    534566    iproute_reset_filter();
    535     filter.tb = RT_TABLE_MAIN;
    536 
    537     if (flush && argc <= 0)
     567    G_filter.tb = RT_TABLE_MAIN;
     568
     569    if (flush && !*argv)
    538570        bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\"");
    539571
    540     while (argc > 0) {
     572    while (*argv) {
    541573        arg = index_in_substrings(keywords, *argv);
    542         if (arg == ARG_proto) {
     574        if (arg == KW_proto) {
    543575            uint32_t prot = 0;
    544576            NEXT_ARG();
    545             filter.protocolmask = -1;
     577            //G_filter.protocolmask = -1;
    546578            if (rtnl_rtprot_a2n(&prot, *argv)) {
    547                 if (index_in_strings(keywords, *argv) != PARM_all)
     579                if (index_in_strings(keywords, *argv) != KW_all)
    548580                    invarg(*argv, "protocol");
    549581                prot = 0;
    550                 filter.protocolmask = 0;
    551             }
    552             filter.protocol = prot;
    553         } else if (arg == ARG_dev || arg == ARG_oif) {
     582                //G_filter.protocolmask = 0;
     583            }
     584            //G_filter.protocol = prot;
     585        } else if (arg == KW_dev || arg == KW_oif) {
    554586            NEXT_ARG();
    555587            od = *argv;
    556         } else if (arg == ARG_iif) {
     588        } else if (arg == KW_iif) {
    557589            NEXT_ARG();
    558590            id = *argv;
    559         } else if (arg == ARG_via) {
    560             NEXT_ARG();
    561             get_prefix(&filter.rvia, *argv, do_ipv6);
    562         } else if (arg == ARG_table) {
     591        } else if (arg == KW_via) {
     592            NEXT_ARG();
     593            get_prefix(&G_filter.rvia, *argv, do_ipv6);
     594        } else if (arg == KW_table) { /* table all/cache/main */
    563595            NEXT_ARG();
    564596            parm = index_in_substrings(keywords, *argv);
    565             if (parm == PARM_cache)
    566                 filter.tb = -1;
    567             else if (parm == PARM_all)
    568                 filter.tb = 0;
    569             else
     597            if (parm == KW_cache)
     598                G_filter.tb = -1;
     599            else if (parm == KW_all)
     600                G_filter.tb = 0;
     601            else if (parm != KW_main) {
     602#if ENABLE_FEATURE_IP_RULE
     603                uint32_t tid;
     604                if (rtnl_rttable_a2n(&tid, *argv))
     605                    invarg(*argv, "table");
     606                G_filter.tb = tid;
     607#else
    570608                invarg(*argv, "table");
    571         } else if (arg == ARG_from) {
     609#endif
     610            }
     611        } else if (arg == KW_cache) {
     612            /* The command 'ip route flush cache' is used by OpenSWAN.
     613             * Assuming it's a synonym for 'ip route flush table cache' */
     614            G_filter.tb = -1;
     615        } else if (arg == KW_from) {
    572616            NEXT_ARG();
    573617            parm = index_in_substrings(keywords, *argv);
    574             if (parm == PARM_root) {
    575                 NEXT_ARG();
    576                 get_prefix(&filter.rsrc, *argv, do_ipv6);
    577             } else if (parm == PARM_match) {
    578                 NEXT_ARG();
    579                 get_prefix(&filter.msrc, *argv, do_ipv6);
     618            if (parm == KW_root) {
     619                NEXT_ARG();
     620                get_prefix(&G_filter.rsrc, *argv, do_ipv6);
     621            } else if (parm == KW_match) {
     622                NEXT_ARG();
     623                get_prefix(&G_filter.msrc, *argv, do_ipv6);
    580624            } else {
    581                 if (parm == PARM_exact)
     625                if (parm == KW_exact)
    582626                    NEXT_ARG();
    583                 get_prefix(&filter.msrc, *argv, do_ipv6);
    584                 filter.rsrc = filter.msrc;
    585             }
    586         } else {
    587             /* parm = arg; // would be more plausible, we reuse arg here */
    588             if (arg == ARG_to) {
     627                get_prefix(&G_filter.msrc, *argv, do_ipv6);
     628                G_filter.rsrc = G_filter.msrc;
     629            }
     630        } else { /* "to" is the default parameter */
     631            if (arg == KW_to) {
    589632                NEXT_ARG();
    590633                arg = index_in_substrings(keywords, *argv);
    591634            }
    592             if (arg == PARM_root) {
    593                 NEXT_ARG();
    594                 get_prefix(&filter.rdst, *argv, do_ipv6);
    595             } else if (arg == PARM_match) {
    596                 NEXT_ARG();
    597                 get_prefix(&filter.mdst, *argv, do_ipv6);
    598             } else {
    599                 if (arg == PARM_exact)
     635            /* parm = arg; - would be more plausible, but we reuse 'arg' here */
     636            if (arg == KW_root) {
     637                NEXT_ARG();
     638                get_prefix(&G_filter.rdst, *argv, do_ipv6);
     639            } else if (arg == KW_match) {
     640                NEXT_ARG();
     641                get_prefix(&G_filter.mdst, *argv, do_ipv6);
     642            } else { /* "to exact" is the default */
     643                if (arg == KW_exact)
    600644                    NEXT_ARG();
    601                 get_prefix(&filter.mdst, *argv, do_ipv6);
    602                 filter.rdst = filter.mdst;
    603             }
    604         }
    605         argc--;
     645                get_prefix(&G_filter.mdst, *argv, do_ipv6);
     646                G_filter.rdst = G_filter.mdst;
     647            }
     648        }
    606649        argv++;
    607650    }
    608651
    609     if (do_ipv6 == AF_UNSPEC && filter.tb) {
     652    if (do_ipv6 == AF_UNSPEC && G_filter.tb) {
    610653        do_ipv6 = AF_INET;
    611654    }
    612655
    613656    xrtnl_open(&rth);
    614 
    615657    ll_init_map(&rth);
    616658
     
    620662        if (id) {
    621663            idx = xll_name_to_index(id);
    622             filter.iif = idx;
    623             filter.iifmask = -1;
     664            G_filter.iif = idx;
     665            G_filter.iifmask = -1;
    624666        }
    625667        if (od) {
    626668            idx = xll_name_to_index(od);
    627             filter.oif = idx;
    628             filter.oifmask = -1;
     669            G_filter.oif = idx;
     670            G_filter.oifmask = -1;
    629671        }
    630672    }
     
    633675        char flushb[4096-512];
    634676
    635         if (filter.tb == -1) {
     677        if (G_filter.tb == -1) { /* "flush table cache" */
    636678            if (do_ipv6 != AF_INET6)
    637679                iproute_flush_cache();
     
    640682        }
    641683
    642         filter.flushb = flushb;
    643         filter.flushp = 0;
    644         filter.flushe = sizeof(flushb);
    645         filter.rth = &rth;
     684        G_filter.flushb = flushb;
     685        G_filter.flushp = 0;
     686        G_filter.flushe = sizeof(flushb);
     687        G_filter.rth = &rth;
    646688
    647689        for (;;) {
    648690            xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
    649             filter.flushed = 0;
    650             xrtnl_dump_filter(&rth, print_route, stdout);
    651             if (filter.flushed == 0)
     691            G_filter.flushed = 0;
     692            xrtnl_dump_filter(&rth, print_route, NULL);
     693            if (G_filter.flushed == 0)
    652694                return 0;
    653695            if (flush_update())
     
    656698    }
    657699
    658     if (filter.tb != -1) {
     700    if (G_filter.tb != -1) {
    659701        xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
    660702    } else if (rtnl_rtcache_request(&rth, do_ipv6) < 0) {
    661         bb_perror_msg_and_die("cannot send dump request");
    662     }
    663     xrtnl_dump_filter(&rth, print_route, stdout);
     703        bb_perror_msg_and_die("can't send dump request");
     704    }
     705    xrtnl_dump_filter(&rth, print_route, NULL);
    664706
    665707    return 0;
     
    668710
    669711/* Return value becomes exitcode. It's okay to not return at all */
    670 static int iproute_get(int argc, char **argv)
     712static int iproute_get(char **argv)
    671713{
    672714    struct rtnl_handle rth;
     
    688730
    689731    req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
    690     req.n.nlmsg_flags = NLM_F_REQUEST;
    691     req.n.nlmsg_type = RTM_GETROUTE;
     732    if (NLM_F_REQUEST)
     733        req.n.nlmsg_flags = NLM_F_REQUEST;
     734    if (RTM_GETROUTE)
     735        req.n.nlmsg_type = RTM_GETROUTE;
    692736    req.r.rtm_family = preferred_family;
    693     req.r.rtm_table = 0;
    694     req.r.rtm_protocol = 0;
    695     req.r.rtm_scope = 0;
    696     req.r.rtm_type = 0;
    697     req.r.rtm_src_len = 0;
    698     req.r.rtm_dst_len = 0;
    699     req.r.rtm_tos = 0;
    700 
    701     while (argc > 0) {
     737    /*req.r.rtm_table = 0; - memset did this already */
     738    /*req.r.rtm_protocol = 0;*/
     739    /*req.r.rtm_scope = 0;*/
     740    /*req.r.rtm_type = 0;*/
     741    /*req.r.rtm_src_len = 0;*/
     742    /*req.r.rtm_dst_len = 0;*/
     743    /*req.r.rtm_tos = 0;*/
     744
     745    while (*argv) {
    702746        switch (index_in_strings(options, *argv)) {
    703747            case 0: /* from */
     
    745789                req.r.rtm_dst_len = addr.bitlen;
    746790            }
    747             argc--; argv++;
    748         }
     791        }
     792        argv++;
    749793    }
    750794
     
    783827        struct rtattr * tb[RTA_MAX+1];
    784828
    785         print_route(NULL, &req.n, (void*)stdout);
     829        print_route(NULL, &req.n, NULL);
    786830
    787831        if (req.n.nlmsg_type != RTM_NEWROUTE) {
     
    800844            r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]);
    801845        } else if (!tb[RTA_SRC]) {
    802             bb_error_msg_and_die("failed to connect the route");
     846            bb_error_msg_and_die("can't connect the route");
    803847        }
    804848        if (!odev && tb[RTA_OIF]) {
     
    818862        }
    819863    }
    820     print_route(NULL, &req.n, (void*)stdout);
     864    print_route(NULL, &req.n, NULL);
    821865    return 0;
    822866}
    823867
    824868/* Return value becomes exitcode. It's okay to not return at all */
    825 int do_iproute(int argc, char **argv)
     869int FAST_FUNC do_iproute(char **argv)
    826870{
    827871    static const char ip_route_commands[] ALIGN1 =
     
    829873    /*4-7*/ "delete\0""get\0""list\0""show\0"
    830874    /*8..*/ "prepend\0""replace\0""test\0""flush\0";
    831     int command_num = 6;
     875    int command_num;
    832876    unsigned flags = 0;
    833877    int cmd = RTM_NEWROUTE;
    834878
     879    if (!*argv)
     880        return iproute_list_or_flush(argv, 0);
     881
    835882    /* "Standard" 'ip r a' treats 'a' as 'add', not 'append' */
    836883    /* It probably means that it is using "first match" rule */
    837     if (*argv) {
    838         command_num = index_in_substrings(ip_route_commands, *argv);
    839     }
     884    command_num = index_in_substrings(ip_route_commands, *argv);
     885
    840886    switch (command_num) {
    841887        case 0: /* add */
     
    853899            break;
    854900        case 5: /* get */
    855             return iproute_get(argc-1, argv+1);
     901            return iproute_get(argv+1);
    856902        case 6: /* list */
    857903        case 7: /* show */
    858             return iproute_list_or_flush(argc-1, argv+1, 0);
     904            return iproute_list_or_flush(argv+1, 0);
    859905        case 8: /* prepend */
    860906            flags = NLM_F_CREATE;
     907            break;
    861908        case 9: /* replace */
    862909            flags = NLM_F_CREATE|NLM_F_REPLACE;
     910            break;
    863911        case 10: /* test */
    864912            flags = NLM_F_EXCL;
     913            break;
    865914        case 11: /* flush */
    866             return iproute_list_or_flush(argc-1, argv+1, 1);
     915            return iproute_list_or_flush(argv+1, 1);
    867916        default:
    868917            bb_error_msg_and_die("unknown command %s", *argv);
    869918    }
    870919
    871     return iproute_modify(cmd, flags, argc-1, argv+1);
     920    return iproute_modify(cmd, flags, argv+1);
    872921}
Note: See TracChangeset for help on using the changeset viewer.