Subject: bin/21872: rtadvd.conf - indexes disabled when addrs=#1
To: None <gnats-bugs@gnats.netbsd.org>
From: None <andrew.e.white@motorola.com>
List: netbsd-bugs
Date: 06/13/2003 04:03:39
>Number:         21872
>Category:       bin
>Synopsis:       rtadvd.conf - indexes disabled when addrs=#1
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Jun 13 04:04:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Andrew White
>Release:        1.6
>Organization:
MARC
>Environment:
NetBSD gateway.private.arpa. 1.6 NetBSD 1.6 (GENERIC) #1: Fri Apr  4 19:45:22 EST 2003
(compiled locally)
>Description:
When addrs#1, rtadvd (in config.c) assumes that all configuration options are NOT subscripted.  For example:

makeentry(entbuf, i, "addr", added);
addr = (char *)agetstr(entbuf, &bp);
if (addr == NULL) {
    syslog(LOG_ERR,
        "<%s> need %s as an prefix for "
        "interface %s",
        __FUNCTION__, entbuf, intface);
    exit(1);
}

'makeentry(entbuf, i, "addr", added)' converts to "addrN" (where N = i) if added is true, or "addr" otherwise.

added is set 0 if pfxs (# of prefixes) <= 1, or 1 otherwise.

This has the interesting side effect that setting addrs = 1 disables the ability to use suffixed mode addresses (specifically "addr0").  However, if addrs > 1, you MUST ust suffixed mode addresses, including "addr0".

This is not intuitive from the manual page, which specifies only:

"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 addrs.  Each index shall follow the name of each item, e.g., ``prefixlen2''."

It does not follow from the above text that if addrs is 1 that addr0 (or prefixlen0 or ...) will mysteriously fail.

The config.c behaviour also means that a different syntax is used for the one address case than the general case.  Relevant code is lines 285 .. 397 of config.c.
>How-To-Repeat:
Following the style of the example listed in the rtadvd.conf man page, add the following entry to rtadvd.conf (changing interface name as appropriate):

ef0:\
  :addrs#2:\
  :addr0="fec0:1234:5678:1::":\
  :addr1="fec0:8765:4321:1::":\
  :tc=ether:

All other things being equal, this will work.

Now, delete the second address and edit addrs accordingly:

ef0:\
  :addrs#1:\
  :addr0="fec0:1234:5678:1::":\
  :tc=ether:

This will fail with error:

<getconfig> need addr as an prefix for interface ef0

The error can be fixed by removing the '0' from 'addr0'.  The special case code in config.c creates an unexpected (and unwelcome) exception to standard behaviour.
>Fix:
Most robust option:

Remove special case from behaviour.  Require index for all situations, not just those where there is more than one address.

Problem:

- Legacy code will break.


Alternative option:

For each test in lines 285 .. 397 of config.c, first attempt to get indexed version.  If indexed version doesn't exist, then if pfxs == 1 attempt to get non-indexed version.

Problem:

- MAYHAVE macro behaviour not easily compatible with this option.  MAYHAVE macro (and surrounding code) in this section would need to be replaced with:

makeentry (entbuf, i, "option", 1);
var = agetnum (entbuf);
if (var < 0 && ! added)
{
  makeentry (entbuf, i, "option", 0);
  var = agetnum (entbuf);
}
if (var < 0)
  var = def;


Incidentally, the < 0 test for "prefixlen", "pltime" and "vltime" is only partially effective, since MAYHAVE silently replaces any value <= 0 (not just -1) with the default.
>Release-Note:
>Audit-Trail:
>Unformatted: