bin/144343: The rtadvd cannot avoid the prefix that doesn't want to
advertise.
Tatsuki Makino
tatsuki_makino at hotmail.com
Sat Feb 27 11:50:02 UTC 2010
>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 root at 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:
More information about the freebsd-bugs
mailing list