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;
};