Hi,I've implemented 90% of this feature. The missing 10% is that it only supports one automatically chosen address.
I've committed attached patch to CVS HEAD. -- Pekka Savola "You each name yourselves king, yet the Netcore Oy kingdom bleeds." Systems. Networks. Security. -- George R.R. Martin: A Clash of Kings
Index: CHANGES =================================================================== RCS file: /work/cvsroot/radvd/CHANGES,v retrieving revision 1.63 diff -u -r1.63 CHANGES --- CHANGES 25 Jun 2007 11:46:45 -0000 1.63 +++ CHANGES 25 Oct 2007 19:25:44 -0000 @@ -1,5 +1,10 @@ $Id: CHANGES,v 1.63 2007/06/25 11:46:45 psavola Exp $ +25/10/2007 Implement automatically selecting and advertising an + interface address, see radvd.conf(5) for more. Add + a warning about not being able to set interface + variables with non-root user. + 25/06/2007 Send prefix, route and RDNSS options (matters if there are many RDNSS options) in the same order they appear in the configuration; add support for AdvDefaultLifetime Index: TODO =================================================================== RCS file: /work/cvsroot/radvd/TODO,v retrieving revision 1.25 diff -u -r1.25 TODO --- TODO 25 Oct 2007 05:53:40 -0000 1.25 +++ TODO 25 Oct 2007 19:25:44 -0000 @@ -39,7 +39,11 @@ Consider whether to support RFC 4286 (Multicast Router Discovery). Consider whether to support multiple IPv4 addresses with Base6to4Interface -(currently the code just uses the first one). +(currently the code just picks one). + +Consider whether to support multiple prefixes and routes with a single +configuration line (instead of having to specify each prefix/route +separately) somewhat similar to how RDNSS configuration already supports. Consider whether to support a generalization of Base6to4Interface for arbitrary IPv6 prefixes, to be used for automatic generation of downstream Index: configure.in =================================================================== RCS file: /work/cvsroot/radvd/configure.in,v retrieving revision 1.10 diff -u -r1.10 configure.in --- configure.in 18 Oct 2005 19:17:29 -0000 1.10 +++ configure.in 25 Oct 2007 19:25:44 -0000 @@ -120,7 +120,7 @@ fi unset hdrfound -AC_CHECK_HEADERS(sys/sockio.h getopt.h inttypes.h) +AC_CHECK_HEADERS(ifaddrs.h sys/sockio.h getopt.h inttypes.h) AC_CHECK_HEADERS(net/if_dl.h net/if_types.h net/if_arp.h) AC_CHECK_HEADERS(sys/param.h) AC_CHECK_HEADERS(machine/param.h) Index: gram.y =================================================================== RCS file: /work/cvsroot/radvd/gram.y,v retrieving revision 1.18 diff -u -r1.18 gram.y --- gram.y 25 Jun 2007 11:46:45 -0000 1.18 +++ gram.y 25 Oct 2007 19:25:44 -0000 @@ -366,6 +366,7 @@ prefixhead : T_PREFIX IPV6ADDR '/' NUMBER { + struct in6_addr zeroaddr; prefix = malloc(sizeof(struct AdvPrefix)); if (prefix == NULL) { @@ -384,6 +385,45 @@ prefix->PrefixLen = $4; memcpy(&prefix->Prefix, $2, sizeof(struct in6_addr)); + + memset(&zeroaddr, 0, sizeof(zeroaddr)); + if (!memcmp($2, &zeroaddr, sizeof(struct in6_addr))) { +#ifndef HAVE_IFADDRS_H + flog(LOG_ERR, "invalid all-zeros prefix in %s, line %d", conf_file, num_lines); + ABORT; +#else + dlog(LOG_DEBUG, 5, "all-zeros prefix in %s, line %d, parsing..", conf_file, num_lines); + struct ifaddrs *ifap, *ifa; + if (getifaddrs(&ifap) != 0) + flog(LOG_ERR, "getifaddrs failed: %s", strerror(errno)); + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + struct sockaddr_in6 *s6; + char buf[INET6_ADDRSTRLEN]; + if (strncmp(ifa->ifa_name, iface->Name, IFNAMSIZ)) + continue; + if (ifa->ifa_addr->sa_family != AF_INET6) + continue; + s6 = (struct sockaddr_in6 *)(ifa->ifa_addr); + if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr)) + continue; + if (inet_ntop(ifa->ifa_addr->sa_family, (void *)&(s6->sin6_addr), buf, sizeof(buf)) == NULL) { + flog(LOG_ERR, "%s: inet_ntop failed in %s, line %d!", ifa->ifa_name, conf_file, num_lines); + } + else { + dlog(LOG_DEBUG, 5, "auto-selected prefix %s on interface %s", buf, ifa->ifa_name); + memcpy(&prefix->Prefix, &s6->sin6_addr, sizeof(struct in6_addr)); + prefix->AdvRouterAddr=1; + prefix->AutoSelected=1; + } + } + if (!memcmp(&prefix->Prefix, &zeroaddr, sizeof(struct in6_addr))) { + prefix->enabled = 0; + flog(LOG_WARNING, "no auto-selected prefix on interface %s, disabling advertisements", iface->Name); + } + freeifaddrs(ifap); + freeifaddrs(ifa); +#endif /* ifndef HAVE_IFADDRS_H */ + } } ; @@ -405,7 +445,10 @@ } | T_AdvRouterAddr SWITCH ';' { - prefix->AdvRouterAddr = $2; + if (prefix->AutoSelected && $2 == 0) + flog(LOG_WARNING, "prefix automatically selected, AdvRouterAddr always enabled, ignoring config line %d", num_lines); + else + prefix->AdvRouterAddr = $2; } | T_AdvValidLifetime number_or_infinity ';' { @@ -417,6 +460,10 @@ } | T_Base6to4Interface name ';' { + if (prefix->AutoSelected) { + flog(LOG_ERR, "automatically selecting the prefix and Base6to4Interface are mutually exclusive"); + ABORT; + } /* fallthrough */ dlog(LOG_DEBUG, 4, "using interface %s for 6to4", $2); strncpy(prefix->if6to4, $2, IFNAMSIZ-1); prefix->if6to4[IFNAMSIZ-1] = '\0'; Index: includes.h =================================================================== RCS file: /work/cvsroot/radvd/includes.h,v retrieving revision 1.13 diff -u -r1.13 includes.h --- includes.h 18 Oct 2005 19:17:29 -0000 1.13 +++ includes.h 25 Oct 2007 19:25:44 -0000 @@ -95,4 +95,8 @@ # include <getopt.h> #endif +#ifdef HAVE_IFADDRS_H +# include <ifaddrs.h> +#endif + #endif /* INCLUDES_H */ Index: radvd.conf.5.man =================================================================== RCS file: /work/cvsroot/radvd/radvd.conf.5.man,v retrieving revision 1.21 diff -u -r1.21 radvd.conf.5.man --- radvd.conf.5.man 25 Oct 2007 05:29:33 -0000 1.21 +++ radvd.conf.5.man 25 Oct 2007 19:25:45 -0000 @@ -48,6 +48,14 @@ The address of interface should be used when using Mobile IPv6 extensions. +Special prefix "::/64" is also supported on systems that implement getifaddrs() +(on other systems, configuration activation fails and radvd exits). +When configured, radvd +picks one non-link-local prefix assigned to the interface and starts advertising +it. This may be applicable in non-6to4 scenarios where the upstream prefix might +change. This option is incompatible with Base6to4Interface option. +AdvRouterAddr option is always enabled when this configuration is used. + All the possible prefix specific options are described below. Each option has to be terminated by a semicolon. Index: radvd.h =================================================================== RCS file: /work/cvsroot/radvd/radvd.h,v retrieving revision 1.24 diff -u -r1.24 radvd.h --- radvd.h 8 Oct 2006 19:01:17 -0000 1.24 +++ radvd.h 25 Oct 2007 19:25:45 -0000 @@ -110,9 +110,10 @@ /* Mobile IPv6 extensions */ int AdvRouterAddr; - /* 6to4 extensions */ + /* 6to4 etc. extensions */ char if6to4[IFNAMSIZ]; int enabled; + int AutoSelected; struct AdvPrefix *next; };