Re: DNS advertisement in RA - rtadvd(8) part

Previous thread: Gratis por TIEMPO LIMITADO by Curso Gratuito on Friday, September 10, 2010 - 4:07 pm. (1 message)

Next thread: mbuf cleanup by Bret S. Lambert on Saturday, September 11, 2010 - 10:15 am. (1 message)
From: Martin Pelikan
Date: Saturday, September 11, 2010 - 9:44 am

Hello tech@,
this is the first part of implenting RFC 5006 a.k.a. support for
learning and advertising DNS servers through IPv6 Router Advertisement.
The next part will probably be in rtsol and rtsold on the client side.
So far it loads DNS servers from resolv.conf and does so only after
start, as DNS server addresses are not likely to be changed often.
Any comments or suggestions are welcome.

--
Martin Pelikan

Index: config.c
===================================================================
RCS file: /cvs/src/usr.sbin/rtadvd/config.c,v
retrieving revision 1.26
diff -u -p -r1.26 config.c
--- config.c	23 Apr 2008 10:17:50 -0000	1.26
+++ config.c	11 Sep 2010 16:04:38 -0000
@@ -55,6 +55,7 @@
 #include <search.h>
 #include <unistd.h>
 #include <ifaddrs.h>
+#include <resolv.h>
 
 #include "rtadvd.h"
 #include "advcap.h"
@@ -67,6 +68,8 @@ static void makeentry(char *, size_t, in
 static int getinet6sysctl(int);
 
 extern struct ralist ralist;
+extern size_t rdnss_ct;
+extern struct in6_addr rdnss_addrs[MAXNS];
 
 void
 getconfig(intface)
@@ -344,6 +347,19 @@ getconfig(intface)
 		exit(1);
 	}
 
+	/* share DNS information from resolv.conf? */
+	if (agetflag("rdnss_resolv_conf")) {
+		tmp->rdnss_ct = rdnss_ct;
+		tmp->rdnss = rdnss_addrs;
+
+		MAYHAVE(val, "rdnss_lifetime", DEF_ADVPREFERREDLIFETIME);
+		tmp->rdnss_lifetime = val;
+	}
+	else {
+		tmp->rdnss_ct = tmp->rdnss_lifetime = 0;
+		tmp->rdnss = NULL;
+	}
+
 	/* route information */
 	MAYHAVE(val, "routes", -1);
 	if (val != -1)
@@ -591,13 +607,16 @@ make_prefix(struct rainfo *rai, int ifin
 void
 make_packet(struct rainfo *rainfo)
 {
+	const size_t rdnssoptlen = sizeof(struct in6_addr) * rainfo->rdnss_ct;
 	size_t packlen, lladdroptlen = 0;
 	char *buf;
 	struct nd_router_advert *ra;
 	struct nd_opt_prefix_info *ndopt_pi;
 	struct nd_opt_mtu *ndopt_mtu;
+	struct nd_opt_rdnss *ndopt_dns;
 	struct prefix *pfx;
 
 	/* calculate total length */
 	packlen = sizeof(struct nd_router_advert);
 ...
From: Martin Pelikan
Date: Saturday, September 11, 2010 - 9:47 am

Sorry, I forgot this part:

Index: icmp6.h
===================================================================
RCS file: /cvs/src/sys/netinet/icmp6.h,v
retrieving revision 1.33
diff -u -p -r1.33 icmp6.h
--- icmp6.h	22 Mar 2010 12:23:32 -0000	1.33
+++ icmp6.h	11 Sep 2010 16:20:15 -0000
@@ -282,6 +282,7 @@ struct nd_opt_hdr {		/* Neighbor discove
 #define ND_OPT_PREFIX_INFORMATION	3
 #define ND_OPT_REDIRECTED_HEADER	4
 #define ND_OPT_MTU			5
+#define ND_OPT_RDNSS			25
 
 struct nd_opt_prefix_info {	/* prefix information */
 	u_int8_t	nd_opt_pi_type;
@@ -310,6 +311,14 @@ struct nd_opt_mtu {		/* MTU option */
 	u_int8_t	nd_opt_mtu_len;
 	u_int16_t	nd_opt_mtu_reserved;
 	u_int32_t	nd_opt_mtu_mtu;
+} __packed;
+
+struct nd_opt_rdnss {		/* Recursive DNS Server option */
+	u_int8_t	nd_opt_rdnss_type;
+	u_int8_t	nd_opt_rdnss_len;
+	u_int16_t	nd_opt_rdnss_reserved;
+	u_int32_t	nd_opt_rdnss_lifetime;
+	/* followed by IP addresses of servers */
 } __packed;
 
 /*

From: Stefan Sperling
Date: Sunday, September 12, 2010 - 6:56 am

I think we'll need a way to configure nameserver addresses from rtadvd.conf.
Reading nameserver information from resolv.conf may be useful in certain
setups, but it won't make everyone happy.
What if the nameserver in resolv.conf is a loopback address?
I run named on my router so resolv.conf points to localhost.

Your diff introduces yet another copy of code parsing the resolv.conf file.
Others are in libc and named. But I guess there's no way around that short
of moving it into some library, which is out of scope for this diff.

RFC 5006 is "experimental". Do you know which operating systems have
already implemented it?

Thanks,
Stefan

From: Martin Pelikán
Date: Sunday, September 12, 2010 - 11:39 am

Sorry, but where in libc would I find a thing for reading configured
resolvers? res_init() claims to do so, but I can't see any arguments
going in or out. The rumors say named is being replaced by nsd and
personally I don't want to mess with named code...
I also thought about it, and Michael Cardell Widerkrantz, the author
of radns, the userland daemon made just for this purpose, informed me
about the openresolv library, the BSD-licensed solution of proper

AFAIK newer Windows, Linux in radvd and FreeBSD through radns on the
client side. Michael said the earlier versions of radns worked even on
Mac OS X...

-- 
Martin Pelikan

From: Stefan Sperling
Date: Sunday, September 12, 2010 - 1:05 pm

I didn't mean to imply that you should change your patch.
Yes, you have no other choice but to parse it yourself.
The other parsers in libc (res_init) and