ADDR: Enable to add IPv6 address with valid/preferred lifetime.

Signed-off-by: TAKAMIYA Noriaki <takamiya@po.ntts.co.jp>
Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>
Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
This commit is contained in:
Masahide NAKAMURA 2006-11-24 12:26:55 +09:00 committed by Stephen Hemminger
parent 0cc5ebf46d
commit 35546df7d5
1 changed files with 51 additions and 1 deletions

View File

@ -60,7 +60,8 @@ static void usage(void)
if (do_link) {
iplink_usage();
}
fprintf(stderr, "Usage: ip addr {add|del} IFADDR dev STRING\n");
fprintf(stderr, "Usage: ip addr add IFADDR dev STRING [ LIFETIME ]\n");
fprintf(stderr, " ip addr del IFADDR dev STRING\n");
fprintf(stderr, " ip addr {show|flush} [ dev STRING ] [ scope SCOPE-ID ]\n");
fprintf(stderr, " [ to PREFIX ] [ FLAG-LIST ] [ label PATTERN ]\n");
fprintf(stderr, "IFADDR := PREFIX | ADDR peer PREFIX\n");
@ -70,6 +71,9 @@ static void usage(void)
fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] FLAG\n");
fprintf(stderr, "FLAG := [ permanent | dynamic | secondary | primary |\n");
fprintf(stderr, " tentative | deprecated ]\n");
fprintf(stderr, "LIFETIME := [ valid_lft LFT ] [ preferred_lft LFT ]\n");
fprintf(stderr, "LFT := forever | SECONDS\n");
exit(-1);
}
@ -276,6 +280,16 @@ static int flush_update(void)
return 0;
}
static int set_lifetime(unsigned int *lifetime, char *argv)
{
if (strcmp(argv, "forever") == 0)
*lifetime = 0xFFFFFFFFU;
else if (get_u32(lifetime, argv, 0))
return -1;
return 0;
}
int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n,
void *arg)
{
@ -742,6 +756,8 @@ int ipaddr_modify(int cmd, int argc, char **argv)
char *d = NULL;
char *l = NULL;
char *lcl_arg = NULL;
char *valid_lftp = NULL;
char *preferred_lftp = NULL;
inet_prefix lcl;
inet_prefix peer;
int local_len = 0;
@ -749,6 +765,9 @@ int ipaddr_modify(int cmd, int argc, char **argv)
int brd_len = 0;
int any_len = 0;
int scoped = 0;
__u32 preferred_lft = 0xFFFFFFFFU;
__u32 valid_lft = 0xFFFFFFFFU;
struct ifa_cacheinfo cinfo;
memset(&req, 0, sizeof(req));
@ -811,6 +830,20 @@ int ipaddr_modify(int cmd, int argc, char **argv)
NEXT_ARG();
l = *argv;
addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1);
} else if (matches(*argv, "valid_lft") == 0) {
if (valid_lftp)
duparg("valid_lft", *argv);
NEXT_ARG();
valid_lftp = *argv;
if (set_lifetime(&valid_lft, *argv))
invarg("valid_lft value", *argv);
} else if (matches(*argv, "preferred_lft") == 0) {
if (preferred_lftp)
duparg("preferred_lft", *argv);
NEXT_ARG();
preferred_lftp = *argv;
if (set_lifetime(&preferred_lft, *argv))
invarg("preferred_lft value", *argv);
} else {
if (strcmp(*argv, "local") == 0) {
NEXT_ARG();
@ -881,6 +914,23 @@ int ipaddr_modify(int cmd, int argc, char **argv)
return -1;
}
if (valid_lftp || preferred_lftp) {
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;
}
memset(&cinfo, 0, sizeof(cinfo));
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)
exit(2);