diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2013-06-01 01:30:55 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2013-06-01 01:30:55 +0000 |
commit | 3d6fd0382d82211c3fc923a8af8cbd23a3121ffc (patch) | |
tree | 5d2f36b5776e44276b2f81bccebdec875c8bdc3f | |
parent | 45293e5b3c3d3b99d2820c2a7dfddc8112bf370f (diff) |
Add support for advertising route information (RFC 4191).
From FreeBSD via UMEZAWA Takeshi
ok bluhm@
-rw-r--r-- | sys/netinet/icmp6.h | 11 | ||||
-rw-r--r-- | usr.sbin/rtadvd/config.c | 92 | ||||
-rw-r--r-- | usr.sbin/rtadvd/config.h | 3 | ||||
-rw-r--r-- | usr.sbin/rtadvd/rtadvd.conf | 3 | ||||
-rw-r--r-- | usr.sbin/rtadvd/rtadvd.conf.5 | 51 | ||||
-rw-r--r-- | usr.sbin/rtadvd/rtadvd.h | 13 |
6 files changed, 166 insertions, 7 deletions
diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h index c8e2d0ba332..5bd1943fe98 100644 --- a/sys/netinet/icmp6.h +++ b/sys/netinet/icmp6.h @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.h,v 1.35 2013/03/17 00:38:29 brad Exp $ */ +/* $OpenBSD: icmp6.h,v 1.36 2013/06/01 01:30:53 brad Exp $ */ /* $KAME: icmp6.h,v 1.84 2003/04/23 10:26:51 itojun Exp $ */ /* @@ -290,6 +290,7 @@ struct nd_opt_hdr { /* Neighbor discovery option header */ #define ND_OPT_PREFIX_INFORMATION 3 #define ND_OPT_REDIRECTED_HEADER 4 #define ND_OPT_MTU 5 +#define ND_OPT_ROUTE_INFO 24 #define ND_OPT_RDNSS 25 #define ND_OPT_DNSSL 31 @@ -322,6 +323,14 @@ struct nd_opt_mtu { /* MTU option */ u_int32_t nd_opt_mtu_mtu; } __packed; +struct nd_opt_route_info { /* route info */ + u_int8_t nd_opt_rti_type; + u_int8_t nd_opt_rti_len; + u_int8_t nd_opt_rti_prefixlen; + u_int8_t nd_opt_rti_flags; + u_int32_t nd_opt_rti_lifetime; +} __packed; + struct nd_opt_rdnss { /* RDNSS option */ u_int8_t nd_opt_rdnss_type; u_int8_t nd_opt_rdnss_len; diff --git a/usr.sbin/rtadvd/config.c b/usr.sbin/rtadvd/config.c index 28ee0116b2b..9be52fbe4c3 100644 --- a/usr.sbin/rtadvd/config.c +++ b/usr.sbin/rtadvd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.37 2013/05/08 06:32:07 brad Exp $ */ +/* $OpenBSD: config.c,v 1.38 2013/06/01 01:30:53 brad Exp $ */ /* $KAME: config.c,v 1.62 2002/05/29 10:13:10 itojun Exp $ */ /* @@ -109,6 +109,7 @@ getconfig(intface) fatal("malloc"); TAILQ_INIT(&tmp->prefixes); + TAILQ_INIT(&tmp->rtinfos); TAILQ_INIT(&tmp->rdnsss); TAILQ_INIT(&tmp->dnssls); SLIST_INIT(&tmp->soliciters); @@ -321,6 +322,77 @@ getconfig(intface) if (tmp->pfxs == 0 && !agetflag("noifprefix")) get_prefix(tmp); + tmp->rtinfocnt = 0; + for (i = -1; i < MAXRTINFO; i++) { + struct rtinfo *rti; + char entbuf[256]; + const char *flagstr; + + makeentry(entbuf, sizeof(entbuf), i, "rtprefix"); + addr = (char *)agetstr(entbuf, &bp); + if (addr == NULL) + continue; + + rti = malloc(sizeof(struct rtinfo)); + if (rti == NULL) + fatal("malloc"); + + if (inet_pton(AF_INET6, addr, &rti->prefix) != 1) { + log_warn("inet_pton failed for %s", addr); + exit(1); + } + + makeentry(entbuf, sizeof(entbuf), i, "rtplen"); + MAYHAVE(val, entbuf, 64); + if (val < 0 || val > 128) { + log_warnx("route prefixlen (%ld) for %s " + "on %s out of range", + 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) { + log_warnx("the \'h\' and \'l\'" + " route preferences are" + " exclusive"); + exit(1); + } + val |= ND_RA_FLAG_RTPREF_LOW; + } + } else + MAYHAVE(val, entbuf, 0); + + rti->rtpref = val & ND_RA_FLAG_RTPREF_MASK; + if (rti->rtpref == ND_RA_FLAG_RTPREF_RSV) { + log_warnx("invalid route preference (%02x)" + " for %s/%d on %s", + rti->rtpref, addr, rti->prefixlen, intface); + exit(1); + } + + makeentry(entbuf, sizeof(entbuf), i, "rtltime"); + MAYHAVE(val64, entbuf, -1); + if (val64 == -1) + val64 = tmp->lifetime; + if (val64 < 0 || val64 >= 0xffffffff) { + log_warnx("route lifetime (%d) " + " for %s/%d on %s out of range", + rti->rtpref, addr, rti->prefixlen, intface); + exit(1); + } + rti->lifetime = (uint32_t)val64; + + TAILQ_INSERT_TAIL(&tmp->rtinfos, rti, entry); + tmp->rtinfocnt++; + } + tmp->rdnsscnt = 0; for (i = -1; i < MAXRDNSS; ++i) { struct rdnss *rds; @@ -694,9 +766,11 @@ make_packet(struct rainfo *rainfo) struct nd_router_advert *ra; struct nd_opt_prefix_info *ndopt_pi; struct nd_opt_mtu *ndopt_mtu; + struct nd_opt_route_info *ndopt_rti; struct nd_opt_rdnss *ndopt_rdnss; struct nd_opt_dnssl *ndopt_dnssl; struct prefix *pfx; + struct rtinfo *rti; struct rdnss *rds; struct dnssl *dsl; struct dnssldom *dnsd; @@ -716,6 +790,9 @@ make_packet(struct rainfo *rainfo) packlen += sizeof(struct nd_opt_prefix_info) * rainfo->pfxs; if (rainfo->linkmtu) packlen += sizeof(struct nd_opt_mtu); + TAILQ_FOREACH(rti, &rainfo->rtinfos, entry) + packlen += sizeof(struct nd_opt_route_info) + + ((rti->prefixlen + 0x3f) >> 6) * 8; TAILQ_FOREACH(rds, &rainfo->rdnsss, entry) packlen += sizeof(struct nd_opt_rdnss) + 16 * rds->servercnt; TAILQ_FOREACH(dsl, &rainfo->dnssls, entry) { @@ -826,6 +903,19 @@ make_packet(struct rainfo *rainfo) buf += sizeof(struct nd_opt_prefix_info); } + TAILQ_FOREACH(rti, &rainfo->rtinfos, entry) { + uint8_t psize = (rti->prefixlen + 0x3f) >> 6; + + ndopt_rti = (struct nd_opt_route_info *)buf; + ndopt_rti->nd_opt_rti_type = ND_OPT_ROUTE_INFO; + ndopt_rti->nd_opt_rti_len = 1 + psize; + ndopt_rti->nd_opt_rti_prefixlen = rti->prefixlen; + ndopt_rti->nd_opt_rti_flags = 0xff & rti->rtpref; + ndopt_rti->nd_opt_rti_lifetime = htonl(rti->lifetime); + memcpy(ndopt_rti + 1, &rti->prefix, psize * 8); + buf += sizeof(struct nd_opt_route_info) + psize * 8; + } + TAILQ_FOREACH(rds, &rainfo->rdnsss, entry) { ndopt_rdnss = (struct nd_opt_rdnss *)buf; ndopt_rdnss->nd_opt_rdnss_type = ND_OPT_RDNSS; diff --git a/usr.sbin/rtadvd/config.h b/usr.sbin/rtadvd/config.h index 53b97bc3406..64622f0ea3f 100644 --- a/usr.sbin/rtadvd/config.h +++ b/usr.sbin/rtadvd/config.h @@ -1,4 +1,4 @@ -/* $OpenBSD: config.h,v 1.7 2012/07/08 10:46:00 phessler Exp $ */ +/* $OpenBSD: config.h,v 1.8 2013/06/01 01:30:54 brad Exp $ */ /* $KAME: config.h,v 1.3 2000/05/16 13:34:13 itojun Exp $ */ /* @@ -42,5 +42,6 @@ extern void get_prefix __P((struct rainfo *)); * so it should be okay to limit it */ #define MAXPREFIX 100 +#define MAXRTINFO 100 #define MAXRDNSS 100 #define MAXDNSSL 100 diff --git a/usr.sbin/rtadvd/rtadvd.conf b/usr.sbin/rtadvd/rtadvd.conf index 04725a4df34..d610925bfae 100644 --- a/usr.sbin/rtadvd/rtadvd.conf +++ b/usr.sbin/rtadvd/rtadvd.conf @@ -1,4 +1,4 @@ -# $OpenBSD: rtadvd.conf,v 1.7 2012/07/08 10:46:00 phessler Exp $ +# $OpenBSD: rtadvd.conf,v 1.8 2013/06/01 01:30:54 brad Exp $ # $KAME: rtadvd.conf,v 1.12 2001/01/21 14:56:38 itojun Exp $ # # Note: All of the following parameters have default values defined @@ -19,4 +19,5 @@ #ef0:\ # :addr="2001:db8:ffff:1000::":prefixlen#64:\ +# :rtprefix="2001:db8:ffff:1001::":\ # :rdnss="2001:db8:ffff:1000::1":dnssl="example.com": diff --git a/usr.sbin/rtadvd/rtadvd.conf.5 b/usr.sbin/rtadvd/rtadvd.conf.5 index 621ffde4d8b..b062ca16796 100644 --- a/usr.sbin/rtadvd/rtadvd.conf.5 +++ b/usr.sbin/rtadvd/rtadvd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: rtadvd.conf.5,v 1.32 2013/03/30 02:49:38 lteo Exp $ +.\" $OpenBSD: rtadvd.conf.5,v 1.33 2013/06/01 01:30:54 brad Exp $ .\" $KAME: rtadvd.conf.5,v 1.46 2003/06/17 08:26:35 itojun Exp $ .\" .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -28,7 +28,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd $Mdocdate: March 30 2013 $ +.Dd $Mdocdate: June 1 2013 $ .Dt RTADVD.CONF 5 .Os .Sh NAME @@ -231,6 +231,45 @@ is specified for this item, MTU option will be included and its value will be set to the interface MTU automatically. .El .Pp +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 \&rtprefix +(str) The prefix filled into the Prefix field of route information option. +Since +.Dq \&: +is used for +.Xr termcap 5 +file format as well as IPv6 numeric address, the field MUST be quoted by +doublequote character. +.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 +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. +.Pq unit: seconds . +The default value is same as router lifetime. +.El +.Pp The following items are for ICMPv6 RDNSS option, used to give a list of recursive DNS servers to hosts. If this item is omitted, no information about DNS servers will be advertised. @@ -341,6 +380,14 @@ ef0:\e .Xr rtsol 8 .Sh STANDARDS .Rs +.%A R. Draves +.%A D. Thaler +.%D 2005 +.%R RFC 4191 +.%T Default Router Preferences and More-Specific Routes +.Re +.Pp +.Rs .%A T. Narten .%A E. Nordmark .%A W. Simpson diff --git a/usr.sbin/rtadvd/rtadvd.h b/usr.sbin/rtadvd/rtadvd.h index 49e31949de5..745dbd17251 100644 --- a/usr.sbin/rtadvd/rtadvd.h +++ b/usr.sbin/rtadvd/rtadvd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rtadvd.h,v 1.15 2013/05/08 06:30:25 brad Exp $ */ +/* $OpenBSD: rtadvd.h,v 1.16 2013/06/01 01:30:54 brad Exp $ */ /* $KAME: rtadvd.h,v 1.20 2002/05/29 10:13:10 itojun Exp $ */ /* @@ -82,6 +82,15 @@ struct prefix { struct in6_addr prefix; }; +struct rtinfo { + TAILQ_ENTRY(rtinfo) entry; + + uint32_t lifetime; + int rtpref; + int prefixlen; + struct in6_addr prefix; +}; + /* * `struct rdnss` may contain an arbitrary number of `servers` and `struct * dnssldom` will contain a variable-sized `domain`. Space required for these @@ -147,6 +156,8 @@ struct rainfo { u_int hoplimit; /* AdvCurHopLimit */ TAILQ_HEAD(prefixlist, prefix) prefixes; /* AdvPrefixList(link head) */ int pfxs; /* number of prefixes */ + TAILQ_HEAD(rtinfolist, rtinfo) rtinfos; + int rtinfocnt; TAILQ_HEAD(rdnsslist, rdnss) rdnsss; /* advertised recursive dns servers */ int rdnsscnt; /* number of rdnss entries */ TAILQ_HEAD(dnssllist, dnssl) dnssls; |