diff options
author | Christian Eggers <ceggers@arri.de> | 2020-06-29 17:57:26 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-07-31 18:48:50 +0200 |
commit | 8a485b0a363935309f976866b8a30988362fadc0 (patch) | |
tree | 96ba6cde1ef879fc4dd7616e20de3c5b189eea90 | |
parent | 31d34f3bd8b0cc41db5e893942d9dc5c14e4dd3c (diff) | |
download | busybox-w32-8a485b0a363935309f976866b8a30988362fadc0.tar.gz busybox-w32-8a485b0a363935309f976866b8a30988362fadc0.tar.bz2 busybox-w32-8a485b0a363935309f976866b8a30988362fadc0.zip |
ip address: Add support for "valid_lft" and "preferred_lft" options
Signed-off-by: Christian Eggers <ceggers@arri.de>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/libiproute/ip_common.h | 4 | ||||
-rw-r--r-- | networking/libiproute/ipaddress.c | 65 |
2 files changed, 62 insertions, 7 deletions
diff --git a/networking/libiproute/ip_common.h b/networking/libiproute/ip_common.h index 40171bed9..894e380f8 100644 --- a/networking/libiproute/ip_common.h +++ b/networking/libiproute/ip_common.h | |||
@@ -33,4 +33,8 @@ int FAST_FUNC do_iplink(char **argv); | |||
33 | 33 | ||
34 | POP_SAVED_FUNCTION_VISIBILITY | 34 | POP_SAVED_FUNCTION_VISIBILITY |
35 | 35 | ||
36 | #ifndef INFINITY_LIFE_TIME | ||
37 | #define INFINITY_LIFE_TIME 0xFFFFFFFFU | ||
38 | #endif | ||
39 | |||
36 | #endif | 40 | #endif |
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c index 6cfd3c398..71e8fb6a7 100644 --- a/networking/libiproute/ipaddress.c +++ b/networking/libiproute/ipaddress.c | |||
@@ -592,6 +592,14 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush) | |||
592 | return 0; | 592 | return 0; |
593 | } | 593 | } |
594 | 594 | ||
595 | static void set_lifetime(unsigned int *lifetime, char *argv, const char *errmsg) | ||
596 | { | ||
597 | if (strcmp(argv, "forever") == 0) | ||
598 | *lifetime = INFINITY_LIFE_TIME; | ||
599 | else | ||
600 | *lifetime = get_u32(argv, errmsg); | ||
601 | } | ||
602 | |||
595 | static int default_scope(inet_prefix *lcl) | 603 | static int default_scope(inet_prefix *lcl) |
596 | { | 604 | { |
597 | if (lcl->family == AF_INET) { | 605 | if (lcl->family == AF_INET) { |
@@ -607,10 +615,13 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
607 | /* If you add stuff here, update ipaddr_full_usage */ | 615 | /* If you add stuff here, update ipaddr_full_usage */ |
608 | static const char option[] ALIGN1 = | 616 | static const char option[] ALIGN1 = |
609 | "peer\0""remote\0""broadcast\0""brd\0" | 617 | "peer\0""remote\0""broadcast\0""brd\0" |
610 | "anycast\0""scope\0""dev\0""label\0""noprefixroute\0""local\0"; | 618 | "anycast\0""valid_lft\0""preferred_lft\0" |
619 | "scope\0""dev\0""label\0""noprefixroute\0""local\0"; | ||
611 | #define option_peer option | 620 | #define option_peer option |
612 | #define option_broadcast (option + sizeof("peer") + sizeof("remote")) | 621 | #define option_broadcast (option + sizeof("peer") + sizeof("remote")) |
613 | #define option_anycast (option_broadcast + sizeof("broadcast") + sizeof("brd")) | 622 | #define option_anycast (option_broadcast + sizeof("broadcast") + sizeof("brd")) |
623 | #define option_valid_lft (option_anycast + sizeof("anycast")) | ||
624 | #define option_pref_lft (option_valid_lft + sizeof("valid_lft")) | ||
614 | struct rtnl_handle rth; | 625 | struct rtnl_handle rth; |
615 | struct { | 626 | struct { |
616 | struct nlmsghdr n; | 627 | struct nlmsghdr n; |
@@ -619,6 +630,8 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
619 | } req; | 630 | } req; |
620 | char *d = NULL; | 631 | char *d = NULL; |
621 | char *l = NULL; | 632 | char *l = NULL; |
633 | char *valid_lftp = NULL; | ||
634 | char *preferred_lftp = NULL; | ||
622 | inet_prefix lcl; | 635 | inet_prefix lcl; |
623 | inet_prefix peer; | 636 | inet_prefix peer; |
624 | int local_len = 0; | 637 | int local_len = 0; |
@@ -626,6 +639,8 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
626 | int brd_len = 0; | 639 | int brd_len = 0; |
627 | int any_len = 0; | 640 | int any_len = 0; |
628 | bool scoped = 0; | 641 | bool scoped = 0; |
642 | __u32 valid_lft = INFINITY_LIFE_TIME; | ||
643 | __u32 preferred_lft = INFINITY_LIFE_TIME; | ||
629 | unsigned int ifa_flags = 0; | 644 | unsigned int ifa_flags = 0; |
630 | 645 | ||
631 | memset(&req, 0, sizeof(req)); | 646 | memset(&req, 0, sizeof(req)); |
@@ -638,10 +653,9 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
638 | while (*argv) { | 653 | while (*argv) { |
639 | unsigned arg = index_in_strings(option, *argv); | 654 | unsigned arg = index_in_strings(option, *argv); |
640 | /* if search fails, "local" is assumed */ | 655 | /* if search fails, "local" is assumed */ |
641 | if ((int)arg >= 0 && arg != 8) | ||
642 | NEXT_ARG(); | ||
643 | 656 | ||
644 | if (arg <= 1) { /* peer, remote */ | 657 | if (arg <= 1) { /* peer, remote */ |
658 | NEXT_ARG(); | ||
645 | if (peer_len) { | 659 | if (peer_len) { |
646 | duparg(option_peer, *argv); | 660 | duparg(option_peer, *argv); |
647 | } | 661 | } |
@@ -654,6 +668,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
654 | req.ifa.ifa_prefixlen = peer.bitlen; | 668 | req.ifa.ifa_prefixlen = peer.bitlen; |
655 | } else if (arg <= 3) { /* broadcast, brd */ | 669 | } else if (arg <= 3) { /* broadcast, brd */ |
656 | inet_prefix addr; | 670 | inet_prefix addr; |
671 | NEXT_ARG(); | ||
657 | if (brd_len) { | 672 | if (brd_len) { |
658 | duparg(option_broadcast, *argv); | 673 | duparg(option_broadcast, *argv); |
659 | } | 674 | } |
@@ -670,6 +685,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
670 | } | 685 | } |
671 | } else if (arg == 4) { /* anycast */ | 686 | } else if (arg == 4) { /* anycast */ |
672 | inet_prefix addr; | 687 | inet_prefix addr; |
688 | NEXT_ARG(); | ||
673 | if (any_len) { | 689 | if (any_len) { |
674 | duparg(option_anycast, *argv); | 690 | duparg(option_anycast, *argv); |
675 | } | 691 | } |
@@ -679,22 +695,39 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
679 | } | 695 | } |
680 | addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen); | 696 | addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen); |
681 | any_len = addr.bytelen; | 697 | any_len = addr.bytelen; |
682 | } else if (arg == 5) { /* scope */ | 698 | } else if (arg == 5) { /* valid_lft */ |
699 | if (valid_lftp) | ||
700 | duparg(option_valid_lft, *argv); | ||
701 | NEXT_ARG(); | ||
702 | valid_lftp = *argv; | ||
703 | set_lifetime(&valid_lft, *argv, option_valid_lft); | ||
704 | } else if (arg == 6) { /* preferred_lft */ | ||
705 | if (preferred_lftp) | ||
706 | duparg(option_pref_lft, *argv); | ||
707 | NEXT_ARG(); | ||
708 | preferred_lftp = *argv; | ||
709 | set_lifetime(&preferred_lft, *argv, option_pref_lft); | ||
710 | } else if (arg == 7) { /* scope */ | ||
683 | uint32_t scope = 0; | 711 | uint32_t scope = 0; |
712 | NEXT_ARG(); | ||
684 | if (rtnl_rtscope_a2n(&scope, *argv)) { | 713 | if (rtnl_rtscope_a2n(&scope, *argv)) { |
685 | invarg_1_to_2(*argv, "scope"); | 714 | invarg_1_to_2(*argv, "scope"); |
686 | } | 715 | } |
687 | req.ifa.ifa_scope = scope; | 716 | req.ifa.ifa_scope = scope; |
688 | scoped = 1; | 717 | scoped = 1; |
689 | } else if (arg == 6) { /* dev */ | 718 | } else if (arg == 8) { /* dev */ |
719 | NEXT_ARG(); | ||
690 | d = *argv; | 720 | d = *argv; |
691 | } else if (arg == 7) { /* label */ | 721 | } else if (arg == 9) { /* label */ |
722 | NEXT_ARG(); | ||
692 | l = *argv; | 723 | l = *argv; |
693 | addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1); | 724 | addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1); |
694 | } else if (arg == 8) { /* noprefixroute */ | 725 | } else if (arg == 10) { /* noprefixroute */ |
695 | ifa_flags |= IFA_F_NOPREFIXROUTE; | 726 | ifa_flags |= IFA_F_NOPREFIXROUTE; |
696 | } else { | 727 | } else { |
697 | /* local (specified or assumed) */ | 728 | /* local (specified or assumed) */ |
729 | if ((int)arg >= 0) | ||
730 | NEXT_ARG(); | ||
698 | if (local_len) { | 731 | if (local_len) { |
699 | duparg2("local", *argv); | 732 | duparg2("local", *argv); |
700 | } | 733 | } |
@@ -755,6 +788,24 @@ static int ipaddr_modify(int cmd, int flags, char **argv) | |||
755 | 788 | ||
756 | req.ifa.ifa_index = xll_name_to_index(d); | 789 | req.ifa.ifa_index = xll_name_to_index(d); |
757 | 790 | ||
791 | if (valid_lftp || preferred_lftp) { | ||
792 | struct ifa_cacheinfo cinfo = {}; | ||
793 | |||
794 | if (!valid_lft) { | ||
795 | fprintf(stderr, "valid_lft is zero\n"); | ||
796 | return 1; | ||
797 | } | ||
798 | if (valid_lft < preferred_lft) { | ||
799 | fprintf(stderr, "preferred_lft is greater than valid_lft\n"); | ||
800 | return 1; | ||
801 | } | ||
802 | |||
803 | cinfo.ifa_prefered = preferred_lft; | ||
804 | cinfo.ifa_valid = valid_lft; | ||
805 | addattr_l(&req.n, sizeof(req), IFA_CACHEINFO, &cinfo, | ||
806 | sizeof(cinfo)); | ||
807 | } | ||
808 | |||
758 | if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) | 809 | if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0) |
759 | return 2; | 810 | return 2; |
760 | 811 | ||