ip address: Add support for "valid_lft" and "preferred_lft" options
No binary (build failed)
—
(log yok)
| @@ -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 | |
| @@ -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; | |