aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Eggers <ceggers@arri.de>2020-06-29 17:57:26 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2020-07-31 18:48:50 +0200
commit8a485b0a363935309f976866b8a30988362fadc0 (patch)
tree96ba6cde1ef879fc4dd7616e20de3c5b189eea90
parent31d34f3bd8b0cc41db5e893942d9dc5c14e4dd3c (diff)
downloadbusybox-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.h4
-rw-r--r--networking/libiproute/ipaddress.c65
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
34POP_SAVED_FUNCTION_VISIBILITY 34POP_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
595static 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
595static int default_scope(inet_prefix *lcl) 603static 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