Signed-off-by: Christian Eggers <[email protected]>
---
 networking/libiproute/ip_common.h |  4 ++
 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);
 
 POP_SAVED_FUNCTION_VISIBILITY
 
+#ifndef        INFINITY_LIFE_TIME
+#define     INFINITY_LIFE_TIME      0xFFFFFFFFU
+#endif
+
 #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)
        return 0;
 }
 
+static void set_lifetime(unsigned int *lifetime, char *argv, const char 
*errmsg)
+{
+       if (strcmp(argv, "forever") == 0)
+               *lifetime = INFINITY_LIFE_TIME;
+       else
+               *lifetime = get_u32(argv, errmsg);
+}
+
 static int default_scope(inet_prefix *lcl)
 {
        if (lcl->family == AF_INET) {
@@ -607,10 +615,13 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
        /* If you add stuff here, update ipaddr_full_usage */
        static const char option[] ALIGN1 =
                "peer\0""remote\0""broadcast\0""brd\0"
-               "anycast\0""scope\0""dev\0""label\0""noprefixroute\0""local\0";
+               "anycast\0""valid_lft\0""preferred_lft\0"
+               "scope\0""dev\0""label\0""noprefixroute\0""local\0";
 #define option_peer      option
 #define option_broadcast (option           + sizeof("peer") + sizeof("remote"))
 #define option_anycast   (option_broadcast + sizeof("broadcast") + 
sizeof("brd"))
+#define option_valid_lft (option_anycast   + sizeof("anycast"))
+#define option_pref_lft  (option_valid_lft + sizeof("valid_lft"))
        struct rtnl_handle rth;
        struct {
                struct nlmsghdr  n;
@@ -619,6 +630,8 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
        } req;
        char *d = NULL;
        char *l = NULL;
+       char *valid_lftp = NULL;
+       char *preferred_lftp = NULL;
        inet_prefix lcl;
        inet_prefix peer;
        int local_len = 0;
@@ -626,6 +639,8 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
        int brd_len = 0;
        int any_len = 0;
        bool scoped = 0;
+       __u32 valid_lft = INFINITY_LIFE_TIME;
+       __u32 preferred_lft = INFINITY_LIFE_TIME;
        unsigned int ifa_flags = 0;
 
        memset(&req, 0, sizeof(req));
@@ -638,10 +653,9 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
        while (*argv) {
                unsigned arg = index_in_strings(option, *argv);
                /* if search fails, "local" is assumed */
-               if ((int)arg >= 0 && arg != 8)
-                       NEXT_ARG();
 
                if (arg <= 1) { /* peer, remote */
+                       NEXT_ARG();
                        if (peer_len) {
                                duparg(option_peer, *argv);
                        }
@@ -654,6 +668,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
                        req.ifa.ifa_prefixlen = peer.bitlen;
                } else if (arg <= 3) { /* broadcast, brd */
                        inet_prefix addr;
+                       NEXT_ARG();
                        if (brd_len) {
                                duparg(option_broadcast, *argv);
                        }
@@ -670,6 +685,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
                        }
                } else if (arg == 4) { /* anycast */
                        inet_prefix addr;
+                       NEXT_ARG();
                        if (any_len) {
                                duparg(option_anycast, *argv);
                        }
@@ -679,22 +695,39 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
                        }
                        addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, 
addr.bytelen);
                        any_len = addr.bytelen;
-               } else if (arg == 5) { /* scope */
+               } else if (arg == 5) { /* valid_lft */
+                       if (valid_lftp)
+                               duparg(option_valid_lft, *argv);
+                       NEXT_ARG();
+                       valid_lftp = *argv;
+                       set_lifetime(&valid_lft, *argv, option_valid_lft);
+               } else if (arg == 6) { /* preferred_lft */
+                       if (preferred_lftp)
+                               duparg(option_pref_lft, *argv);
+                       NEXT_ARG();
+                       preferred_lftp = *argv;
+                       set_lifetime(&preferred_lft, *argv, option_pref_lft);
+               } else if (arg == 7) { /* scope */
                        uint32_t scope = 0;
+                       NEXT_ARG();
                        if (rtnl_rtscope_a2n(&scope, *argv)) {
                                invarg_1_to_2(*argv, "scope");
                        }
                        req.ifa.ifa_scope = scope;
                        scoped = 1;
-               } else if (arg == 6) { /* dev */
+               } else if (arg == 8) { /* dev */
+                       NEXT_ARG();
                        d = *argv;
-               } else if (arg == 7) { /* label */
+               } else if (arg == 9) { /* label */
+                       NEXT_ARG();
                        l = *argv;
                        addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) 
+ 1);
-               } else if (arg == 8) { /* noprefixroute */
+               } else if (arg == 10) { /* noprefixroute */
                        ifa_flags |= IFA_F_NOPREFIXROUTE;
                } else {
                        /* local (specified or assumed) */
+                       if ((int)arg >= 0)
+                               NEXT_ARG();
                        if (local_len) {
                                duparg2("local", *argv);
                        }
@@ -755,6 +788,24 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
 
        req.ifa.ifa_index = xll_name_to_index(d);
 
+       if (valid_lftp || preferred_lftp) {
+               struct ifa_cacheinfo cinfo = {};
+
+               if (!valid_lft) {
+                       fprintf(stderr, "valid_lft is zero\n");
+                       return 1;
+               }
+               if (valid_lft < preferred_lft) {
+                       fprintf(stderr, "preferred_lft is greater than 
valid_lft\n");
+                       return 1;
+               }
+
+               cinfo.ifa_prefered = preferred_lft;
+               cinfo.ifa_valid = valid_lft;
+               addattr_l(&req.n, sizeof(req), IFA_CACHEINFO, &cinfo,
+                         sizeof(cinfo));
+       }
+
        if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
                return 2;
 
-- 
Christian Eggers
Embedded software developer

Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: 
HRA 57918
Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: 
HRB 54477
Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; 
Markus Zeiler

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to