IPv6 Router Advertisement Option for RDNSS

IPv6 Router Advertisement Option for DNS Configuration (RFC 5006)[1]
introduced a mechanism to hand out recursive DNS server addresses via
router advertisement (RA) messages. This simple combines the IPv6
stateless address auto-configuration process with the ability to get DNS
server information - in one message. This options frees many
environments from operating an additional DHCPv6 server that provides
such information.

This patch extends quagga by the ability to generate and transport RDNS
addresses. RDNSS options are currently supported at radvd(1) and the
Linux Kernel by handover this information to the user-space (via netlink
socket).

A simple RA configuration with two RDNS entries can be enabled via

no ipv6 nd suppress-ra
ipv6 nd prefix 2001:db8::/64
ipv6 nd rdnss 2001:db8::1
ipv6 nd rdnss 2001:db8::2

It is additionally possible to specify the lifetime of an RDNSS option
as stated in [1] section 4.1. The default is infinity lifetime
(0xfffffff) as it serves the most common application areas.

ip nd rdnss 2001:db8::1 300000

[1] http://tools.ietf.org/html/rfc5006

Signed-off-by: Hagen Paul Pfeifer <hagen@jauu.net>

Conflicts:

	zebra/interface.c
	zebra/rtadv.c
extend IPv6 documention for RDNSS option

RDNSS RA are specified by RFC 5006 and supported by quagga. This extends
the user documentation to illustrate these changes and explain user
visable flags.

Signed-off-by: Hagen Paul Pfeifer <hagen@jauu.net>

Conflicts:

	doc/ipv6.texi
zebra: fix rtadv/rdnss vtysh breakage
zebra: fix rdnss on NetBSD

NetBSD ships struct nd_opt_rdnss in netinet/icmp6.h. fix zebra RDNSS to
detect and use that if present.
zebra: dismiss a type cast in rtadv_config_write()
zebra: improve RFC compliance in RDNSS code

This commit addresses several issues in the recently merged RDNSS
implementation:

1. Lifetime is now stored per-address (as it is configured in the CLI),
not per-interface. This for now results in multiple RDNSS TLVs in the
RA packet, even when all the servers have the same lifetime value.
Per-lifetime server grouping in TLV is possible, but not required by
RFC, and is left for a future implementation.

2. Lifetime is now enforced to take only values permitted by the RFC
(regardless if the user is changing the lifetime or ra-interval).

3. Lifetime default value is now 2 times the current MaxRtrAdvInterval
(same as in rtadvd), not infinity.

* zebra/interface.h: remove two fields from struct rtadvconf
* zebra/interface.c
  * if_zebra_new_hook(): remove initialization
  * nd_dump_vty(): use listcount()
* zebra/rtadv.h: introduce struct rtadv_rdnss_entry
* zebra/rtadv.c
  * rtadv_send_packet(): rewrite RDNSS TLV setup
  * rtadv_rdnss_lifetime_fits(): new helper function
  * ipv6_nd_ra_interval_msec(): add RDNSS Lifetime constraint check
  * ipv6_nd_ra_interval(): idem
  * rtadv_rdnss_lookup(): update to use struct in6_addr as input and
    struct rtadv_rdnss_entry as result
  * rtadv_rdnss_set(): dismiss, merged into ipv6_nd_rdnss()
  * rtadv_rdnss_reset(): comment out, unused
  * ipv6_nd_rdnss(): rewrite around struct rtadv_rdnss_entry, add
    constraint checks and list management
zebra: justify RDNSS CLI

This commit adds two missing "no ipv6 rdnss ..." CLI commands and makes
the running-config text feature necessary "ipv6 nd rdnss ..." lines.

* zebra/rtadv.c
  * rtadv_rdnss_reset(): dismiss, merged into no_ipv6_nd_rdnss_addr()
  * no_ipv6_nd_rdnss_addr(): new VTY function with list management
  * rtadv_config_write(): add output of RDNSS entries
  * rtadv_init(): register new commands
zebra: justify RDNSS as a part of RFC6106

This commit updates RDNSS documentation to match the current behaviour
of the code and performs renaming of assorted bits to make a later
implementation of DNSSL, the other part of RFC6106, simpler.

* doc/ipv6.texi: update
* zebra/interface.h: rename lifetime macros
* zebra/rtadv.h: update comments
* zebra/rtadv.c
  * rtadv_send_packet(): rename "entry" to "rdnss_entry"
  * ipv6_nd_ra_interval_msec(): idem
  * ipv6_nd_ra_interval(): idem
  * rtadv_config_write(): idem
  * ipv6_nd_rdnss(): rename to ipv6_nd_rdnss_addr to meet the pattern
  * rtadv_init(): update
zebra: refactor rtadv_rdnss_lifetime_fits()
zebra: initial DNSSL implementation

So far Quagga implemented RFC5006, which mainly consisted of RDNSS RA
option only. RFC5006 was eventually obsoleted by RFC6106, which extended
the spec with another RA option (DNSSL). This commit adds enough DNSSL
code and documentation to consider Quagga RFC6106-compliant.

* configure.ac: add check for struct nd_opt_dnssl
* doc/ipv6.texi: add description of "[no] ipv6 nd dnssl ..." commands
* zebra/interface.h: one more list in struct rtadvconf
* zebra/interface.c
  * if_zebra_new_hook(): add list initialization
  * nd_dump_vty(): update
* zebra/rtadv.h: add related macros and structures
* zebra/rtadv.c
  * rtadv_send_packet(): add DNSSL TLV generation
  * ipv6_nd_ra_interval_msec(): add DNSSL Lifetime constraint check
  * ipv6_nd_ra_interval(): idem
  * is_rfc1035_digit(): new static inline helper function
  * is_rfc1035_letter(): idem
  * is_rfc1035_let_dig(): idem
  * is_rfc1035_let_dig_hyp(): idem
  * is_rfc1035_ldh_str(): idem
  * is_rfc1035_label(): idem
  * parse_rfc1035_subdomain(): new function, RFC1035 validator/encoder
  * rtadv_dnssl_lookup(): new function similar to rtadv_rdnss_lookup()
  * ipv6_nd_dnssl_domain: new DEFUN with ALIAS
  * no_ipv6_nd_dnssl_domain(): idem
  * rtadv_config_write(): add "ipv6 nd dnssl ..." generation block
  * rtadv_init(): update for added VTY commands
zebra: immediately send a router advertisement if RA config changed.

* rtadv.c (ipv6_nd_ra_lifetime, no_ipv6_nd_ra_lifetime,
  ipv6_nd_reachable_time, no_ipv6_nd_reachable_time,
  ipv6_nd_homeagent_preference, no_ipv6_nd_homeagent_preference,
  ipv6_nd_homeagent_lifetime, no_ipv6_nd_homeagent_lifetime,
  ipv6_nd_managed_config_flag, no_ipv6_nd_managed_config_flag,
  ipv6_nd_homeagent_config_flag, no_ipv6_nd_homeagent_config_flag,
  ipv6_nd_other_config_flag, no_ipv6_nd_other_config_flag,
  ipv6_nd_prefix, no_ipv6_nd_prefix, ipv6_nd_router_preference,
  no_ipv6_nd_router_preference, ipv6_nd_mtu, no_ipv6_nd_mtu,
  ipv6_nd_rdnss_addr, ipv6_nd_dnssl_domain, no_ipv6_nd_dnssl_domain):
  reset AdvInternalTimer to 0 when RA config changes. This will trigger
  (almost) immediate resend of a new Router Advertisement packet reflecting
  new configuration.