>Number:         144343
>Category:       bin
>Synopsis:       The rtadvd cannot avoid the prefix that doesn't want to 
>advertise.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sat Feb 27 11:50:01 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Tatsuki Makino
>Release:        FreeBSD 6.4-RELEASE-p9 i386
>Organization:
>Environment:
FreeBSD T0.test 6.4-RELEASE-p9 FreeBSD 6.4-RELEASE-p9 #0: Thu Jan  7 11:28:17 
GMT 2010     r...@t0.test:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
When one network interface has 2 prefixes or more, all prefixes are advertised. 
I don't hope for it.
When choice prefixes to advertise by configuration file, it is limited only to 
static prefixes. I want also to advertise dynamic prefix.
>How-To-Repeat:
-- Host T0:

 /etc/rc.conf (snipped)
 ipv6_gateway_enable="YES"
 rtadvd_enable="YES"
 rtadvd_interfaces="rl0"

 rl0 has these addresses as follows
 inet6 2001:db8:0:0::0 prefixlen 64 # fixed
 inet6 2001:db8:0:1:: prefixlen 64 # add or remove dynamically
 inet6 2001:db8:0:2:: prefixlen 64 # add or remove dynamically
 inet6 2001:db8:0:3:: prefixlen 64 # add or remove dynamically
 (snip)
 inet6 2001:db8:0:ffff:: prefixlen 64 # add or remove dynamically

--

-- Host T2:

 /etc/sysctl.conf (snipped)
 net.inet6.ip6.use_tempaddr=1
 net.inet6.ip6.prefer_tempaddr=1

 rl0 has these addresses as follows
 ether XX:XX:XX:XX:XX:XX
 inet6 2001:db8:0:0::1 prefixlen 64 # fixed (A)
 inet6 2001:db8:0:0:XXXX:XXff:feXX:XXXX prefixlen 64 # or this (B)

--

rl0 on T0 and rl0 on T2 are connected via cable.
When T2 used inet6 address (A), T2 generate tempaddr. I don't want to tempaddr 
for 2001:db8:0:0/64.
When T2 used inet6 address (B), T2 log a lot of messages as "in6_ifadd: 
2001:db8::XXXX:XXff:feXX:XXXX is already configured".
>Fix:
Patch it (written for 6.4-RELEASE).
Build and install.
Configure /etc/rtadvd.conf as follows

rl0:\
 :ignoreaddr="2001:db8::":ignoreprefixlen#8:

Start rtadvd.

I don't know it is useful for you...
If it is not useful for you, close this PR immediately.

Patch attached with submission follows:

diff -u -r -N -d /usr/src/usr.sbin/rtadvd/config.c usr.sbin/rtadvd/config.c
--- /usr/src/usr.sbin/rtadvd/config.c   2008-10-02 02:57:24.000000000 +0000
+++ usr.sbin/rtadvd/config.c    2010-02-27 08:06:36.000000000 +0000
@@ -123,6 +123,7 @@
 #ifdef ROUTEINFO
        tmp->route.next = tmp->route.prev = &tmp->route;
 #endif
+       tmp->ignore_prefix.next = tmp->ignore_prefix.prev = &tmp->ignore_prefix;
 
        /* check if we are allowed to forward packets (if not determined) */
        if (forwarding < 0) {
@@ -381,6 +382,51 @@
                                now.tv_sec + pfx->preflifetime;
                }
        }
+       /* ignore prefix */
+       tmp->ignore_pfxs = 0;
+       for (i = -1; i < MAXPREFIX; i++) {
+               struct prefix *pfx;
+               char entbuf[256];
+
+               makeentry(entbuf, sizeof(entbuf), i, "ignoreaddr");
+               addr = (char *)agetstr(entbuf, &bp);
+               if (addr == NULL)
+                       continue;
+
+               /* allocate memory to store prefix information */
+               if ((pfx = malloc(sizeof(struct prefix))) == NULL) {
+                       syslog(LOG_ERR,
+                              "<%s> can't allocate enough memory",
+                              __func__);
+                       exit(1);
+               }
+               memset(pfx, 0, sizeof(*pfx));
+
+               /* link into chain */
+               insque(pfx, &tmp->ignore_prefix);
+               tmp->ignore_pfxs++;
+               pfx->rainfo = tmp;
+
+               pfx->origin = PREFIX_FROM_CONFIG;
+
+               if (inet_pton(AF_INET6, addr, &pfx->prefix) != 1) {
+                       syslog(LOG_ERR,
+                              "<%s> inet_pton failed for %s",
+                              __func__, addr);
+                       exit(1);
+               }
+
+               makeentry(entbuf, sizeof(entbuf), i, "ignoreprefixlen");
+               MAYHAVE(val, entbuf, 64);
+               if (val < 0 || val > 128) {
+                       syslog(LOG_ERR, "<%s> prefixlen (%ld) for %s "
+                              "on %s out of range",
+                              __func__, val, addr, intface);
+                       exit(1);
+               }
+               pfx->prefixlen = (int)val;
+
+       }
        if (tmp->pfxs == 0)
                get_prefix(tmp);
 
@@ -641,6 +687,10 @@
                        /* ignore a duplicated prefix. */
                        continue;
                }
+               if (find_ignore_prefix(rai, a, plen)) {
+                       /* ignore a ignored prefix. */
+                       continue;
+               }
 
                /* allocate memory to store prefix info. */
                if ((pp = malloc(sizeof(*pp))) == NULL) {
diff -u -r -N -d /usr/src/usr.sbin/rtadvd/rtadvd.c usr.sbin/rtadvd/rtadvd.c
--- /usr/src/usr.sbin/rtadvd/rtadvd.c   2008-10-02 02:57:24.000000000 +0000
+++ usr.sbin/rtadvd/rtadvd.c    2010-02-26 16:17:07.000000000 +0000
@@ -490,6 +490,18 @@
                                    __func__, plen);
                                break;
                        }
+                       if (find_ignore_prefix(rai, addr, plen)) {
+                               if (dflag > 1) {
+                                       syslog(LOG_DEBUG,
+                                           "<%s> new prefix(%s/%d) "
+                                           "ignored on %s",
+                                           __func__,
+                                           inet_ntop(AF_INET6, addr,
+                                           (char *)addrbuf, INET6_ADDRSTRLEN),
+                                           plen, rai->ifname);
+                               }
+                               break;
+                       }
                        prefix = find_prefix(rai, addr, plen);
                        if (prefix) {
                                if (prefix->timer) {
@@ -1263,6 +1275,20 @@
        return(0);
 }
 
+struct prefix *
+find_ignore_prefix(struct rainfo *rai, struct in6_addr *prefix, int plen)
+{
+       struct prefix *pp;
+
+       for (pp = rai->ignore_prefix.next; pp != &rai->ignore_prefix; pp = 
pp->next) {
+               if (prefix_match(prefix, plen, &pp->prefix, pp->prefixlen)) {
+                       return pp;
+               }
+       }
+
+       return(NULL);
+}
+
 static int
 nd6_options(struct nd_opt_hdr *hdr, int limit,
            union nd_opts *ndopts, u_int32_t optflags)
diff -u -r -N -d /usr/src/usr.sbin/rtadvd/rtadvd.h usr.sbin/rtadvd/rtadvd.h
--- /usr/src/usr.sbin/rtadvd/rtadvd.h   2008-10-02 02:57:24.000000000 +0000
+++ usr.sbin/rtadvd/rtadvd.h    2010-02-26 16:11:21.000000000 +0000
@@ -149,6 +149,10 @@
 
        /* info about soliciter */
        struct soliciter *soliciter;    /* recent solication source */
+
+       /* prefixes not advertised */
+       struct prefix ignore_prefix;    /* AdvPrefixList(link head) */
+       int     ignore_pfxs;            /* number of prefixes */
 };
 
 struct rtadvd_timer *ra_timeout __P((void *));
@@ -157,5 +161,6 @@
 int prefix_match __P((struct in6_addr *, int, struct in6_addr *, int));
 struct rainfo *if_indextorainfo __P((int));
 struct prefix *find_prefix __P((struct rainfo *, struct in6_addr *, int));
+struct prefix *find_ignore_prefix __P((struct rainfo *, struct in6_addr *, 
int));
 
 extern struct in6_addr in6a_site_allrouters;


>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to