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>
This commit is contained in:
parent
31d34f3bd8
commit
8a485b0a36
@ -33,4 +33,8 @@ int FAST_FUNC do_iplink(char **argv);
|
|||||||
|
|
||||||
POP_SAVED_FUNCTION_VISIBILITY
|
POP_SAVED_FUNCTION_VISIBILITY
|
||||||
|
|
||||||
|
#ifndef INFINITY_LIFE_TIME
|
||||||
|
#define INFINITY_LIFE_TIME 0xFFFFFFFFU
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -592,6 +592,14 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush)
|
|||||||
return 0;
|
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)
|
static int default_scope(inet_prefix *lcl)
|
||||||
{
|
{
|
||||||
if (lcl->family == AF_INET) {
|
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 */
|
/* If you add stuff here, update ipaddr_full_usage */
|
||||||
static const char option[] ALIGN1 =
|
static const char option[] ALIGN1 =
|
||||||
"peer\0""remote\0""broadcast\0""brd\0"
|
"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_peer option
|
||||||
#define option_broadcast (option + sizeof("peer") + sizeof("remote"))
|
#define option_broadcast (option + sizeof("peer") + sizeof("remote"))
|
||||||
#define option_anycast (option_broadcast + sizeof("broadcast") + sizeof("brd"))
|
#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 rtnl_handle rth;
|
||||||
struct {
|
struct {
|
||||||
struct nlmsghdr n;
|
struct nlmsghdr n;
|
||||||
@ -619,6 +630,8 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
|
|||||||
} req;
|
} req;
|
||||||
char *d = NULL;
|
char *d = NULL;
|
||||||
char *l = NULL;
|
char *l = NULL;
|
||||||
|
char *valid_lftp = NULL;
|
||||||
|
char *preferred_lftp = NULL;
|
||||||
inet_prefix lcl;
|
inet_prefix lcl;
|
||||||
inet_prefix peer;
|
inet_prefix peer;
|
||||||
int local_len = 0;
|
int local_len = 0;
|
||||||
@ -626,6 +639,8 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
|
|||||||
int brd_len = 0;
|
int brd_len = 0;
|
||||||
int any_len = 0;
|
int any_len = 0;
|
||||||
bool scoped = 0;
|
bool scoped = 0;
|
||||||
|
__u32 valid_lft = INFINITY_LIFE_TIME;
|
||||||
|
__u32 preferred_lft = INFINITY_LIFE_TIME;
|
||||||
unsigned int ifa_flags = 0;
|
unsigned int ifa_flags = 0;
|
||||||
|
|
||||||
memset(&req, 0, sizeof(req));
|
memset(&req, 0, sizeof(req));
|
||||||
@ -638,10 +653,9 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
|
|||||||
while (*argv) {
|
while (*argv) {
|
||||||
unsigned arg = index_in_strings(option, *argv);
|
unsigned arg = index_in_strings(option, *argv);
|
||||||
/* if search fails, "local" is assumed */
|
/* if search fails, "local" is assumed */
|
||||||
if ((int)arg >= 0 && arg != 8)
|
|
||||||
NEXT_ARG();
|
|
||||||
|
|
||||||
if (arg <= 1) { /* peer, remote */
|
if (arg <= 1) { /* peer, remote */
|
||||||
|
NEXT_ARG();
|
||||||
if (peer_len) {
|
if (peer_len) {
|
||||||
duparg(option_peer, *argv);
|
duparg(option_peer, *argv);
|
||||||
}
|
}
|
||||||
@ -654,6 +668,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
|
|||||||
req.ifa.ifa_prefixlen = peer.bitlen;
|
req.ifa.ifa_prefixlen = peer.bitlen;
|
||||||
} else if (arg <= 3) { /* broadcast, brd */
|
} else if (arg <= 3) { /* broadcast, brd */
|
||||||
inet_prefix addr;
|
inet_prefix addr;
|
||||||
|
NEXT_ARG();
|
||||||
if (brd_len) {
|
if (brd_len) {
|
||||||
duparg(option_broadcast, *argv);
|
duparg(option_broadcast, *argv);
|
||||||
}
|
}
|
||||||
@ -670,6 +685,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
|
|||||||
}
|
}
|
||||||
} else if (arg == 4) { /* anycast */
|
} else if (arg == 4) { /* anycast */
|
||||||
inet_prefix addr;
|
inet_prefix addr;
|
||||||
|
NEXT_ARG();
|
||||||
if (any_len) {
|
if (any_len) {
|
||||||
duparg(option_anycast, *argv);
|
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);
|
addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen);
|
||||||
any_len = 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;
|
uint32_t scope = 0;
|
||||||
|
NEXT_ARG();
|
||||||
if (rtnl_rtscope_a2n(&scope, *argv)) {
|
if (rtnl_rtscope_a2n(&scope, *argv)) {
|
||||||
invarg_1_to_2(*argv, "scope");
|
invarg_1_to_2(*argv, "scope");
|
||||||
}
|
}
|
||||||
req.ifa.ifa_scope = scope;
|
req.ifa.ifa_scope = scope;
|
||||||
scoped = 1;
|
scoped = 1;
|
||||||
} else if (arg == 6) { /* dev */
|
} else if (arg == 8) { /* dev */
|
||||||
|
NEXT_ARG();
|
||||||
d = *argv;
|
d = *argv;
|
||||||
} else if (arg == 7) { /* label */
|
} else if (arg == 9) { /* label */
|
||||||
|
NEXT_ARG();
|
||||||
l = *argv;
|
l = *argv;
|
||||||
addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1);
|
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;
|
ifa_flags |= IFA_F_NOPREFIXROUTE;
|
||||||
} else {
|
} else {
|
||||||
/* local (specified or assumed) */
|
/* local (specified or assumed) */
|
||||||
|
if ((int)arg >= 0)
|
||||||
|
NEXT_ARG();
|
||||||
if (local_len) {
|
if (local_len) {
|
||||||
duparg2("local", *argv);
|
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);
|
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)
|
if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
|
||||||
return 2;
|
return 2;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user