From: Masahide NAKAMURA Date: Fri, 24 Nov 2006 03:26:55 +0000 (+0900) Subject: ADDR: Enable to add IPv6 address with valid/preferred lifetime. X-Git-Tag: v2.6.19-061214~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=35546df7d53a7ec2974a7b4f777d5a52f521d513;p=thirdparty%2Fiproute2.git ADDR: Enable to add IPv6 address with valid/preferred lifetime. Signed-off-by: TAKAMIYA Noriaki Signed-off-by: Masahide NAKAMURA Signed-off-by: Stephen Hemminger --- diff --git a/ip/ipaddress.c b/ip/ipaddress.c index 592875a9e..ea27d4218 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -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);