1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-01 08:27:59 +00:00

- supported a string notation for xxflags.

- deprecate routes#N, as it is hard to keep consistency with
  rtprefixN.  accept any number of "rtprefix", "rtrefix0",
  ..., "rtprefix99".
- deprecate "addrs#N", as it is difficult for users to keep
  consistency with "addrN".
  accept 100 prefix info in maximum - like "addr", "addr0"
  ... "addr99".  WARNS=2 clean on netbsd.
  old configuration file should work just fine.
  behavior change:
  previously, we rejected "addrN" if there's "addr", and we rejected
  "addr" if there is "addrN".  now we accept both without problem.
- when an advertised prefix configured from the kernel has been added
  or invalidated, notice the change in a short delay.
- when invalidating a prefix, do not bark even if there is
  inconsistency about prefix lifetimes.
- wrap more specific route info code into ROUTEINFO.

Obtained from:	KAME
MFC after:	1 week
This commit is contained in:
Hajimu UMEMOTO 2003-08-15 19:13:53 +00:00
parent 11c568961d
commit fc35a81b09
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=118968
9 changed files with 529 additions and 407 deletions

View File

@ -18,7 +18,7 @@ PROG= rtadvd
MAN= rtadvd.conf.5 rtadvd.8
SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c dump.c
CFLAGS+= -DINET6 -DHAVE_ARC4RANDOM -DHAVE_POLL_H
CFLAGS+= -DINET6 -DHAVE_ARC4RANDOM -DHAVE_POLL_H -DROUTEINFO
DPADD= ${LIBCOMPAT}
LDADD= -lcompat

View File

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: config.c,v 1.37 2001/05/25 07:34:00 itojun Exp $ */
/* $KAME: config.c,v 1.84 2003/08/05 12:34:23 itojun Exp $ */
/*
* Copyright (C) 1998 WIDE Project.
@ -68,22 +68,21 @@ static time_t prefix_timo = (60 * 120); /* 2 hours.
extern struct rainfo *ralist;
static struct rtadvd_timer *prefix_timeout __P((void *));
static void makeentry __P((char *, size_t, int, char *, int));
static void get_prefix __P((struct rainfo *));
static void makeentry __P((char *, size_t, int, char *));
static int getinet6sysctl __P((int));
void
getconfig(intface)
char *intface;
{
int stat, pfxs, i;
int stat, i;
char tbuf[BUFSIZ];
struct rainfo *tmp;
long val;
int64_t val64;
char buf[BUFSIZ];
char *bp = buf;
char *addr;
char *addr, *flagstr;
static int forwarding = -1;
#define MUSTHAVE(var, cap) \
@ -119,7 +118,9 @@ getconfig(intface)
}
memset(tmp, 0, sizeof(*tmp));
tmp->prefix.next = tmp->prefix.prev = &tmp->prefix;
#ifdef ROUTEINFO
tmp->route.next = tmp->route.prev = &tmp->route;
#endif
/* check if we are allowed to forward packets (if not determined) */
if (forwarding < 0) {
@ -156,17 +157,18 @@ getconfig(intface)
MAYHAVE(val, "maxinterval", DEF_MAXRTRADVINTERVAL);
if (val < MIN_MAXINTERVAL || val > MAX_MAXINTERVAL) {
syslog(LOG_ERR,
"<%s> maxinterval must be between %e and %u",
__func__, MIN_MAXINTERVAL, MAX_MAXINTERVAL);
"<%s> maxinterval (%ld) on %s is invalid "
"(must be between %u and %u)", __func__, val,
intface, MIN_MAXINTERVAL, MAX_MAXINTERVAL);
exit(1);
}
tmp->maxinterval = (u_int)val;
MAYHAVE(val, "mininterval", tmp->maxinterval/3);
if (val < MIN_MININTERVAL || val > (tmp->maxinterval * 3) / 4) {
syslog(LOG_ERR,
"<%s> mininterval must be between %e and %d",
__func__,
MIN_MININTERVAL,
"<%s> mininterval (%ld) on %s is invalid "
"(must be between %d and %d)",
__func__, val, intface, MIN_MININTERVAL,
(tmp->maxinterval * 3) / 4);
exit(1);
}
@ -175,7 +177,25 @@ getconfig(intface)
MAYHAVE(val, "chlim", DEF_ADVCURHOPLIMIT);
tmp->hoplimit = val & 0xff;
MAYHAVE(val, "raflags", 0);
if ((flagstr = (char *)agetstr("raflags", &bp))) {
val = 0;
if (strchr(flagstr, 'm'))
val |= ND_RA_FLAG_MANAGED;
if (strchr(flagstr, 'o'))
val |= ND_RA_FLAG_OTHER;
if (strchr(flagstr, 'h'))
val |= ND_RA_FLAG_RTPREF_HIGH;
if (strchr(flagstr, 'l')) {
if ((val & ND_RA_FLAG_RTPREF_HIGH)) {
syslog(LOG_ERR, "<%s> the \'h\' and \'l\'"
" router flags are exclusive", __func__);
exit(1);
}
val |= ND_RA_FLAG_RTPREF_LOW;
}
} else {
MAYHAVE(val, "raflags", 0);
}
tmp->managedflg = val & ND_RA_FLAG_MANAGED;
tmp->otherflg = val & ND_RA_FLAG_OTHER;
#ifndef ND_RA_FLAG_RTPREF_MASK
@ -184,18 +204,19 @@ getconfig(intface)
#endif
tmp->rtpref = val & ND_RA_FLAG_RTPREF_MASK;
if (tmp->rtpref == ND_RA_FLAG_RTPREF_RSV) {
syslog(LOG_ERR, "<%s> invalid router preference on %s",
__func__, intface);
syslog(LOG_ERR, "<%s> invalid router preference (%02x) on %s",
__func__, tmp->rtpref, intface);
exit(1);
}
MAYHAVE(val, "rltime", tmp->maxinterval * 3);
if (val && (val < tmp->maxinterval || val > MAXROUTERLIFETIME)) {
syslog(LOG_ERR,
"<%s> router lifetime on %s must be 0 or"
" between %d and %d",
__func__, intface,
tmp->maxinterval, MAXROUTERLIFETIME);
"<%s> router lifetime (%ld) on %s is invalid "
"(must be 0 or between %d and %d)",
__func__, val, intface,
tmp->maxinterval,
MAXROUTERLIFETIME);
exit(1);
}
/*
@ -207,37 +228,39 @@ getconfig(intface)
* explicitly set zero. (see also the above section)
*/
if (val && forwarding == 0) {
syslog(LOG_WARNING,
syslog(LOG_ERR,
"<%s> non zero router lifetime is specified for %s, "
"which must not be allowed for hosts.",
"which must not be allowed for hosts. you must "
"change router lifetime or enable IPv6 forwarding.",
__func__, intface);
exit(1);
}
tmp->lifetime = val & 0xffff;
MAYHAVE(val, "rtime", DEF_ADVREACHABLETIME);
if (val > MAXREACHABLETIME) {
if (val < 0 || val > MAXREACHABLETIME) {
syslog(LOG_ERR,
"<%s> reachable time must be no greater than %d",
__func__, MAXREACHABLETIME);
"<%s> reachable time (%ld) on %s is invalid "
"(must be no greater than %d)",
__func__, val, intface, MAXREACHABLETIME);
exit(1);
}
tmp->reachabletime = (u_int32_t)val;
MAYHAVE(val64, "retrans", DEF_ADVRETRANSTIMER);
if (val64 < 0 || val64 > 0xffffffff) {
syslog(LOG_ERR, "<%s> retrans time out of range", __func__);
syslog(LOG_ERR, "<%s> retrans time (%lld) on %s out of range",
__func__, (long long)val64, intface);
exit(1);
}
tmp->retranstimer = (u_int32_t)val64;
if (agetstr("hapref", &bp) || agetstr("hatime", &bp)) {
if (agetnum("hapref") != -1 || agetnum("hatime") != -1) {
syslog(LOG_ERR,
"<%s> mobile-ip6 configuration not supported",
__func__);
exit(1);
}
/* prefix information */
/*
@ -248,132 +271,122 @@ getconfig(intface)
MAYHAVE(val, "clockskew", 0);
tmp->clockskew = val;
if ((pfxs = agetnum("addrs")) < 0) {
/* auto configure prefix information */
if (agetstr("addr", &bp) || agetstr("addr1", &bp)) {
tmp->pfxs = 0;
for (i = -1; i < MAXPREFIX; i++) {
struct prefix *pfx;
char entbuf[256];
makeentry(entbuf, sizeof(entbuf), i, "addr");
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> conflicting prefix configuration for %s: "
"automatic and manual config at the same time",
__func__, intface);
"<%s> can't allocate enough memory",
__func__);
exit(1);
}
get_prefix(tmp);
}
else {
tmp->pfxs = pfxs;
for (i = 0; i < pfxs; i++) {
struct prefix *pfx;
char entbuf[256];
int added = (pfxs > 1) ? 1 : 0;
memset(pfx, 0, sizeof(*pfx));
/* 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->prefix);
tmp->pfxs++;
pfx->rainfo = tmp;
/* link into chain */
insque(pfx, &tmp->prefix);
pfx->rainfo = tmp;
pfx->origin = PREFIX_FROM_CONFIG;
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);
}
if (IN6_IS_ADDR_MULTICAST(&pfx->prefix)) {
syslog(LOG_ERR,
"<%s> multicast prefix (%s) must "
"not be advertised on %s",
__func__, addr, intface);
exit(1);
}
if (IN6_IS_ADDR_LINKLOCAL(&pfx->prefix))
syslog(LOG_NOTICE,
"<%s> link-local prefix (%s) will be"
" advertised on %s",
__func__, addr, intface);
makeentry(entbuf, sizeof(entbuf), i, "prefixlen",
added);
MAYHAVE(val, entbuf, 64);
if (val < 0 || val > 128) {
syslog(LOG_ERR,
"<%s> prefixlen out of range",
__func__);
exit(1);
}
pfx->prefixlen = (int)val;
makeentry(entbuf, sizeof(entbuf), i, "prefixlen");
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;
makeentry(entbuf, sizeof(entbuf), i, "pinfoflags",
added);
{
MAYHAVE(val, entbuf,
(ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO));
}
pfx->onlinkflg = val & ND_OPT_PI_FLAG_ONLINK;
pfx->autoconfflg = val & ND_OPT_PI_FLAG_AUTO;
makeentry(entbuf, sizeof(entbuf), i, "pinfoflags");
if ((flagstr = (char *)agetstr(entbuf, &bp))) {
val = 0;
if (strchr(flagstr, 'l'))
val |= ND_OPT_PI_FLAG_ONLINK;
if (strchr(flagstr, 'a'))
val |= ND_OPT_PI_FLAG_AUTO;
} else {
MAYHAVE(val, entbuf,
(ND_OPT_PI_FLAG_ONLINK|ND_OPT_PI_FLAG_AUTO));
}
pfx->onlinkflg = val & ND_OPT_PI_FLAG_ONLINK;
pfx->autoconfflg = val & ND_OPT_PI_FLAG_AUTO;
makeentry(entbuf, sizeof(entbuf), i, "vltime", added);
MAYHAVE(val64, entbuf, DEF_ADVVALIDLIFETIME);
if (val64 < 0 || val64 > 0xffffffff) {
syslog(LOG_ERR,
"<%s> vltime out of range",
__func__);
exit(1);
}
pfx->validlifetime = (u_int32_t)val64;
makeentry(entbuf, sizeof(entbuf), i, "vltime");
MAYHAVE(val64, entbuf, DEF_ADVVALIDLIFETIME);
if (val64 < 0 || val64 > 0xffffffff) {
syslog(LOG_ERR, "<%s> vltime (%lld) for "
"%s/%d on %s is out of range",
__func__, (long long)val64,
addr, pfx->prefixlen, intface);
exit(1);
}
pfx->validlifetime = (u_int32_t)val64;
makeentry(entbuf, sizeof(entbuf), i, "vltimedecr",
added);
if (agetflag(entbuf)) {
struct timeval now;
gettimeofday(&now, 0);
pfx->vltimeexpire =
now.tv_sec + pfx->validlifetime;
}
makeentry(entbuf, sizeof(entbuf), i, "vltimedecr");
if (agetflag(entbuf)) {
struct timeval now;
gettimeofday(&now, 0);
pfx->vltimeexpire =
now.tv_sec + pfx->validlifetime;
}
makeentry(entbuf, sizeof(entbuf), i, "pltime", added);
MAYHAVE(val64, entbuf, DEF_ADVPREFERREDLIFETIME);
if (val64 < 0 || val64 > 0xffffffff) {
syslog(LOG_ERR,
"<%s> pltime out of range",
__func__);
exit(1);
}
pfx->preflifetime = (u_int32_t)val64;
makeentry(entbuf, sizeof(entbuf), i, "pltime");
MAYHAVE(val64, entbuf, DEF_ADVPREFERREDLIFETIME);
if (val64 < 0 || val64 > 0xffffffff) {
syslog(LOG_ERR,
"<%s> pltime (%lld) for %s/%d on %s "
"is out of range",
__func__, (long long)val64,
addr, pfx->prefixlen, intface);
exit(1);
}
pfx->preflifetime = (u_int32_t)val64;
makeentry(entbuf, sizeof(entbuf), i, "pltimedecr",
added);
if (agetflag(entbuf)) {
struct timeval now;
gettimeofday(&now, 0);
pfx->pltimeexpire =
now.tv_sec + pfx->preflifetime;
}
makeentry(entbuf, sizeof(entbuf), i, "addr", added);
addr = (char *)agetstr(entbuf, &bp);
if (addr == NULL) {
syslog(LOG_ERR,
"<%s> need %s as a prefix for "
"interface %s",
__func__, entbuf, intface);
exit(1);
}
if (inet_pton(AF_INET6, addr,
&pfx->prefix) != 1) {
syslog(LOG_ERR,
"<%s> inet_pton failed for %s",
__func__, addr);
exit(1);
}
if (IN6_IS_ADDR_MULTICAST(&pfx->prefix)) {
syslog(LOG_ERR,
"<%s> multicast prefix(%s) must "
"not be advertised (IF=%s)",
__func__, addr, intface);
exit(1);
}
if (IN6_IS_ADDR_LINKLOCAL(&pfx->prefix))
syslog(LOG_NOTICE,
"<%s> link-local prefix(%s) will be"
" advertised on %s",
__func__, addr, intface);
makeentry(entbuf, sizeof(entbuf), i, "pltimedecr");
if (agetflag(entbuf)) {
struct timeval now;
gettimeofday(&now, 0);
pfx->pltimeexpire =
now.tv_sec + pfx->preflifetime;
}
}
if (tmp->pfxs == 0)
get_prefix(tmp);
MAYHAVE(val, "mtu", 0);
if (val < 0 || val > 0xffffffff) {
syslog(LOG_ERR,
"<%s> mtu out of range", __func__);
"<%s> mtu (%ld) on %s out of range",
__func__, val, intface);
exit(1);
}
tmp->linkmtu = (u_int32_t)val;
@ -386,25 +399,32 @@ getconfig(intface)
}
else if (tmp->linkmtu < IPV6_MMTU || tmp->linkmtu > tmp->phymtu) {
syslog(LOG_ERR,
"<%s> advertised link mtu must be between"
" least MTU and physical link MTU",
__func__);
"<%s> advertised link mtu (%lu) on %s is invalid (must "
"be between least MTU (%d) and physical link MTU (%d)",
__func__, (unsigned long)tmp->linkmtu, intface,
IPV6_MMTU, tmp->phymtu);
exit(1);
}
/* route information */
MAYHAVE(val, "routes", 0);
if (val < 0 || val > 0xffffffff) {
syslog(LOG_ERR,
"<%s> number of route information improper", __func__);
exit(1);
}
tmp->routes = val;
for (i = 0; i < tmp->routes; i++) {
#ifdef ROUTEINFO
tmp->routes = 0;
for (i = -1; i < MAXROUTE; i++) {
struct rtinfo *rti;
char entbuf[256];
int added = (tmp->routes > 1) ? 1 : 0;
char entbuf[256], oentbuf[256];
makeentry(entbuf, sizeof(entbuf), i, "rtprefix");
addr = (char *)agetstr(entbuf, &bp);
if (addr == NULL) {
makeentry(oentbuf, sizeof(oentbuf), i, "rtrprefix");
addr = (char *)agetstr(oentbuf, &bp);
if (addr) {
fprintf(stderr, "%s was obsoleted. Use %s.\n",
oentbuf, entbuf);
}
}
if (addr == NULL)
continue;
/* allocate memory to store prefix information */
if ((rti = malloc(sizeof(struct rtinfo))) == NULL) {
@ -417,80 +437,122 @@ getconfig(intface)
/* link into chain */
insque(rti, &tmp->route);
tmp->routes++;
makeentry(entbuf, sizeof(entbuf), i, "rtrplen", added);
MAYHAVE(val, entbuf, 64);
if (val < 0 || val > 128) {
syslog(LOG_ERR,
"<%s> prefixlen out of range",
__func__);
exit(1);
}
rti->prefixlen = (int)val;
makeentry(entbuf, sizeof(entbuf), i, "rtrflags", added);
MAYHAVE(val, entbuf, 0);
rti->rtpref = val & ND_RA_FLAG_RTPREF_MASK;
if (rti->rtpref == ND_RA_FLAG_RTPREF_RSV) {
syslog(LOG_ERR, "<%s> invalid route preference",
__func__);
exit(1);
}
makeentry(entbuf, sizeof(entbuf), i, "rtrltime", added);
/*
* XXX: since default value of route lifetime is not defined in
* draft-draves-route-selection-01.txt, I took the default
* value of valid lifetime of prefix as its default.
* It need be much considered.
*/
MAYHAVE(val64, entbuf, DEF_ADVVALIDLIFETIME);
if (val64 < 0 || val64 > 0xffffffff) {
syslog(LOG_ERR,
"<%s> rtrltime out of range",
__func__);
exit(1);
}
rti->ltime = (u_int32_t)val64;
makeentry(entbuf, sizeof(entbuf), i, "rtrprefix", added);
addr = (char *)agetstr(entbuf, &bp);
if (addr == NULL) {
syslog(LOG_ERR,
"<%s> need %s as a route for "
"interface %s",
__func__, entbuf, intface);
exit(1);
}
if (inet_pton(AF_INET6, addr, &rti->prefix) != 1) {
syslog(LOG_ERR,
"<%s> inet_pton failed for %s",
syslog(LOG_ERR, "<%s> inet_pton failed for %s",
__func__, addr);
exit(1);
}
#if 0
/*
* XXX: currently there's no restriction in route information
* prefix according to draft-draves-route-selection-01.txt,
* however I think the similar restriction be necessary.
* prefix according to
* draft-ietf-ipngwg-router-selection-00.txt.
* However, I think the similar restriction be necessary.
*/
MAYHAVE(val64, entbuf, DEF_ADVVALIDLIFETIME);
if (IN6_IS_ADDR_MULTICAST(&rti->prefix)) {
syslog(LOG_ERR,
"<%s> multicast route (%s) must "
"not be advertised (IF=%s)",
"not be advertised on %s",
__func__, addr, intface);
exit(1);
}
if (IN6_IS_ADDR_LINKLOCAL(&rti->prefix)) {
syslog(LOG_NOTICE,
"<%s> link-local route (%s) must "
"not be advertised on %s",
"<%s> link-local route (%s) will "
"be advertised on %s",
__func__, addr, intface);
exit(1);
}
#endif
makeentry(entbuf, sizeof(entbuf), i, "rtplen");
/* XXX: 256 is a magic number for compatibility check. */
MAYHAVE(val, entbuf, 256);
if (val == 256) {
makeentry(oentbuf, sizeof(oentbuf), i, "rtrplen");
MAYHAVE(val, oentbuf, 256);
if (val != 256) {
fprintf(stderr, "%s was obsoleted. Use %s.\n",
oentbuf, entbuf);
} else
val = 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);
}
rti->prefixlen = (int)val;
makeentry(entbuf, sizeof(entbuf), i, "rtflags");
if ((flagstr = (char *)agetstr(entbuf, &bp))) {
val = 0;
if (strchr(flagstr, 'h'))
val |= ND_RA_FLAG_RTPREF_HIGH;
if (strchr(flagstr, 'l')) {
if ((val & ND_RA_FLAG_RTPREF_HIGH)) {
syslog(LOG_ERR,
"<%s> the \'h\' and \'l\' route"
" preferences are exclusive",
__func__);
exit(1);
}
val |= ND_RA_FLAG_RTPREF_LOW;
}
} else
MAYHAVE(val, entbuf, 256); /* XXX */
if (val == 256) {
makeentry(oentbuf, sizeof(oentbuf), i, "rtrflags");
MAYHAVE(val, oentbuf, 256);
if (val != 256) {
fprintf(stderr, "%s was obsoleted. Use %s.\n",
oentbuf, entbuf);
} else
val = 0;
}
rti->rtpref = val & ND_RA_FLAG_RTPREF_MASK;
if (rti->rtpref == ND_RA_FLAG_RTPREF_RSV) {
syslog(LOG_ERR, "<%s> invalid route preference (%02x) "
"for %s/%d on %s",
__func__, rti->rtpref, addr,
rti->prefixlen, intface);
exit(1);
}
/*
* Since the spec does not a default value, we should make
* this entry mandatory. However, FreeBSD 4.4 has shipped
* with this field being optional, we use the router lifetime
* as an ad-hoc default value with a warning message.
*/
makeentry(entbuf, sizeof(entbuf), i, "rtltime");
MAYHAVE(val64, entbuf, -1);
if (val64 == -1) {
makeentry(oentbuf, sizeof(oentbuf), i, "rtrltime");
MAYHAVE(val64, oentbuf, -1);
if (val64 != -1) {
fprintf(stderr, "%s was obsoleted. Use %s.\n",
oentbuf, entbuf);
} else {
fprintf(stderr, "%s should be specified "
"for interface %s.\n",
entbuf, intface);
val64 = tmp->lifetime;
}
}
if (val64 < 0 || val64 > 0xffffffff) {
syslog(LOG_ERR, "<%s> route lifetime (%lld) for "
"%s/%d on %s out of range", __func__,
(long long)val64, addr, rti->prefixlen, intface);
exit(1);
}
rti->ltime = (u_int32_t)val64;
}
#endif
/* okey */
tmp->next = ralist;
@ -506,7 +568,7 @@ getconfig(intface)
rtadvd_set_timer(&tmp->timer->tm, tmp->timer);
}
static void
void
get_prefix(struct rainfo *rai)
{
struct ifaddrs *ifap, *ifa;
@ -536,12 +598,14 @@ get_prefix(struct rainfo *rai)
m = (u_char *)&((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr;
lim = (u_char *)(ifa->ifa_netmask) + ifa->ifa_netmask->sa_len;
plen = prefixlen(m, lim);
if (plen < 0 || plen > 128) {
if (plen <= 0 || plen > 128) {
syslog(LOG_ERR, "<%s> failed to get prefixlen "
"or prefix is invalid",
__func__);
exit(1);
}
if (plen == 128) /* XXX */
continue;
if (find_prefix(rai, a, plen)) {
/* ignore a duplicated prefix. */
continue;
@ -580,10 +644,10 @@ get_prefix(struct rainfo *rai)
pp->onlinkflg = 1;
pp->autoconfflg = 1;
pp->origin = PREFIX_FROM_KERNEL;
pp->rainfo = rai;
/* link into chain */
insque(pp, &rai->prefix);
pp->rainfo = rai;
/* counter increment */
rai->pfxs++;
@ -593,29 +657,24 @@ get_prefix(struct rainfo *rai)
}
static void
makeentry(buf, len, id, string, add)
makeentry(buf, len, id, string)
char *buf;
size_t len;
int id;
char *string;
int add;
{
char *ep = buf + len;
strlcpy(buf, string, len);
if (add) {
char *cp;
cp = (char *)index(buf, '\0');
snprintf(cp, ep - cp, "%d", id);
}
if (id < 0)
strlcpy(buf, string, len);
else
snprintf(buf, len, "%s%d", string, id);
}
/*
* Add a prefix to the list of specified interface and reconstruct
* the outgoing packet.
* The prefix must not be in the list.
* XXX: other parameter of the prefix(e.g. lifetime) shoule be
* XXX: other parameters of the prefix (e.g. lifetime) shoule be
* able to be specified.
*/
static void
@ -653,13 +712,6 @@ add_prefix(struct rainfo *rai, struct in6_prefixreq *ipr)
/* reconstruct the packet */
rai->pfxs++;
make_packet(rai);
/*
* reset the timer so that the new prefix will be advertised quickly.
*/
rai->initcounter = 0;
ra_timer_update((void *)rai, &rai->timer->tm);
rtadvd_set_timer(&rai->timer->tm, rai->timer);
}
/*
@ -826,9 +878,11 @@ make_packet(struct rainfo *rainfo)
struct nd_router_advert *ra;
struct nd_opt_prefix_info *ndopt_pi;
struct nd_opt_mtu *ndopt_mtu;
#ifdef ROUTEINFO
struct nd_opt_route_info *ndopt_rti;
struct prefix *pfx;
struct rtinfo *rti;
#endif
struct prefix *pfx;
/* calculate total length */
packlen = sizeof(struct nd_router_advert);
@ -846,7 +900,7 @@ make_packet(struct rainfo *rainfo)
packlen += sizeof(struct nd_opt_prefix_info) * rainfo->pfxs;
if (rainfo->linkmtu)
packlen += sizeof(struct nd_opt_mtu);
#ifdef ND_OPT_ROUTE_INFO
#ifdef ROUTEINFO
for (rti = rainfo->route.next; rti != &rainfo->route; rti = rti->next)
packlen += sizeof(struct nd_opt_route_info) +
((rti->prefixlen + 0x3f) >> 6) * 8;
@ -956,7 +1010,7 @@ make_packet(struct rainfo *rainfo)
buf += sizeof(struct nd_opt_prefix_info);
}
#ifdef ND_OPT_ROUTE_INFO
#ifdef ROUTEINFO
for (rti = rainfo->route.next; rti != &rainfo->route; rti = rti->next) {
u_int8_t psize = (rti->prefixlen + 0x3f) >> 6;

View File

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: config.h,v 1.3 2000/05/16 13:34:13 itojun Exp $ */
/* $KAME: config.h,v 1.8 2003/06/17 08:26:22 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
@ -36,3 +36,12 @@ extern void invalidate_prefix __P((struct prefix *));
extern void update_prefix __P((struct prefix *));
extern void make_prefix __P((struct rainfo *, int, struct in6_addr *, int));
extern void make_packet __P((struct rainfo *));
extern void get_prefix __P((struct rainfo *));
/*
* it is highly unlikely to have 100 prefix information options,
* so it should be okay to limit it
*/
#define MAXPREFIX 100
#define MAXROUTE 100

View File

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: dump.c,v 1.16 2001/03/21 17:41:13 jinmei Exp $ */
/* $KAME: dump.c,v 1.32 2003/05/19 09:46:50 keiichi Exp $ */
/*
* Copyright (C) 2000 WIDE Project.
@ -93,7 +93,9 @@ if_dump()
{
struct rainfo *rai;
struct prefix *pfx;
#ifdef ROUTEINFO
struct rtinfo *rti;
#endif
char prefixbuf[INET6_ADDRSTRLEN];
int first;
struct timeval now;
@ -208,6 +210,7 @@ if_dump()
}
fprintf(fp, ")\n");
}
#ifdef ROUTEINFO
for (first = 1, rti = rai->route.next; rti != &rai->route;
rti = rti->next) {
if (first) {
@ -226,6 +229,7 @@ if_dump()
fprintf(fp, "lifetime: %ld", (long)rti->ltime);
fprintf(fp, ")\n");
}
#endif
}
}

View File

@ -1,5 +1,5 @@
.\" $FreeBSD$
.\" $KAME: rtadvd.8,v 1.17 2001/02/04 05:34:38 jinmei Exp $
.\" $KAME: rtadvd.8,v 1.24 2002/05/31 16:16:08 jinmei Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@ -40,9 +40,8 @@
.Op Fl c Ar configfile
.Ar interface ...
.Sh DESCRIPTION
The
.Nm
utility sends router advertisement packets to the specified
sends router advertisement packets to the specified
.Ar interfaces .
.Pp
The program will daemonize itself on invocation.
@ -62,9 +61,8 @@ In particular,
reads all the interface routes from the routing table and advertises
them as on-link prefixes.
.Pp
The
.Nm
utility also watches the routing table.
also watches the routing table.
If an interface direct route is
added on an advertising interface and no static prefixes are
specified by the configuration file,
@ -126,25 +124,19 @@ Print debugging information.
Even more debugging information is printed.
.It Fl f
Foreground mode (useful when debugging).
Log messages will be dumped to stderr when this option is specified.
.It Fl M
Specify an interface to join the all-routers site-local multicast group.
By default,
.Nm
tries to join the first advertising interface appeared in the command
tries to join the first advertising interface appearing on the command
line.
This option has meaning only with the
.Fl R
option, which enables routing renumbering protocol support.
.\".It Fl m
.\"Enables mobile IPv6 support.
.\"This changes the content of router advertisement option, as well as
.\"permitted configuration directives.
.It Fl R
Accept router renumbering requests.
If you enable it, certain IPsec setup is suggested for security reasons.
On KAME-based systems,
.Xr rrenumd 8
generates router renumbering request packets.
This option is currently disabled, and is ignored by
.Nm
with a warning message.
@ -168,9 +160,11 @@ In this case,
.Nm
will transmit router advertisement with router lifetime 0
to all the interfaces
(in accordance with RFC2461 6.2.5).
.Sh DIAGNOSTICS
.Ex -std
.Pq in accordance with RFC2461 6.2.5 .
.Sh RETURN VALUES
The
.Nm
program exits 0 on success, and >0 on failures.
.Sh FILES
.Bl -tag -width Pa -compact
.It Pa /etc/rtadvd.conf
@ -179,19 +173,18 @@ The default configuration file.
contains the pid of the currently running
.Nm .
.It Pa /var/run/rtadvd.dump
in which
The file in which
.Nm
dumps its internal state.
.El
.Sh SEE ALSO
.Xr rtadvd.conf 5 ,
.Xr rrenumd 8 ,
.Xr rtsol 8
.Sh HISTORY
The
.Nm
utility first appeared in WIDE Hydrangea IPv6 protocol stack kit.
.Sh CAVEAT
command first appeared in the WIDE Hydrangea IPv6 protocol stack kit.
.Sh BUGS
There used to be some text that recommended users not to let
.Nm
advertise Router Advertisement messages on an upstream link to avoid

View File

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: rtadvd.c,v 1.50 2001/02/04 06:15:15 itojun Exp $ */
/* $KAME: rtadvd.c,v 1.82 2003/08/05 12:34:23 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -96,7 +96,7 @@ struct nd_optlist {
struct nd_opt_hdr *opt;
};
union nd_opts {
struct nd_opt_hdr *nd_opt_array[7];
struct nd_opt_hdr *nd_opt_array[9];
struct {
struct nd_opt_hdr *zero;
struct nd_opt_hdr *src_lladdr;
@ -122,7 +122,7 @@ union nd_opts {
u_int32_t ndopt_flags[] = {
0, NDOPT_FLAG_SRCLINKADDR, NDOPT_FLAG_TGTLINKADDR,
NDOPT_FLAG_PREFIXINFO, NDOPT_FLAG_RDHDR, NDOPT_FLAG_MTU
NDOPT_FLAG_PREFIXINFO, NDOPT_FLAG_RDHDR, NDOPT_FLAG_MTU,
};
int main __P((int, char *[]));
@ -143,6 +143,7 @@ static void free_ndopts __P((union nd_opts *));
static void ra_output __P((struct rainfo *));
static void rtmsg_input __P((void));
static void rtadvd_set_dump_file __P((int));
static void set_short_delay __P((struct rainfo *));
int
main(argc, argv)
@ -243,8 +244,8 @@ main(argc, argv)
pid = getpid();
if ((pidfp = fopen(pidfilename, "w")) == NULL) {
syslog(LOG_ERR,
"<%s> failed to open a log file(%s), run anyway.",
__func__, pidfilename);
"<%s> failed to open the pid log file, run anyway.",
__func__);
} else {
fprintf(pidfp, "%d\n", pid);
fclose(pidfp);
@ -398,6 +399,7 @@ rtmsg_input()
struct rainfo *rai;
struct in6_addr *addr;
char addrbuf[INET6_ADDRSTRLEN];
int prefixchange = 0;
n = read(rtsock, msg, sizeof(msg));
if (dflag > 1) {
@ -496,6 +498,7 @@ rtmsg_input()
* make it available again.
*/
update_prefix(prefix);
prefixchange = 1;
} else if (dflag > 1) {
syslog(LOG_DEBUG,
"<%s> new prefix(%s/%d) "
@ -509,6 +512,7 @@ rtmsg_input()
break;
}
make_prefix(rai, ifindex, addr, plen);
prefixchange = 1;
break;
case RTM_DELETE:
/* init ifflags because it may have changed */
@ -544,6 +548,7 @@ rtmsg_input()
break;
}
invalidate_prefix(prefix);
prefixchange = 1;
break;
case RTM_NEWADDR:
case RTM_DELADDR:
@ -584,6 +589,14 @@ rtmsg_input()
ra_timer_update, rai, rai);
ra_timer_update((void *)rai, &rai->timer->tm);
rtadvd_set_timer(&rai->timer->tm, rai->timer);
} else if (prefixchange &&
(iflist[ifindex]->ifm_flags & IFF_UP)) {
/*
* An advertised prefix has been added or invalidated.
* Will notice the change in a short delay.
*/
rai->initcounter = 0;
set_short_delay(rai);
}
}
@ -784,6 +797,7 @@ rs_input(int len, struct nd_router_solicit *rs,
u_char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
union nd_opts ndopts;
struct rainfo *ra;
struct soliciter *sol;
syslog(LOG_DEBUG,
"<%s> RS received from %s on %s",
@ -841,73 +855,77 @@ rs_input(int len, struct nd_router_solicit *rs,
* Decide whether to send RA according to the rate-limit
* consideration.
*/
{
long delay; /* must not be greater than 1000000 */
struct timeval interval, now, min_delay, tm_tmp, *rest;
struct soliciter *sol;
/*
* record sockaddr waiting for RA, if possible
*/
sol = (struct soliciter *)malloc(sizeof(*sol));
if (sol) {
sol->addr = *from;
/*XXX RFC2553 need clarification on flowinfo */
sol->addr.sin6_flowinfo = 0;
sol->next = ra->soliciter;
ra->soliciter = sol->next;
}
/*
* If there is already a waiting RS packet, don't
* update the timer.
*/
if (ra->waiting++)
goto done;
/*
* Compute a random delay. If the computed value
* corresponds to a time later than the time the next
* multicast RA is scheduled to be sent, ignore the random
* delay and send the advertisement at the
* already-scheduled time. RFC-2461 6.2.6
*/
delay = random() % MAX_RA_DELAY_TIME;
interval.tv_sec = 0;
interval.tv_usec = delay;
rest = rtadvd_timer_rest(ra->timer);
if (TIMEVAL_LT(*rest, interval)) {
syslog(LOG_DEBUG,
"<%s> random delay is larger than "
"the rest of normal timer",
__func__);
interval = *rest;
}
/*
* If we sent a multicast Router Advertisement within
* the last MIN_DELAY_BETWEEN_RAS seconds, schedule
* the advertisement to be sent at a time corresponding to
* MIN_DELAY_BETWEEN_RAS plus the random value after the
* previous advertisement was sent.
*/
gettimeofday(&now, NULL);
TIMEVAL_SUB(&now, &ra->lastsent, &tm_tmp);
min_delay.tv_sec = MIN_DELAY_BETWEEN_RAS;
min_delay.tv_usec = 0;
if (TIMEVAL_LT(tm_tmp, min_delay)) {
TIMEVAL_SUB(&min_delay, &tm_tmp, &min_delay);
TIMEVAL_ADD(&min_delay, &interval, &interval);
}
rtadvd_set_timer(&interval, ra->timer);
goto done;
/* record sockaddr waiting for RA, if possible */
sol = (struct soliciter *)malloc(sizeof(*sol));
if (sol) {
sol->addr = *from;
/* XXX RFC2553 need clarification on flowinfo */
sol->addr.sin6_flowinfo = 0;
sol->next = ra->soliciter;
ra->soliciter = sol;
}
/*
* If there is already a waiting RS packet, don't
* update the timer.
*/
if (ra->waiting++)
goto done;
set_short_delay(ra);
done:
free_ndopts(&ndopts);
return;
}
static void
set_short_delay(rai)
struct rainfo *rai;
{
long delay; /* must not be greater than 1000000 */
struct timeval interval, now, min_delay, tm_tmp, *rest;
/*
* Compute a random delay. If the computed value
* corresponds to a time later than the time the next
* multicast RA is scheduled to be sent, ignore the random
* delay and send the advertisement at the
* already-scheduled time. RFC-2461 6.2.6
*/
#ifdef HAVE_ARC4RANDOM
delay = arc4random() % MAX_RA_DELAY_TIME;
#else
delay = random() % MAX_RA_DELAY_TIME;
#endif
interval.tv_sec = 0;
interval.tv_usec = delay;
rest = rtadvd_timer_rest(rai->timer);
if (TIMEVAL_LT(*rest, interval)) {
syslog(LOG_DEBUG, "<%s> random delay is larger than "
"the rest of the current timer", __func__);
interval = *rest;
}
/*
* If we sent a multicast Router Advertisement within
* the last MIN_DELAY_BETWEEN_RAS seconds, schedule
* the advertisement to be sent at a time corresponding to
* MIN_DELAY_BETWEEN_RAS plus the random value after the
* previous advertisement was sent.
*/
gettimeofday(&now, NULL);
TIMEVAL_SUB(&now, &rai->lastsent, &tm_tmp);
min_delay.tv_sec = MIN_DELAY_BETWEEN_RAS;
min_delay.tv_usec = 0;
if (TIMEVAL_LT(tm_tmp, min_delay)) {
TIMEVAL_SUB(&min_delay, &tm_tmp, &min_delay);
TIMEVAL_ADD(&min_delay, &interval, &interval);
}
rtadvd_set_timer(&interval, rai->timer);
}
static void
ra_input(int len, struct nd_router_advert *ra,
struct in6_pktinfo *pi, struct sockaddr_in6 *from)
@ -1125,7 +1143,7 @@ prefix_check(struct nd_opt_prefix_info *pinfo,
gettimeofday(&now, NULL);
preferred_time += now.tv_sec;
if (rai->clockskew &&
if (!pp->timer && rai->clockskew &&
abs(preferred_time - pp->pltimeexpire) > rai->clockskew) {
syslog(LOG_INFO,
"<%s> preferred lifetime for %s/%d"
@ -1141,7 +1159,7 @@ prefix_check(struct nd_opt_prefix_info *pinfo,
pp->pltimeexpire);
inconsistent++;
}
} else if (preferred_time != pp->preflifetime) {
} else if (!pp->timer && preferred_time != pp->preflifetime) {
syslog(LOG_INFO,
"<%s> preferred lifetime for %s/%d"
" inconsistent on %s:"
@ -1161,7 +1179,7 @@ prefix_check(struct nd_opt_prefix_info *pinfo,
gettimeofday(&now, NULL);
valid_time += now.tv_sec;
if (rai->clockskew &&
if (!pp->timer && rai->clockskew &&
abs(valid_time - pp->vltimeexpire) > rai->clockskew) {
syslog(LOG_INFO,
"<%s> valid lifetime for %s/%d"
@ -1177,7 +1195,7 @@ prefix_check(struct nd_opt_prefix_info *pinfo,
pp->vltimeexpire);
inconsistent++;
}
} else if (valid_time != pp->validlifetime) {
} else if (!pp->timer && valid_time != pp->validlifetime) {
syslog(LOG_INFO,
"<%s> valid lifetime for %s/%d"
" inconsistent on %s:"
@ -1201,17 +1219,21 @@ find_prefix(struct rainfo *rai, struct in6_addr *prefix, int plen)
{
struct prefix *pp;
int bytelen, bitlen;
u_char bitmask;
for (pp = rai->prefix.next; pp != &rai->prefix; pp = pp->next) {
if (plen != pp->prefixlen)
continue;
bytelen = plen / 8;
bitlen = plen % 8;
bitmask = 0xff << (8 - bitlen);
if (memcmp((void *)prefix, (void *)&pp->prefix, bytelen))
continue;
if (prefix->s6_addr[bytelen] >> (8 - bitlen) ==
pp->prefix.s6_addr[bytelen] >> (8 - bitlen))
if (bitlen == 0 ||
((prefix->s6_addr[bytelen] & bitmask) ==
(pp->prefix.s6_addr[bytelen] & bitmask))) {
return(pp);
}
}
return(NULL);
@ -1223,16 +1245,20 @@ prefix_match(struct in6_addr *p0, int plen0,
struct in6_addr *p1, int plen1)
{
int bytelen, bitlen;
u_char bitmask;
if (plen0 < plen1)
return(0);
bytelen = plen1 / 8;
bitlen = plen1 % 8;
bitmask = 0xff << (8 - bitlen);
if (memcmp((void *)p0, (void *)p1, bytelen))
return(0);
if (p0->s6_addr[bytelen] >> (8 - bitlen) ==
p1->s6_addr[bytelen] >> (8 - bitlen))
if (bitlen == 0 ||
((p0->s6_addr[bytelen] & bitmask) ==
(p1->s6_addr[bytelen] & bitmask))) {
return(1);
}
return(0);
}
@ -1577,6 +1603,10 @@ struct rainfo *rainfo;
strerror(errno));
}
}
/* update counter */
if (rainfo->initcounter < MAX_INITIAL_RTR_ADVERTISEMENTS)
rainfo->initcounter++;
rainfo->raoutput++;
/*
* unicast advertisements
@ -1591,11 +1621,6 @@ struct rainfo *rainfo;
}
rainfo->soliciter = NULL;
/* update counter */
if (rainfo->initcounter < MAX_INITIAL_RTR_ADVERTISEMENTS)
rainfo->initcounter++;
rainfo->raoutput++;
/* update timestamp */
gettimeofday(&rainfo->lastsent, NULL);

View File

@ -1,5 +1,5 @@
# $FreeBSD$
# $KAME: rtadvd.conf,v 1.12 2001/01/21 14:56:38 itojun Exp $
# $KAME: rtadvd.conf,v 1.13 2003/06/25 03:45:21 itojun Exp $
#
# Note: All of the following parameters have default values defined
# in specifications, and hence you usually do not have to set them
@ -18,4 +18,4 @@
# this part by hand, and then invoke rtadvd with the -s option.
#ef0:\
# :addrs#1:addr="3ffe:501:ffff:1000::":prefixlen#64:
# :addr="3ffe:501:ffff:1000::":prefixlen#64:

View File

@ -1,5 +1,5 @@
.\" $FreeBSD$
.\" $KAME: rtadvd.conf.5,v 1.35 2001/05/25 07:40:22 jinmei Exp $
.\" $KAME: rtadvd.conf.5,v 1.49 2003/07/24 21:51:26 jinmei Exp $
.\"
.\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
.\" All rights reserved.
@ -80,14 +80,14 @@ will use the default values.
.It Cm \&maxinterval
(num) The maximum time allowed between sending unsolicited
multicast router advertisements
(unit: seconds).
.Pq unit: seconds .
The default value is 600.
Its value must be no less than 4 seconds
and no greater than 1800 seconds.
.It Cm \&mininterval
(num) The minimum time allowed between sending unsolicited multicast
router advertisements
(unit: seconds).
.Pq unit: seconds .
The default value is the one third of value of
.Cm maxinterval .
Its value must be no less than 3 seconds and no greater than .75 *
@ -105,27 +105,52 @@ will use the default values.
(num) The value for Cur Hop Limit field.
The default value is 64.
.It Cm \&raflags
(num) Flags field in router advertisement message header.
(str or num) A 8-bit flags field in router advertisement message header.
This field can be specified either as a case-sensitive string or as an
integer.
A sting consists of characters each of which corresponds to a
particular flag bit(s).
An integer should be the logical OR of all enabled bits.
Bit 7
.Pq Li 0x80
.Po
.Li 'm' or 0x80
.Pc
means Managed address configuration flag bit,
and Bit 6
.Pq Li 0x40
.Po
.Li 'o' or 0x40
.Pc
means Other stateful configuration flag bit.
Bit 4
.Pq Li 0x10
.Po
.Li 0x10
.Pc
and Bit 3
.Pq Li 0x08
.Po
.Li 0x08
.Pc
are used to encode router preference.
Bits 01 means high, 00 means medium, and 11 means low.
Bits 01
.Po
or 'h'
.Pc
means high, 00 means medium, and 11
.Po
or 'l'
.Pc
means low.
Bits 10 is reserved, and must not be specified.
The default value of the entire flag is 0,
There is no character to specify the medium preference explicitly.
The default value of the entire flag is 0
.Po
or a null string,
.Pc
which means no additional
configuration methods, and the medium router preference.
.It Cm \&rltime
(num) Router lifetime field
(unit: seconds).
Its value must be either zero or between
.Pq unit: seconds .
The value must be either zero or between
the value of
.Cm maxinterval
and 9000.
@ -137,11 +162,11 @@ advertising interfaces as described in
The default value is 1800.
.It Cm \&rtime
(num) Reachable time field
(unit: milliseconds).
.Pq unit: milliseconds .
The default value is 0, which means unspecified by this router.
.It Cm \&retrans
(num) Retrans Timer field
(unit: milliseconds).
.Pq unit: milliseconds .
The default value is 0, which means unspecified by this router.
.El
.Pp
@ -151,11 +176,16 @@ These items can be omitted, then
.Nm rtadvd
will automatically get appropriate prefixes from the kernel's routing table,
and advertise the prefixes with the default parameters.
Keywords other than
.Cm clockskew
can be augmented with a number, like
.Dq Li prefix2 ,
to specify multiple prefixes.
.Bl -tag -width indent
.It Cm \&clockskew
(num) Time skew to adjust link propagation delays and clock skews
between routers on the link
(unit: seconds).
.Pq unit: seconds .
This value is used in consistency check for locally-configured and
advertised prefix lifetimes, and has its meaning when the local router
configures a prefix on the link with a lifetime that decrements in
@ -163,34 +193,27 @@ real time.
If the value is 0, it means the consistency check will be skipped
for such prefixes.
The default value is 0.
.It Cm \&addrs
(num) Number of prefixes.
Its default is 0, so it must explicitly be set to positive values
if you want to specify any prefix information option.
If its value is 0,
.Xr rtadvd 8
looks up the system routing table and
advertise the prefixes corresponding to interface routes
on the interface.
If its value is more than 1, you must specify the index of the prefix
for each item below.
Indices vary from 0 to N-1, where N is the
value of
.Cm addrs .
Each index shall follow the name of each item, e.g.,
.Dq prefixlen2 .
.It Cm \&prefixlen
(num) Prefix length field.
The default value is 64.
.It Cm \&pinfoflags
(num) Flags field in prefix information option.
(str or num) A 8-bit flags field in prefix information option.
This field can be specified either as a case-sensitive string or as an
integer.
A sting consists of characters each of which corresponds to a
particular flag bit(s).
An integer should be the logical OR of all enabled bits.
Bit 7
.Pq Li 0x80
.Po
.Li 'l' or 0x80
.Pc
means On-link flag bit,
and Bit 6
.Pq Li 0x40
.Po
.Li 'a' or 0x40
.Pc
means Autonomous address-configuration flag bit.
The default value is 0xc0, i.e., both bits are set.
The default value is "la" or 0xc0, i.e., both bits are set.
.It Cm \&addr
(str) The address filled into Prefix field.
Since
@ -199,20 +222,16 @@ is used for
.Xr termcap 5
file format as well as IPv6 numeric address, the field MUST be quoted by
doublequote character.
This field cannot be
omitted if the value of
.Cm addrs
is more than 0.
.It Cm \&vltime
(num) Valid lifetime field
(unit: seconds).
.Pq unit: seconds .
The default value is 2592000 (30 days).
.It Cm \&vltimedecr
(bool) This item means the advertised valid lifetime will decrements
in real time, which is disabled by default.
.It Cm \&pltime
(num) Preferred lifetime field
(unit: seconds).
.Pq unit: seconds .
The default value is 604800 (7 days).
.It Cm \&pltimedecr
(bool) This item means the advertised preferred lifetime will decrements
@ -243,9 +262,11 @@ will use the default value.
.Bl -tag -width indent
.It Cm \&nolladdr
(bool) By default
(if
.Po
if
.Cm \&nolladdr
is not specified),
is not specified
.Pc ,
.Xr rtadvd 8
will try to get link-layer address for the interface from the kernel,
and attach that in source link-layer address option.
@ -255,7 +276,7 @@ will not attach source link-layer address option to
router advertisement packets.
.El
.Pp
The following item controls ICMPV6 home agent information option,
The following item controls ICMPv6 home agent information option,
which was defined with mobile IPv6 support.
It will be attached to router advertisement header just like other options do.
.Bl -tag -width indent
@ -278,32 +299,11 @@ explicitly.
The following items are for ICMPv6 route information option,
which will be attached to router advertisement header.
These items are optional.
Each items can be augmented with number, like
.Dq Li rtplen2 ,
to specify multiple routes.
.Bl -tag -width indent
.It Cm \&routes
(num) Number of routes.
Its default is 0, so it must explicitly be set to positive values
if you want to specify any route information option.
If its value is 0, no route information is sent.
If its value is more than 1, you must specify the index of the routes
for each item below.
Indices vary from 0 to N-1, where N is the
value of
.Cm routes.
Each index shall follow the name of each item, e.g.,
.Dq rtrplen2 .
.It Cm \&rtrplen
(num) Prefix length field in route information option.
The default value is 64.
.It Cm \&rtrflags
(num) Flags field in route information option.
Bit 4
.Pq Li 0x10
and
and Bit 3
.Pq Li 0x08
are used to encode router preference for the route.
The default value is 0x00, i.e. medium router preference.
.It Cm \&rtrprefix
.It Cm \&rtprefix
(str) The prefix filled into the Prefix field of route information option.
Since
.Dq \&:
@ -311,15 +311,49 @@ is used for
.Xr termcap 5
file format as well as IPv6 numeric address, the field MUST be quoted by
doublequote character.
This field cannot be
omitted if the value of
.Cm addrs
is more than 0.
.It Cm \&rtrltime
.It Cm \&rtplen
(num) Prefix length field in route information option.
The default value is 64.
.It Cm \&rtflags
(str or num) A 8-bit flags field in route information option.
Currently only the preference values are defined.
The notation is same as that of the raflags field.
Bit 4
.Po
.Li 0x10
.Pc
and
and Bit 3
.Po
.Li 0x08
.Pc
are used to encode the route preference for the route.
The default value is 0x00, i.e. medium preference.
.It Cm \&rtltime
(num) route lifetime field in route information option.
(unit: seconds).
The default value is 2592000 (30 days). (not specified in draft-draves-router-selection-01.txt now)
.Pq unit: seconds .
Since the specification does not define the default value of this
item, the value for this item should be specified by hand.
However,
.Nm rtadvd
allows this item to be unspecified, and uses the router lifetime
as the default value in such a case, just for compatibility with an
old version of the program.
.El
.Pp
In the above list, each keyword beginning with
.Dq Li rt
could be replaced with the one beginning with
.Dq Li rtr
for backward compatibility reason.
For example,
.Cm rtrplen
is accepted instead of
.Cm rtplen .
However, keywords that start with
.Dq Li rtr
have basically been obsoleted, and should not be used any more.
.Pp
You can also refer one line from another by using
.Cm tc
capability.
@ -353,7 +387,7 @@ option to
.Xr rtadvd 8 .
.Bd -literal -offset
ef0:\\
:addrs#1:addr="3ffe:501:ffff:1000::":prefixlen#64:
:addr="3ffe:501:ffff:1000::":prefixlen#64:
.Ed
.Pp
The following example presents the default values in an explicit manner.
@ -362,9 +396,9 @@ YOU DO NOT NEED TO HAVE IT AT ALL.
.Bd -literal -offset
default:\\
:chlim#64:raflags#0:rltime#1800:rtime#0:retrans#0:\\
:pinfoflags#192:vltime#2592000:pltime#604800:mtu#0:
:pinfoflags="la":vltime#2592000:pltime#604800:mtu#0:
ef0:\\
:addrs#1:addr="3ffe:501:ffff:1000::":prefixlen#64:tc=default:
:addr="3ffe:501:ffff:1000::":prefixlen#64:tc=default:
.Ed
.Sh SEE ALSO
.Xr termcap 5 ,
@ -381,7 +415,7 @@ Richard Draves,
.Do
Default Router Preferences and More-Specific Routes
.Dc ,
draft-ietf-ipngwg-router-selection-01.txt
draft-ietf-ipngwg-router-selection-xx.txt
.Sh HISTORY
The
.Xr rtadvd 8

View File

@ -1,5 +1,5 @@
/* $FreeBSD$ */
/* $KAME: rtadvd.h,v 1.16 2001/04/10 15:08:31 suz Exp $ */
/* $KAME: rtadvd.h,v 1.26 2003/08/05 12:34:23 itojun Exp $ */
/*
* Copyright (C) 1998 WIDE Project.
@ -45,9 +45,8 @@
#define DEF_ADVVALIDLIFETIME 2592000
#define DEF_ADVPREFERREDLIFETIME 604800
/*XXX int-to-double comparison for INTERVAL items */
#define MAXROUTERLIFETIME 9000
#define MIN_MAXINTERVAL 4.0
#define MIN_MAXINTERVAL 4
#define MAX_MAXINTERVAL 1800
#define MIN_MININTERVAL 3
#define MAXREACHABLETIME 3600000
@ -83,6 +82,7 @@ struct prefix {
struct in6_addr prefix;
};
#ifdef ROUTEINFO
struct rtinfo {
struct rtinfo *prev; /* previous link */
struct rtinfo *next; /* forward link */
@ -92,6 +92,7 @@ struct rtinfo {
int prefixlen;
struct in6_addr prefix;
};
#endif
struct soliciter {
struct soliciter *next;
@ -131,8 +132,10 @@ struct rainfo {
int pfxs; /* number of prefixes */
long clockskew; /* used for consisitency check of lifetimes */
#ifdef ROUTEINFO
struct rtinfo route; /* route information option (link head) */
int routes; /* number of route information options */
#endif
/* actual RA packet data and its length */
size_t ra_datalen;