summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2013-06-01 01:30:55 +0000
committerBrad Smith <brad@cvs.openbsd.org>2013-06-01 01:30:55 +0000
commit3d6fd0382d82211c3fc923a8af8cbd23a3121ffc (patch)
tree5d2f36b5776e44276b2f81bccebdec875c8bdc3f
parent45293e5b3c3d3b99d2820c2a7dfddc8112bf370f (diff)
Add support for advertising route information (RFC 4191).
From FreeBSD via UMEZAWA Takeshi ok bluhm@
-rw-r--r--sys/netinet/icmp6.h11
-rw-r--r--usr.sbin/rtadvd/config.c92
-rw-r--r--usr.sbin/rtadvd/config.h3
-rw-r--r--usr.sbin/rtadvd/rtadvd.conf3
-rw-r--r--usr.sbin/rtadvd/rtadvd.conf.551
-rw-r--r--usr.sbin/rtadvd/rtadvd.h13
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;