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

Reply via email to