summaryrefslogtreecommitdiff
path: root/networking/libiproute/iproute.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/libiproute/iproute.c')
-rw-r--r--networking/libiproute/iproute.c107
1 files changed, 54 insertions, 53 deletions
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index 27d37ac79..bb0bfaed1 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -24,8 +24,7 @@
24#endif 24#endif
25 25
26 26
27static struct 27typedef struct filter_t {
28{
29 int tb; 28 int tb;
30 int flushed; 29 int flushed;
31 char *flushb; 30 char *flushb;
@@ -45,12 +44,14 @@ static struct
45 inet_prefix mdst; 44 inet_prefix mdst;
46 inet_prefix rsrc; 45 inet_prefix rsrc;
47 inet_prefix msrc; 46 inet_prefix msrc;
48} filter; 47} filter_t;
48
49#define filter (*(filter_t*)&bb_common_bufsiz1)
49 50
50static int flush_update(void) 51static int flush_update(void)
51{ 52{
52 if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) { 53 if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) {
53 perror("Failed to send flush request\n"); 54 bb_perror_msg("failed to send flush request");
54 return -1; 55 return -1;
55 } 56 }
56 filter.flushp = 0; 57 filter.flushp = 0;
@@ -273,7 +274,7 @@ static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
273 } 274 }
274 if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) { 275 if ((r->rtm_flags & RTM_F_CLONED) || (ci && ci->rta_expires)) {
275 if (r->rtm_flags & RTM_F_CLONED) { 276 if (r->rtm_flags & RTM_F_CLONED) {
276 fprintf(fp, "%s cache ", _SL_); 277 fprintf(fp, "%c cache ", _SL_);
277 } 278 }
278 if (ci->rta_expires) { 279 if (ci->rta_expires) {
279 fprintf(fp, " expires %dsec", ci->rta_expires / get_hz()); 280 fprintf(fp, " expires %dsec", ci->rta_expires / get_hz());
@@ -289,11 +290,12 @@ static int print_route(struct sockaddr_nl *who ATTRIBUTE_UNUSED,
289 if (tb[RTA_IIF] && filter.iifmask != -1) { 290 if (tb[RTA_IIF] && filter.iifmask != -1) {
290 fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF]))); 291 fprintf(fp, " iif %s", ll_index_to_name(*(int*)RTA_DATA(tb[RTA_IIF])));
291 } 292 }
292 fprintf(fp, "\n"); 293 fputc('\n', fp);
293 fflush(fp); 294 fflush(fp);
294 return 0; 295 return 0;
295} 296}
296 297
298/* Return value becomes exitcode. It's okay to not return at all */
297static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) 299static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
298{ 300{
299 struct rtnl_handle rth; 301 struct rtnl_handle rth;
@@ -302,10 +304,10 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
302 struct rtmsg r; 304 struct rtmsg r;
303 char buf[1024]; 305 char buf[1024];
304 } req; 306 } req;
305 char mxbuf[256]; 307 char mxbuf[256];
306 struct rtattr * mxrta = (void*)mxbuf; 308 struct rtattr * mxrta = (void*)mxbuf;
307 unsigned mxlock = 0; 309 unsigned mxlock = 0;
308 char *d = NULL; 310 char *d = NULL;
309 int gw_ok = 0; 311 int gw_ok = 0;
310 int dst_ok = 0; 312 int dst_ok = 0;
311 int proto_ok = 0; 313 int proto_ok = 0;
@@ -384,8 +386,9 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
384 if (strcmp(*argv, "to") == 0) { 386 if (strcmp(*argv, "to") == 0) {
385 NEXT_ARG(); 387 NEXT_ARG();
386 } 388 }
387 if ((**argv < '0' || **argv > '9') && 389 if ((**argv < '0' || **argv > '9')
388 rtnl_rtntype_a2n(&type, *argv) == 0) { 390 && rtnl_rtntype_a2n(&type, *argv) == 0
391 ) {
389 NEXT_ARG(); 392 NEXT_ARG();
390 req.r.rtm_type = type; 393 req.r.rtm_type = type;
391 type_ok = 1; 394 type_ok = 1;
@@ -408,7 +411,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
408 } 411 }
409 412
410 if (rtnl_open(&rth, 0) < 0) { 413 if (rtnl_open(&rth, 0) < 0) {
411 exit(1); 414 return 1;
412 } 415 }
413 416
414 if (d) { 417 if (d) {
@@ -419,8 +422,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
419 if (d) { 422 if (d) {
420 idx = ll_name_to_index(d); 423 idx = ll_name_to_index(d);
421 if (idx == 0) { 424 if (idx == 0) {
422 bb_error_msg("cannot find device \"%s\"", d); 425 bb_error_msg_and_die("cannot find device \"%s\"", d);
423 return -1;
424 } 426 }
425 addattr32(&req.n, sizeof(req), RTA_OIF, idx); 427 addattr32(&req.n, sizeof(req), RTA_OIF, idx);
426 } 428 }
@@ -438,7 +440,7 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
438 } 440 }
439 441
440 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) { 442 if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) {
441 exit(2); 443 return 2;
442 } 444 }
443 445
444 return 0; 446 return 0;
@@ -467,21 +469,21 @@ static int rtnl_rtcache_request(struct rtnl_handle *rth, int family)
467 return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr)); 469 return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr));
468} 470}
469 471
470static int iproute_flush_cache(void) 472static void iproute_flush_cache(void)
471{ 473{
472 static const char fn[] = "/proc/sys/net/ipv4/route/flush"; 474 static const char fn[] = "/proc/sys/net/ipv4/route/flush";
473 int flush_fd = open(fn, O_WRONLY); 475 int flush_fd = open(fn, O_WRONLY);
476
474 if (flush_fd < 0) { 477 if (flush_fd < 0) {
475 bb_perror_msg("cannot open '%s'", fn); 478 bb_perror_msg("cannot open '%s'", fn);
476 return -1; 479 return;
477 } 480 }
478 481
479 if (write(flush_fd, "-1", 2) < 2) { 482 if (write(flush_fd, "-1", 2) < 2) {
480 bb_perror_msg("cannot flush routing cache"); 483 bb_perror_msg("cannot flush routing cache");
481 return -1; 484 return;
482 } 485 }
483 close(flush_fd); 486 close(flush_fd);
484 return 0;
485} 487}
486 488
487static void iproute_reset_filter(void) 489static void iproute_reset_filter(void)
@@ -491,6 +493,7 @@ static void iproute_reset_filter(void)
491 filter.msrc.bitlen = -1; 493 filter.msrc.bitlen = -1;
492} 494}
493 495
496/* Return value becomes exitcode. It's okay to not return at all */
494static int iproute_list_or_flush(int argc, char **argv, int flush) 497static int iproute_list_or_flush(int argc, char **argv, int flush)
495{ 498{
496 int do_ipv6 = preferred_family; 499 int do_ipv6 = preferred_family;
@@ -501,10 +504,8 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
501 iproute_reset_filter(); 504 iproute_reset_filter();
502 filter.tb = RT_TABLE_MAIN; 505 filter.tb = RT_TABLE_MAIN;
503 506
504 if (flush && argc <= 0) { 507 if (flush && argc <= 0)
505 bb_error_msg(bb_msg_requires_arg, "\"ip route flush\""); 508 bb_error_msg_and_die(bb_msg_requires_arg, "\"ip route flush\"");
506 return -1;
507 }
508 509
509 while (argc > 0) { 510 while (argc > 0) {
510 if (matches(*argv, "protocol") == 0) { 511 if (matches(*argv, "protocol") == 0) {
@@ -572,7 +573,8 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
572 filter.rdst = filter.mdst; 573 filter.rdst = filter.mdst;
573 } 574 }
574 } 575 }
575 argc--; argv++; 576 argc--;
577 argv++;
576 } 578 }
577 579
578 if (do_ipv6 == AF_UNSPEC && filter.tb) { 580 if (do_ipv6 == AF_UNSPEC && filter.tb) {
@@ -580,7 +582,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
580 } 582 }
581 583
582 if (rtnl_open(&rth, 0) < 0) { 584 if (rtnl_open(&rth, 0) < 0) {
583 exit(1); 585 return 1;
584 } 586 }
585 587
586 ll_init_map(&rth); 588 ll_init_map(&rth);
@@ -589,15 +591,16 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
589 int idx; 591 int idx;
590 592
591 if (id) { 593 if (id) {
592 if ((idx = ll_name_to_index(id)) == 0) { 594 idx = ll_name_to_index(id);
593 bb_error_msg("cannot find device \"%s\"", id); 595 if (idx == 0) {
594 return -1; 596 bb_error_msg_and_die("cannot find device \"%s\"", id);
595 } 597 }
596 filter.iif = idx; 598 filter.iif = idx;
597 filter.iifmask = -1; 599 filter.iifmask = -1;
598 } 600 }
599 if (od) { 601 if (od) {
600 if ((idx = ll_name_to_index(od)) == 0) { 602 idx = ll_name_to_index(od);
603 if (idx == 0) {
601 bb_error_msg("cannot find device \"%s\"", od); 604 bb_error_msg("cannot find device \"%s\"", od);
602 } 605 }
603 filter.oif = idx; 606 filter.oif = idx;
@@ -622,20 +625,17 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
622 625
623 for (;;) { 626 for (;;) {
624 if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) { 627 if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) {
625 perror("Cannot send dump request"); 628 bb_perror_msg_and_die("cannot send dump request");
626 return -1;
627 } 629 }
628 filter.flushed = 0; 630 filter.flushed = 0;
629 if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) { 631 if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {
630 bb_error_msg("flush terminated"); 632 bb_error_msg_and_die("flush terminated");
631 return -1;
632 } 633 }
633 if (filter.flushed == 0) { 634 if (filter.flushed == 0) {
634 fflush(stdout);
635 return 0; 635 return 0;
636 } 636 }
637 if (flush_update() < 0) 637 if (flush_update())
638 exit(1); 638 return 1;
639 } 639 }
640 } 640 }
641 641
@@ -653,10 +653,11 @@ static int iproute_list_or_flush(int argc, char **argv, int flush)
653 bb_error_msg_and_die("dump terminated"); 653 bb_error_msg_and_die("dump terminated");
654 } 654 }
655 655
656 exit(0); 656 return 0;
657} 657}
658 658
659 659
660/* Return value becomes exitcode. It's okay to not return at all */
660static int iproute_get(int argc, char **argv) 661static int iproute_get(int argc, char **argv)
661{ 662{
662 struct rtnl_handle rth; 663 struct rtnl_handle rth;
@@ -734,7 +735,8 @@ static int iproute_get(int argc, char **argv)
734 } 735 }
735 req.r.rtm_dst_len = addr.bitlen; 736 req.r.rtm_dst_len = addr.bitlen;
736 } 737 }
737 argc--; argv++; 738 argc--;
739 argv++;
738 } 740 }
739 } 741 }
740 742
@@ -743,7 +745,7 @@ static int iproute_get(int argc, char **argv)
743 } 745 }
744 746
745 if (rtnl_open(&rth, 0) < 0) 747 if (rtnl_open(&rth, 0) < 0)
746 exit(1); 748 return 1;
747 749
748 ll_init_map(&rth); 750 ll_init_map(&rth);
749 751
@@ -751,16 +753,16 @@ static int iproute_get(int argc, char **argv)
751 int idx; 753 int idx;
752 754
753 if (idev) { 755 if (idev) {
754 if ((idx = ll_name_to_index(idev)) == 0) { 756 idx = ll_name_to_index(idev);
755 bb_error_msg("cannot find device \"%s\"", idev); 757 if (idx == 0) {
756 return -1; 758 bb_error_msg_and_die("cannot find device \"%s\"", idev);
757 } 759 }
758 addattr32(&req.n, sizeof(req), RTA_IIF, idx); 760 addattr32(&req.n, sizeof(req), RTA_IIF, idx);
759 } 761 }
760 if (odev) { 762 if (odev) {
761 if ((idx = ll_name_to_index(odev)) == 0) { 763 idx = ll_name_to_index(odev);
762 bb_error_msg("cannot find device \"%s\"", odev); 764 if (idx == 0) {
763 return -1; 765 bb_error_msg_and_die("cannot find device \"%s\"", odev);
764 } 766 }
765 addattr32(&req.n, sizeof(req), RTA_OIF, idx); 767 addattr32(&req.n, sizeof(req), RTA_OIF, idx);
766 } 768 }
@@ -771,7 +773,7 @@ static int iproute_get(int argc, char **argv)
771 } 773 }
772 774
773 if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) { 775 if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) {
774 exit(2); 776 return 2;
775 } 777 }
776 778
777 if (connected && !from_ok) { 779 if (connected && !from_ok) {
@@ -784,13 +786,11 @@ static int iproute_get(int argc, char **argv)
784 } 786 }
785 787
786 if (req.n.nlmsg_type != RTM_NEWROUTE) { 788 if (req.n.nlmsg_type != RTM_NEWROUTE) {
787 bb_error_msg("not a route?"); 789 bb_error_msg_and_die("not a route?");
788 return -1;
789 } 790 }
790 len -= NLMSG_LENGTH(sizeof(*r)); 791 len -= NLMSG_LENGTH(sizeof(*r));
791 if (len < 0) { 792 if (len < 0) {
792 bb_error_msg("wrong len %d", len); 793 bb_error_msg_and_die("wrong len %d", len);
793 return -1;
794 } 794 }
795 795
796 memset(tb, 0, sizeof(tb)); 796 memset(tb, 0, sizeof(tb));
@@ -800,8 +800,7 @@ static int iproute_get(int argc, char **argv)
800 tb[RTA_PREFSRC]->rta_type = RTA_SRC; 800 tb[RTA_PREFSRC]->rta_type = RTA_SRC;
801 r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]); 801 r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]);
802 } else if (!tb[RTA_SRC]) { 802 } else if (!tb[RTA_SRC]) {
803 bb_error_msg("failed to connect the route"); 803 bb_error_msg_and_die("failed to connect the route");
804 return -1;
805 } 804 }
806 if (!odev && tb[RTA_OIF]) { 805 if (!odev && tb[RTA_OIF]) {
807 tb[RTA_OIF]->rta_type = 0; 806 tb[RTA_OIF]->rta_type = 0;
@@ -816,17 +815,19 @@ static int iproute_get(int argc, char **argv)
816 req.n.nlmsg_type = RTM_GETROUTE; 815 req.n.nlmsg_type = RTM_GETROUTE;
817 816
818 if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) { 817 if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) {
819 exit(2); 818 return 2;
820 } 819 }
821 } 820 }
822 821
823 if (print_route(NULL, &req.n, (void*)stdout) < 0) { 822 if (print_route(NULL, &req.n, (void*)stdout) < 0) {
823// how is this useful?
824 bb_error_msg_and_die("an error :-)"); 824 bb_error_msg_and_die("an error :-)");
825 } 825 }
826 826
827 exit(0); 827 return 0;
828} 828}
829 829
830/* Return value becomes exitcode. It's okay to not return at all */
830int do_iproute(int argc, char **argv) 831int do_iproute(int argc, char **argv)
831{ 832{
832 static const char * const ip_route_commands[] = { 833 static const char * const ip_route_commands[] = {