Ignore:
Timestamp:
Nov 6, 2007, 11:01:53 AM (16 years ago)
Author:
Bruno Cornec
Message:
  • Better output for mindi-busybox revision
  • Remove dummy file created on NFS - report from Arnaud Tiger <arnaud.tiger_at_hp.com>
  • strace useful for debug
  • fix new versions for pb (2.0.0 for mindi and 1.7.2 for mindi-busybox)
  • fix build process for mindi-busybox + options used in that version (dd for label-partitions-as-necessary)
  • fix typo in label-partitions-as-necessary which doesn't seem to work
  • Update to busybox 1.7.2
  • perl is now required at restore time to support uuid swap partitions (and will be used for many other thigs

in the future for sure)

  • next mindi version will be 2.0.0 due to all the changes made in it (udev may break working distros)
  • small optimization in mindi on keyboard handling (one single find instead of multiple)
  • better interaction for USB device when launching mindi manually
  • attempt to automatically guess block disk size for ramdisk
  • fix typos in bkphw
  • Fix the remaining problem with UUID support for swap partitions
  • Updates mondoarchive man page for USB support
  • Adds preliminary Hardware support to mindi (Proliant SSSTK)
  • Tries to add udev support also for rhel4
  • Fix UUID support which was still broken.
  • Be conservative in test for the start-nfs script
  • Update config file for mindi-busybox for 1.7.2 migration
  • Try to run around a busybox bug (1.2.2 pb on inexistant links)
  • Add build content for mindi-busybox in pb
  • Remove distributions content for mindi-busybox
  • Fix a warning on inexistant raidtab
  • Solve problem on tmpfs in restore init (Problem of inexistant symlink and busybox)
  • Create MONDO_CACHE and use it everywhere + creation at start
  • Really never try to eject a USB device
  • Fix a issue with &> usage (replaced with 1> and 2>)
  • Adds magic file to depllist in order to have file working + ldd which helps for debugging issues
  • tty modes correct to avoid sh error messages
  • Use ext3 normally and not ext2 instead
  • USB device should be corrected after reading (take 1st part)
  • Adds a mount_USB_here function derived from mount_CDROM_here
  • usb detection place before /dev detection in device name at restore time
  • Fix when restoring from USB: media is asked in interactive mode
  • Adds USB support for mondorestore
  • mount_cdrom => mount_media
  • elilo.efi is now searched throughout /boot/efi and not in a fixed place as there is no standard
  • untar-and-softlink => untar (+ interface change)
  • suppress useless softlinks creation/removal in boot process
  • avoids udevd messages on groups
  • Increase # of disks to 99 as in mindi at restore time (should be a conf file parameter)
  • skip existing big file creation
  • seems to work correctly for USB mindi boot
  • Adds group and tty link to udev conf
  • Always load usb-torage (even 2.6) to initiate USB bus discovery
  • Better printing of messages
  • Attempt to fix a bug in supporting OpenSusE 10.3 kernel for initramfs (mindi may now use multiple regex for kernel initrd detection)
  • Links were not correctly done as non relative for modules in mindi
  • exclusion of modules denied now works
  • Also create modules in their ordinary place, so that classical modprobe works + copy modules.dep
  • Fix bugs for DENY_MODS handling
  • Add device /dev/console for udev
  • ide-generic should now really be excluded
  • Fix a bug in major number for tty
  • If udev then adds modprobe/insmod to rootfs
  • tty0 is also cretaed with udev
  • ide-generic put rather in DENY_MODS
  • udevd remove from deplist s handled in mindi directly
  • better default for mindi when using --usb
  • Handles dynamically linked busybox (in case we want to use it soon ;-)
  • Adds fixed devices to create for udev
  • ide-generic should not be part of the initrd when using libata v2
  • support a dynamically linked udev (case on Ubuntu 7.10 and Mandriva 2008.0 so should be quite generic) This will give incitation to move to dyn. linked binaries in the initrd which will help for other tasks (ia6 4)
  • Improvement in udev support (do not use cl options not available in busybox)
  • Udev in mindi
    • auto creation of the right links at boot time with udev-links.conf(from Mandriva 2008.0)
    • rework startup of udev as current makes kernel crash (from Mandriva 2008.0)
    • add support for 64 bits udev
  • Try to render MyInsmod silent at boot time
  • Adds udev support (mandatory for newest distributions to avoid remapping of devices in a different way as on the original system)
  • We also need vaft format support for USB boot
  • Adds libusual support (Ubuntu 7.10 needs it for USB)
  • Improve Ubuntu/Debian keyboard detection and support
  • pbinit adapted to new pb (0.8.10). Filtering of docs done in it
  • Suppress some mondo warnings and errors on USB again
  • Tries to fix lack of files in deb mindi package
  • Verify should now work for USB devices
  • More log/mesages improvement for USB support
  • - Supress g_erase_tmpdir_and_scratchdir
  • Improve some log messages for USB support
  • Try to improve install in mindi to avoid issues with isolinux.cfg not installed vene if in the pkg :-(
  • Improve mindi-busybox build
  • In conformity with pb 0.8.9
  • Add support for Ubuntu 7.10 in build process
  • Add USB Key button to Menu UI (CD streamer removed)
  • Attempt to fix error messages on tmp/scratch files at the end by removing those dir at the latest possible.
  • Fix a bug linked to the size of the -E param which could be used (Arnaud Tiger/René Ribaud).
  • Integrate ~/.pbrc content into mondorescue.pb (required project-builder >= 0.8.7)
  • Put mondorescue in conformity with new pb filtering rules
  • Add USB support at restore time (no test done yet). New start-usb script PB varibale added where useful
  • Unmounting USB device before removal of temporary scratchdir
  • Stil refining USB copy back to mondo (one command was not executed)
  • No need to have the image subdor in the csratchdir when USB.
  • umount the USB partition before attempting to use it
  • Remove useless copy from mindi to mondo at end of USB handling

(risky merge, we are raising the limits of 2 diverging branches. The status of stable is not completely sure as such. Will need lots of tests, but it's not yet done :-()
(merge -r1692:1769 $SVN_M/branches/2.2.5)

File:
1 edited

Legend:

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

    r821 r1770  
    1414 */
    1515
    16 #include "libbb.h"
    17 
    18 #include <sys/socket.h>
    19 
    20 #include <string.h>
    21 #include <fcntl.h>
    22 #include <unistd.h>
    23 
     16#include "ip_common.h"  /* #include "libbb.h" is inside */
    2417#include "rt_names.h"
    2518#include "utils.h"
    26 #include "ip_common.h"
    2719
    2820#ifndef RTAX_RTTVAR
     
    3123
    3224
    33 static struct
    34 {
     25typedef struct filter_t {
    3526    int tb;
    3627    int flushed;
     
    5243    inet_prefix rsrc;
    5344    inet_prefix msrc;
    54 } filter;
     45} filter_t;
     46
     47#define filter (*(filter_t*)&bb_common_bufsiz1)
    5548
    5649static int flush_update(void)
    5750{
    5851    if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
    59         perror("Failed to send flush request\n");
     52        bb_perror_msg("failed to send flush request");
    6053        return -1;
    6154    }
    6255    filter.flushp = 0;
    6356    return 0;
     57}
     58
     59static unsigned get_hz(void)
     60{
     61    static unsigned hz_internal;
     62    FILE *fp;
     63
     64    if (hz_internal)
     65        return hz_internal;
     66
     67    fp = fopen("/proc/net/psched", "r");
     68    if (fp) {
     69        unsigned nom, denom;
     70
     71        if (fscanf(fp, "%*08x%*08x%08x%08x", &nom, &denom) == 2)
     72            if (nom == 1000000)
     73                hz_internal = denom;
     74        fclose(fp);
     75    }
     76    if (!hz_internal)
     77        hz_internal = sysconf(_SC_CLK_TCK);
     78    return hz_internal;
    6479}
    6580
     
    86101        return 0;
    87102    len -= NLMSG_LENGTH(sizeof(*r));
    88     if (len < 0) {
    89         bb_error_msg("wrong nlmsg len %d", len);
    90         return -1;
    91     }
     103    if (len < 0)
     104        bb_error_msg_and_die("wrong nlmsg len %d", len);
    92105
    93106    if (r->rtm_family == AF_INET6)
     
    170183        if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) {
    171184            if (flush_update())
    172                 return -1;
     185                bb_error_msg_and_die("flush");
    173186        }
    174187        fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp));
     
    249262    }
    250263    if (tb[RTA_PRIORITY]) {
    251         fprintf(fp, " metric %d ", *(__u32*)RTA_DATA(tb[RTA_PRIORITY]));
     264        fprintf(fp, " metric %d ", *(uint32_t*)RTA_DATA(tb[RTA_PRIORITY]));
    252265    }
    253266    if (r->rtm_family == AF_INET6) {
     
    257270        }
    258271        if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) {
    259             static int hz;
    260             if (!hz) {
    261                 hz = get_hz();
    262             }
    263272            if (r->rtm_flags & RTM_F_CLONED) {
    264                 fprintf(fp, "%s    cache ", _SL_);
     273                fprintf(fp, "%c    cache ", _SL_);
    265274            }
    266275            if (ci->rta_expires) {
    267                 fprintf(fp, " expires %dsec", ci->rta_expires/hz);
     276                fprintf(fp, " expires %dsec", ci->rta_expires / get_hz());
    268277            }
    269278            if (ci->rta_error != 0) {
     
    278287        fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF])));
    279288    }
    280     fprintf(fp, "\n");
     289    fputc('\n', fp);
    281290    fflush(fp);
    282291    return 0;
    283292}
    284293
     294/* Return value becomes exitcode. It's okay to not return at all */
    285295static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
    286296{
     297    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";
     300    enum {
     301        ARG_src,
     302        ARG_via,
     303        ARG_mtu, PARM_lock,
     304        ARG_protocol,
     305USE_FEATURE_IP_RULE(ARG_table,)
     306        ARG_dev,
     307        ARG_oif,
     308        ARG_to
     309    };
     310    enum {
     311        gw_ok = 1 << 0,
     312        dst_ok = 1 << 1,
     313        proto_ok = 1 << 2,
     314        type_ok = 1 << 3
     315    };
    287316    struct rtnl_handle rth;
    288317    struct {
     
    291320        char            buf[1024];
    292321    } req;
    293     char  mxbuf[256];
     322    char mxbuf[256];
    294323    struct rtattr * mxrta = (void*)mxbuf;
    295324    unsigned mxlock = 0;
    296     char  *d = NULL;
    297     int gw_ok = 0;
    298     int dst_ok = 0;
    299     int proto_ok = 0;
    300     int type_ok = 0;
     325    char *d = NULL;
     326    smalluint ok = 0;
     327    int arg;
    301328
    302329    memset(&req, 0, sizeof(req));
     
    319346
    320347    while (argc > 0) {
    321         if (strcmp(*argv, "src") == 0) {
     348        arg = index_in_substrings(keywords, *argv);
     349        if (arg == ARG_src) {
    322350            inet_prefix addr;
     351            NEXT_ARG();
     352            get_addr(&addr, *argv, req.r.rtm_family);
     353            if (req.r.rtm_family == AF_UNSPEC)
     354                req.r.rtm_family = addr.family;
     355            addattr_l(&req.n, sizeof(req), RTA_PREFSRC, &addr.data, addr.bytelen);
     356        } else if (arg == ARG_via) {
     357            inet_prefix addr;
     358            ok |= gw_ok;
    323359            NEXT_ARG();
    324360            get_addr(&addr, *argv, req.r.rtm_family);
     
    326362                req.r.rtm_family = addr.family;
    327363            }
    328             addattr_l(&req.n, sizeof(req), RTA_PREFSRC, &addr.data, addr.bytelen);
    329         } else if (strcmp(*argv, "via") == 0) {
    330             inet_prefix addr;
    331             gw_ok = 1;
    332             NEXT_ARG();
    333             get_addr(&addr, *argv, req.r.rtm_family);
    334             if (req.r.rtm_family == AF_UNSPEC) {
    335                 req.r.rtm_family = addr.family;
    336             }
    337364            addattr_l(&req.n, sizeof(req), RTA_GATEWAY, &addr.data, addr.bytelen);
    338         } else if (strcmp(*argv, "mtu") == 0) {
     365        } else if (arg == ARG_mtu) {
    339366            unsigned mtu;
    340367            NEXT_ARG();
    341             if (strcmp(*argv, "lock") == 0) {
     368            if (index_in_strings(keywords, *argv) == PARM_lock) {
    342369                mxlock |= (1<<RTAX_MTU);
    343370                NEXT_ARG();
    344371            }
    345             if (get_unsigned(&mtu, *argv, 0)) {
     372            if (get_unsigned(&mtu, *argv, 0))
    346373                invarg(*argv, "mtu");
    347             }
    348374            rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu);
    349         } else if (matches(*argv, "protocol") == 0) {
     375        } else if (arg == ARG_protocol) {
    350376            uint32_t prot;
    351377            NEXT_ARG();
     
    353379                invarg(*argv, "protocol");
    354380            req.r.rtm_protocol = prot;
    355             proto_ok =1;
    356         } else if (strcmp(*argv, "dev") == 0 ||
    357                strcmp(*argv, "oif") == 0) {
     381            ok |= proto_ok;
     382#if ENABLE_FEATURE_IP_RULE
     383        } else if (arg == ARG_table) {
     384            uint32_t tid;
     385            NEXT_ARG();
     386            if (rtnl_rttable_a2n(&tid, *argv))
     387                invarg(*argv, "table");
     388            req.r.rtm_table = tid;
     389#endif
     390        } else if (arg == ARG_dev || arg == ARG_oif) {
    358391            NEXT_ARG();
    359392            d = *argv;
     
    362395            inet_prefix dst;
    363396
    364             if (strcmp(*argv, "to") == 0) {
    365                 NEXT_ARG();
    366             }
    367             if ((**argv < '0' || **argv > '9') &&
    368                 rtnl_rtntype_a2n(&type, *argv) == 0) {
     397            if (arg == ARG_to) {
     398                NEXT_ARG();
     399            }
     400            if ((**argv < '0' || **argv > '9')
     401                && rtnl_rtntype_a2n(&type, *argv) == 0) {
    369402                NEXT_ARG();
    370403                req.r.rtm_type = type;
    371                 type_ok = 1;
    372             }
    373 
    374             if (dst_ok) {
     404                ok |= type_ok;
     405            }
     406
     407            if (ok & dst_ok) {
    375408                duparg2("to", *argv);
    376409            }
     
    380413            }
    381414            req.r.rtm_dst_len = dst.bitlen;
    382             dst_ok = 1;
     415            ok |= dst_ok;
    383416            if (dst.bytelen) {
    384417                addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen);
     
    388421    }
    389422
    390     if (rtnl_open(&rth, 0) < 0) {
    391         exit(1);
    392     }
     423    xrtnl_open(&rth);
    393424
    394425    if (d)  {
     
    398429
    399430        if (d) {
    400             if ((idx = ll_name_to_index(d)) == 0) {
    401                 bb_error_msg("Cannot find device \"%s\"", d);
    402                 return -1;
    403             }
     431            idx = xll_name_to_index(d);
    404432            addattr32(&req.n, sizeof(req), RTA_OIF, idx);
    405433        }
     
    413441    }
    414442
     443    if (req.r.rtm_type == RTN_LOCAL || req.r.rtm_type == RTN_NAT)
     444        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)
     448        req.r.rtm_scope = RT_SCOPE_LINK;
     449    else if (req.r.rtm_type == RTN_UNICAST || req.r.rtm_type == RTN_UNSPEC) {
     450        if (cmd == RTM_DELROUTE)
     451            req.r.rtm_scope = RT_SCOPE_NOWHERE;
     452        else if (!(ok & gw_ok))
     453            req.r.rtm_scope = RT_SCOPE_LINK;
     454    }
     455
    415456    if (req.r.rtm_family == AF_UNSPEC) {
    416457        req.r.rtm_family = AF_INET;
     
    418459
    419460    if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) {
    420         exit(2);
     461        return 2;
    421462    }
    422463
     
    444485    req.rtm.rtm_flags |= RTM_F_CLONED;
    445486
    446     return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr));
    447 }
    448 
    449 static int iproute_flush_cache(void)
    450 {
    451 #define ROUTE_FLUSH_PATH "/proc/sys/net/ipv4/route/flush"
    452 
    453     int len;
    454     int flush_fd = open (ROUTE_FLUSH_PATH, O_WRONLY);
    455     char *buffer = "-1";
     487    return xsendto(rth->fd, (void*)&req, sizeof(req), (struct sockaddr*)&nladdr, sizeof(nladdr));
     488}
     489
     490static void iproute_flush_cache(void)
     491{
     492    static const char fn[] ALIGN1 = "/proc/sys/net/ipv4/route/flush";
     493    int flush_fd = open_or_warn(fn, O_WRONLY);
    456494
    457495    if (flush_fd < 0) {
    458         fprintf (stderr, "Cannot open \"%s\"\n", ROUTE_FLUSH_PATH);
    459         return -1;
    460     }
    461 
    462     len = strlen (buffer);
    463 
    464     if ((write (flush_fd, (void *)buffer, len)) < len) {
    465         fprintf (stderr, "Cannot flush routing cache\n");
    466         return -1;
     496        return;
     497    }
     498
     499    if (write(flush_fd, "-1", 2) < 2) {
     500        bb_perror_msg("cannot flush routing cache");
     501        return;
    467502    }
    468503    close(flush_fd);
    469     return 0;
    470504}
    471505
     
    477511}
    478512
     513/* Return value becomes exitcode. It's okay to not return at all */
    479514static int iproute_list_or_flush(int argc, char **argv, int flush)
    480515{
     
    483518    char *id = NULL;
    484519    char *od = NULL;
    485 
     520    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*/;
     523    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*/
     532    };
     533    int arg, parm;
    486534    iproute_reset_filter();
    487535    filter.tb = RT_TABLE_MAIN;
    488536
    489     if (flush && argc <= 0) {
    490         bb_error_msg(bb_msg_requires_arg, "\"ip route flush\"");
    491         return -1;
    492     }
     537    if (flush && argc <= 0)
     538        bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\"");
    493539
    494540    while (argc > 0) {
    495         if (matches(*argv, "protocol") == 0) {
     541        arg = index_in_substrings(keywords, *argv);
     542        if (arg == ARG_proto) {
    496543            uint32_t prot = 0;
    497544            NEXT_ARG();
    498545            filter.protocolmask = -1;
    499546            if (rtnl_rtprot_a2n(&prot, *argv)) {
    500                 if (strcmp(*argv, "all") != 0) {
     547                if (index_in_strings(keywords, *argv) != PARM_all)
    501548                    invarg(*argv, "protocol");
    502                 }
    503549                prot = 0;
    504550                filter.protocolmask = 0;
    505551            }
    506552            filter.protocol = prot;
    507         } else if (strcmp(*argv, "dev") == 0 ||
    508                strcmp(*argv, "oif") == 0) {
     553        } else if (arg == ARG_dev || arg == ARG_oif) {
    509554            NEXT_ARG();
    510555            od = *argv;
    511         } else if (strcmp(*argv, "iif") == 0) {
     556        } else if (arg == ARG_iif) {
    512557            NEXT_ARG();
    513558            id = *argv;
    514         } else if (matches(*argv, "from") == 0) {
    515             NEXT_ARG();
    516             if (matches(*argv, "root") == 0) {
     559        } else if (arg == ARG_via) {
     560            NEXT_ARG();
     561            get_prefix(&filter.rvia, *argv, do_ipv6);
     562        } else if (arg == ARG_table) {
     563            NEXT_ARG();
     564            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
     570                invarg(*argv, "table");
     571        } else if (arg == ARG_from) {
     572            NEXT_ARG();
     573            parm = index_in_substrings(keywords, *argv);
     574            if (parm == PARM_root) {
    517575                NEXT_ARG();
    518576                get_prefix(&filter.rsrc, *argv, do_ipv6);
    519             } else if (matches(*argv, "match") == 0) {
     577            } else if (parm == PARM_match) {
    520578                NEXT_ARG();
    521579                get_prefix(&filter.msrc, *argv, do_ipv6);
    522580            } else {
    523                 if (matches(*argv, "exact") == 0) {
     581                if (parm == PARM_exact)
    524582                    NEXT_ARG();
    525                 }
    526583                get_prefix(&filter.msrc, *argv, do_ipv6);
    527584                filter.rsrc = filter.msrc;
    528585            }
    529586        } else {
    530             if (matches(*argv, "to") == 0) {
    531                 NEXT_ARG();
    532             }
    533             if (matches(*argv, "root") == 0) {
     587            /* parm = arg; // would be more plausible, we reuse arg here */
     588            if (arg == ARG_to) {
     589                NEXT_ARG();
     590                arg = index_in_substrings(keywords, *argv);
     591            }
     592            if (arg == PARM_root) {
    534593                NEXT_ARG();
    535594                get_prefix(&filter.rdst, *argv, do_ipv6);
    536             } else if (matches(*argv, "match") == 0) {
     595            } else if (arg == PARM_match) {
    537596                NEXT_ARG();
    538597                get_prefix(&filter.mdst, *argv, do_ipv6);
    539             } else if (matches(*argv, "table") == 0) {
    540                 NEXT_ARG();
    541                 if (matches(*argv, "cache") == 0) {
    542                     filter.tb = -1;
    543                 } else if (matches(*argv, "main") != 0) {
    544                     invarg(*argv, "table");
    545                 }
    546             } else if (matches(*argv, "cache") == 0) {
    547                 filter.tb = -1;
    548598            } else {
    549                 if (matches(*argv, "exact") == 0) {
     599                if (arg == PARM_exact)
    550600                    NEXT_ARG();
    551                 }
    552601                get_prefix(&filter.mdst, *argv, do_ipv6);
    553602                filter.rdst = filter.mdst;
    554603            }
    555604        }
    556         argc--; argv++;
     605        argc--;
     606        argv++;
    557607    }
    558608
     
    561611    }
    562612
    563     if (rtnl_open(&rth, 0) < 0) {
    564         exit(1);
    565     }
     613    xrtnl_open(&rth);
    566614
    567615    ll_init_map(&rth);
     
    571619
    572620        if (id) {
    573             if ((idx = ll_name_to_index(id)) == 0) {
    574                 bb_error_msg("Cannot find device \"%s\"", id);
    575                 return -1;
    576             }
     621            idx = xll_name_to_index(id);
    577622            filter.iif = idx;
    578623            filter.iifmask = -1;
    579624        }
    580625        if (od) {
    581             if ((idx = ll_name_to_index(od)) == 0) {
    582                 bb_error_msg("Cannot find device \"%s\"", od);
    583             }
     626            idx = xll_name_to_index(od);
    584627            filter.oif = idx;
    585628            filter.oifmask = -1;
     
    603646
    604647        for (;;) {
    605             if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) {
    606                 perror("Cannot send dump request");
    607                 return -1;
    608             }
     648            xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
    609649            filter.flushed = 0;
    610             if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {
    611                 bb_error_msg("Flush terminated\n");
    612                 return -1;
    613             }
    614             if (filter.flushed == 0) {
    615                 fflush(stdout);
     650            xrtnl_dump_filter(&rth, print_route, stdout);
     651            if (filter.flushed == 0)
    616652                return 0;
    617             }
    618             if (flush_update() < 0)
    619                 exit(1);
     653            if (flush_update())
     654                return 1;
    620655        }
    621656    }
    622657
    623658    if (filter.tb != -1) {
    624         if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) {
    625             bb_perror_msg_and_die("Cannot send dump request");
    626         }
    627     } else {
    628         if (rtnl_rtcache_request(&rth, do_ipv6) < 0) {
    629             bb_perror_msg_and_die("Cannot send dump request");
    630         }
    631     }
    632 
    633     if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {
    634         bb_error_msg_and_die("Dump terminated");
    635     }
    636 
    637     exit(0);
    638 }
    639 
    640 
     659        xrtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE);
     660    } 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);
     664
     665    return 0;
     666}
     667
     668
     669/* Return value becomes exitcode. It's okay to not return at all */
    641670static int iproute_get(int argc, char **argv)
    642671{
    643672    struct rtnl_handle rth;
    644673    struct {
    645         struct nlmsghdr     n;
    646         struct rtmsg        r;
    647         char            buf[1024];
     674        struct nlmsghdr n;
     675        struct rtmsg    r;
     676        char            buf[1024];
    648677    } req;
    649     char  *idev = NULL;
    650     char  *odev = NULL;
    651     int connected = 0;
    652     int from_ok = 0;
    653     static const char * const options[] =
    654         { "from", "iif", "oif", "dev", "notify", "connected", "to", 0 };
     678    char *idev = NULL;
     679    char *odev = NULL;
     680    bool connected = 0;
     681    bool from_ok = 0;
     682    static const char options[] ALIGN1 =
     683        "from\0""iif\0""oif\0""dev\0""notify\0""connected\0""to\0";
    655684
    656685    memset(&req, 0, sizeof(req));
     
    671700
    672701    while (argc > 0) {
    673         switch (compare_string_array(options, *argv)) {
     702        switch (index_in_strings(options, *argv)) {
    674703            case 0: /* from */
    675704            {
     
    724753    }
    725754
    726     if (rtnl_open(&rth, 0) < 0)
    727         exit(1);
     755    xrtnl_open(&rth);
    728756
    729757    ll_init_map(&rth);
     
    733761
    734762        if (idev) {
    735             if ((idx = ll_name_to_index(idev)) == 0) {
    736                 bb_error_msg("Cannot find device \"%s\"", idev);
    737                 return -1;
    738             }
     763            idx = xll_name_to_index(idev);
    739764            addattr32(&req.n, sizeof(req), RTA_IIF, idx);
    740765        }
    741766        if (odev) {
    742             if ((idx = ll_name_to_index(odev)) == 0) {
    743                 bb_error_msg("Cannot find device \"%s\"", odev);
    744                 return -1;
    745             }
     767            idx = xll_name_to_index(odev);
    746768            addattr32(&req.n, sizeof(req), RTA_OIF, idx);
    747769        }
     
    753775
    754776    if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) {
    755         exit(2);
     777        return 2;
    756778    }
    757779
     
    761783        struct rtattr * tb[RTA_MAX+1];
    762784
    763         if (print_route(NULL, &req.n, (void*)stdout) < 0) {
    764             bb_error_msg_and_die("An error :-)");
    765         }
     785        print_route(NULL, &req.n, (void*)stdout);
    766786
    767787        if (req.n.nlmsg_type != RTM_NEWROUTE) {
    768             bb_error_msg("Not a route?");
    769             return -1;
     788            bb_error_msg_and_die("not a route?");
    770789        }
    771790        len -= NLMSG_LENGTH(sizeof(*r));
    772791        if (len < 0) {
    773             bb_error_msg("Wrong len %d", len);
    774             return -1;
     792            bb_error_msg_and_die("wrong len %d", len);
    775793        }
    776794
     
    782800            r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]);
    783801        } else if (!tb[RTA_SRC]) {
    784             bb_error_msg("Failed to connect the route");
    785             return -1;
     802            bb_error_msg_and_die("failed to connect the route");
    786803        }
    787804        if (!odev && tb[RTA_OIF]) {
     
    798815
    799816        if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) {
    800             exit(2);
    801         }
    802     }
    803 
    804     if (print_route(NULL, &req.n, (void*)stdout) < 0) {
    805         bb_error_msg_and_die("An error :-)");
    806     }
    807 
    808     exit(0);
    809 }
    810 
     817            return 2;
     818        }
     819    }
     820    print_route(NULL, &req.n, (void*)stdout);
     821    return 0;
     822}
     823
     824/* Return value becomes exitcode. It's okay to not return at all */
    811825int do_iproute(int argc, char **argv)
    812826{
    813     static const char * const ip_route_commands[] =
    814         { "add", "append", "change", "chg", "delete", "del", "get",
    815         "list", "show", "prepend", "replace", "test", "flush", 0 };
    816     int command_num = 7;
    817     unsigned int flags = 0;
     827    static const char ip_route_commands[] ALIGN1 =
     828    /*0-3*/ "add\0""append\0""change\0""chg\0"
     829    /*4-7*/ "delete\0""get\0""list\0""show\0"
     830    /*8..*/ "prepend\0""replace\0""test\0""flush\0";
     831    int command_num = 6;
     832    unsigned flags = 0;
    818833    int cmd = RTM_NEWROUTE;
    819834
     835    /* "Standard" 'ip r a' treats 'a' as 'add', not 'append' */
     836    /* It probably means that it is using "first match" rule */
    820837    if (*argv) {
    821         command_num = compare_string_array(ip_route_commands, *argv);
    822     }
    823     switch(command_num) {
    824         case 0: /* add*/
     838        command_num = index_in_substrings(ip_route_commands, *argv);
     839    }
     840    switch (command_num) {
     841        case 0: /* add */
    825842            flags = NLM_F_CREATE|NLM_F_EXCL;
    826843            break;
     
    833850            break;
    834851        case 4: /* delete */
    835         case 5: /* del */
    836852            cmd = RTM_DELROUTE;
    837853            break;
    838         case 6: /* get */
     854        case 5: /* get */
    839855            return iproute_get(argc-1, argv+1);
    840         case 7: /* list */
    841         case 8: /* show */
     856        case 6: /* list */
     857        case 7: /* show */
    842858            return iproute_list_or_flush(argc-1, argv+1, 0);
    843         case 9: /* prepend */
     859        case 8: /* prepend */
    844860            flags = NLM_F_CREATE;
    845         case 10: /* replace */
     861        case 9: /* replace */
    846862            flags = NLM_F_CREATE|NLM_F_REPLACE;
    847         case 11: /* test */
     863        case 10: /* test */
    848864            flags = NLM_F_EXCL;
    849         case 12: /* flush */
     865        case 11: /* flush */
    850866            return iproute_list_or_flush(argc-1, argv+1, 1);
    851867        default:
    852             bb_error_msg_and_die("Unknown command %s", *argv);
     868            bb_error_msg_and_die("unknown command %s", *argv);
    853869    }
    854870
Note: See TracChangeset for help on using the changeset viewer.