Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/networking/libiproute/iproute.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/networking/libiproute/iproute.c
r821 r1770 14 14 */ 15 15 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 */ 24 17 #include "rt_names.h" 25 18 #include "utils.h" 26 #include "ip_common.h"27 19 28 20 #ifndef RTAX_RTTVAR … … 31 23 32 24 33 static struct 34 { 25 typedef struct filter_t { 35 26 int tb; 36 27 int flushed; … … 52 43 inet_prefix rsrc; 53 44 inet_prefix msrc; 54 } filter; 45 } filter_t; 46 47 #define filter (*(filter_t*)&bb_common_bufsiz1) 55 48 56 49 static int flush_update(void) 57 50 { 58 51 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"); 60 53 return -1; 61 54 } 62 55 filter.flushp = 0; 63 56 return 0; 57 } 58 59 static 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; 64 79 } 65 80 … … 86 101 return 0; 87 102 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); 92 105 93 106 if (r->rtm_family == AF_INET6) … … 170 183 if (NLMSG_ALIGN(filter.flushp) + n->nlmsg_len > filter.flushe) { 171 184 if (flush_update()) 172 return -1;185 bb_error_msg_and_die("flush"); 173 186 } 174 187 fn = (struct nlmsghdr*)(filter.flushb + NLMSG_ALIGN(filter.flushp)); … … 249 262 } 250 263 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])); 252 265 } 253 266 if (r->rtm_family == AF_INET6) { … … 257 270 } 258 271 if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) { 259 static int hz;260 if (!hz) {261 hz = get_hz();262 }263 272 if (r->rtm_flags & RTM_F_CLONED) { 264 fprintf(fp, "% scache ", _SL_);273 fprintf(fp, "%c cache ", _SL_); 265 274 } 266 275 if (ci->rta_expires) { 267 fprintf(fp, " expires %dsec", ci->rta_expires /hz);276 fprintf(fp, " expires %dsec", ci->rta_expires / get_hz()); 268 277 } 269 278 if (ci->rta_error != 0) { … … 278 287 fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF]))); 279 288 } 280 fp rintf(fp, "\n");289 fputc('\n', fp); 281 290 fflush(fp); 282 291 return 0; 283 292 } 284 293 294 /* Return value becomes exitcode. It's okay to not return at all */ 285 295 static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) 286 296 { 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, 305 USE_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 }; 287 316 struct rtnl_handle rth; 288 317 struct { … … 291 320 char buf[1024]; 292 321 } req; 293 char 322 char mxbuf[256]; 294 323 struct rtattr * mxrta = (void*)mxbuf; 295 324 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; 301 328 302 329 memset(&req, 0, sizeof(req)); … … 319 346 320 347 while (argc > 0) { 321 if (strcmp(*argv, "src") == 0) { 348 arg = index_in_substrings(keywords, *argv); 349 if (arg == ARG_src) { 322 350 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; 323 359 NEXT_ARG(); 324 360 get_addr(&addr, *argv, req.r.rtm_family); … … 326 362 req.r.rtm_family = addr.family; 327 363 } 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 }337 364 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) { 339 366 unsigned mtu; 340 367 NEXT_ARG(); 341 if ( strcmp(*argv, "lock") == 0) {368 if (index_in_strings(keywords, *argv) == PARM_lock) { 342 369 mxlock |= (1<<RTAX_MTU); 343 370 NEXT_ARG(); 344 371 } 345 if (get_unsigned(&mtu, *argv, 0)) {372 if (get_unsigned(&mtu, *argv, 0)) 346 373 invarg(*argv, "mtu"); 347 }348 374 rta_addattr32(mxrta, sizeof(mxbuf), RTAX_MTU, mtu); 349 } else if ( matches(*argv, "protocol") == 0) {375 } else if (arg == ARG_protocol) { 350 376 uint32_t prot; 351 377 NEXT_ARG(); … … 353 379 invarg(*argv, "protocol"); 354 380 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) { 358 391 NEXT_ARG(); 359 392 d = *argv; … … 362 395 inet_prefix dst; 363 396 364 if ( strcmp(*argv, "to") == 0) {365 NEXT_ARG(); 366 } 367 if ((**argv < '0' || **argv > '9') &&368 397 if (arg == ARG_to) { 398 NEXT_ARG(); 399 } 400 if ((**argv < '0' || **argv > '9') 401 && rtnl_rtntype_a2n(&type, *argv) == 0) { 369 402 NEXT_ARG(); 370 403 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) { 375 408 duparg2("to", *argv); 376 409 } … … 380 413 } 381 414 req.r.rtm_dst_len = dst.bitlen; 382 dst_ok = 1;415 ok |= dst_ok; 383 416 if (dst.bytelen) { 384 417 addattr_l(&req.n, sizeof(req), RTA_DST, &dst.data, dst.bytelen); … … 388 421 } 389 422 390 if (rtnl_open(&rth, 0) < 0) { 391 exit(1); 392 } 423 xrtnl_open(&rth); 393 424 394 425 if (d) { … … 398 429 399 430 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); 404 432 addattr32(&req.n, sizeof(req), RTA_OIF, idx); 405 433 } … … 413 441 } 414 442 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 415 456 if (req.r.rtm_family == AF_UNSPEC) { 416 457 req.r.rtm_family = AF_INET; … … 418 459 419 460 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) { 420 exit(2);461 return 2; 421 462 } 422 463 … … 444 485 req.rtm.rtm_flags |= RTM_F_CLONED; 445 486 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 490 static 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); 456 494 457 495 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; 467 502 } 468 503 close(flush_fd); 469 return 0;470 504 } 471 505 … … 477 511 } 478 512 513 /* Return value becomes exitcode. It's okay to not return at all */ 479 514 static int iproute_list_or_flush(int argc, char **argv, int flush) 480 515 { … … 483 518 char *id = NULL; 484 519 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; 486 534 iproute_reset_filter(); 487 535 filter.tb = RT_TABLE_MAIN; 488 536 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\""); 493 539 494 540 while (argc > 0) { 495 if (matches(*argv, "protocol") == 0) { 541 arg = index_in_substrings(keywords, *argv); 542 if (arg == ARG_proto) { 496 543 uint32_t prot = 0; 497 544 NEXT_ARG(); 498 545 filter.protocolmask = -1; 499 546 if (rtnl_rtprot_a2n(&prot, *argv)) { 500 if ( strcmp(*argv, "all") != 0) {547 if (index_in_strings(keywords, *argv) != PARM_all) 501 548 invarg(*argv, "protocol"); 502 }503 549 prot = 0; 504 550 filter.protocolmask = 0; 505 551 } 506 552 filter.protocol = prot; 507 } else if (strcmp(*argv, "dev") == 0 || 508 strcmp(*argv, "oif") == 0) { 553 } else if (arg == ARG_dev || arg == ARG_oif) { 509 554 NEXT_ARG(); 510 555 od = *argv; 511 } else if ( strcmp(*argv, "iif") == 0) {556 } else if (arg == ARG_iif) { 512 557 NEXT_ARG(); 513 558 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) { 517 575 NEXT_ARG(); 518 576 get_prefix(&filter.rsrc, *argv, do_ipv6); 519 } else if ( matches(*argv, "match") == 0) {577 } else if (parm == PARM_match) { 520 578 NEXT_ARG(); 521 579 get_prefix(&filter.msrc, *argv, do_ipv6); 522 580 } else { 523 if ( matches(*argv, "exact") == 0) {581 if (parm == PARM_exact) 524 582 NEXT_ARG(); 525 }526 583 get_prefix(&filter.msrc, *argv, do_ipv6); 527 584 filter.rsrc = filter.msrc; 528 585 } 529 586 } 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) { 534 593 NEXT_ARG(); 535 594 get_prefix(&filter.rdst, *argv, do_ipv6); 536 } else if ( matches(*argv, "match") == 0) {595 } else if (arg == PARM_match) { 537 596 NEXT_ARG(); 538 597 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;548 598 } else { 549 if ( matches(*argv, "exact") == 0) {599 if (arg == PARM_exact) 550 600 NEXT_ARG(); 551 }552 601 get_prefix(&filter.mdst, *argv, do_ipv6); 553 602 filter.rdst = filter.mdst; 554 603 } 555 604 } 556 argc--; argv++; 605 argc--; 606 argv++; 557 607 } 558 608 … … 561 611 } 562 612 563 if (rtnl_open(&rth, 0) < 0) { 564 exit(1); 565 } 613 xrtnl_open(&rth); 566 614 567 615 ll_init_map(&rth); … … 571 619 572 620 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); 577 622 filter.iif = idx; 578 623 filter.iifmask = -1; 579 624 } 580 625 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); 584 627 filter.oif = idx; 585 628 filter.oifmask = -1; … … 603 646 604 647 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); 609 649 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) 616 652 return 0; 617 } 618 if (flush_update() < 0) 619 exit(1); 653 if (flush_update()) 654 return 1; 620 655 } 621 656 } 622 657 623 658 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 */ 641 670 static int iproute_get(int argc, char **argv) 642 671 { 643 672 struct rtnl_handle rth; 644 673 struct { 645 struct nlmsghdr 646 struct rtmsg 647 char 674 struct nlmsghdr n; 675 struct rtmsg r; 676 char buf[1024]; 648 677 } req; 649 char 650 char 651 intconnected = 0;652 intfrom_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"; 655 684 656 685 memset(&req, 0, sizeof(req)); … … 671 700 672 701 while (argc > 0) { 673 switch ( compare_string_array(options, *argv)) {702 switch (index_in_strings(options, *argv)) { 674 703 case 0: /* from */ 675 704 { … … 724 753 } 725 754 726 if (rtnl_open(&rth, 0) < 0) 727 exit(1); 755 xrtnl_open(&rth); 728 756 729 757 ll_init_map(&rth); … … 733 761 734 762 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); 739 764 addattr32(&req.n, sizeof(req), RTA_IIF, idx); 740 765 } 741 766 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); 746 768 addattr32(&req.n, sizeof(req), RTA_OIF, idx); 747 769 } … … 753 775 754 776 if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) { 755 exit(2);777 return 2; 756 778 } 757 779 … … 761 783 struct rtattr * tb[RTA_MAX+1]; 762 784 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); 766 786 767 787 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?"); 770 789 } 771 790 len -= NLMSG_LENGTH(sizeof(*r)); 772 791 if (len < 0) { 773 bb_error_msg("Wrong len %d", len); 774 return -1; 792 bb_error_msg_and_die("wrong len %d", len); 775 793 } 776 794 … … 782 800 r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]); 783 801 } 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"); 786 803 } 787 804 if (!odev && tb[RTA_OIF]) { … … 798 815 799 816 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 */ 811 825 int do_iproute(int argc, char **argv) 812 826 { 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; 818 833 int cmd = RTM_NEWROUTE; 819 834 835 /* "Standard" 'ip r a' treats 'a' as 'add', not 'append' */ 836 /* It probably means that it is using "first match" rule */ 820 837 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 */ 825 842 flags = NLM_F_CREATE|NLM_F_EXCL; 826 843 break; … … 833 850 break; 834 851 case 4: /* delete */ 835 case 5: /* del */836 852 cmd = RTM_DELROUTE; 837 853 break; 838 case 6: /* get */854 case 5: /* get */ 839 855 return iproute_get(argc-1, argv+1); 840 case 7: /* list */841 case 8: /* show */856 case 6: /* list */ 857 case 7: /* show */ 842 858 return iproute_list_or_flush(argc-1, argv+1, 0); 843 case 9: /* prepend */859 case 8: /* prepend */ 844 860 flags = NLM_F_CREATE; 845 case 10: /* replace */861 case 9: /* replace */ 846 862 flags = NLM_F_CREATE|NLM_F_REPLACE; 847 case 1 1: /* test */863 case 10: /* test */ 848 864 flags = NLM_F_EXCL; 849 case 1 2: /* flush */865 case 11: /* flush */ 850 866 return iproute_list_or_flush(argc-1, argv+1, 1); 851 867 default: 852 bb_error_msg_and_die(" Unknown command %s", *argv);868 bb_error_msg_and_die("unknown command %s", *argv); 853 869 } 854 870
Note:
See TracChangeset
for help on using the changeset viewer.