changeset 2571:51235d228097 draft

Add --pfxdlgonly and --nopfxdlg options to spawn separate dhcpcd instances to allow for RFC conformance when you need to configure a Prefix Delegation and a Normal Address for DHCPv6 on the same interface.
author Roy Marples <roy@marples.name>
date Fri, 04 Jul 2014 11:53:56 +0000
parents 12b378a0f258
children 26808803c235
files defs.h dhcp6.c dhcpcd.8.in dhcpcd.c dhcpcd.conf.5.in if-options.c if-options.h
diffstat 7 files changed, 93 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/defs.h	Thu Jul 03 23:11:00 2014 +0000
+++ b/defs.h	Fri Jul 04 11:53:56 2014 +0000
@@ -49,7 +49,7 @@
 # define LEASEFILE		DBDIR "/" PACKAGE "-%s.lease"
 #endif
 #ifndef LEASEFILE6
-# define LEASEFILE6		DBDIR "/" PACKAGE "-%s.lease6"
+# define LEASEFILE6		DBDIR "/" PACKAGE "-%s%s.lease6"
 #endif
 #ifndef PIDFILE
 # define PIDFILE		RUNDIR "/" PACKAGE "%s%s%s.pid"
--- a/dhcp6.c	Thu Jul 03 23:11:00 2014 +0000
+++ b/dhcp6.c	Fri Jul 04 11:53:56 2014 +0000
@@ -445,17 +445,25 @@
 			if (ap->prefix_vltime == 0 &&
 			    !(ap->flags & IPV6_AF_REQUEST))
 				continue;
-			if (ap->ia_type == D6_OPTION_IA_PD)
-				len += sizeof(*o) + sizeof(u8) +
-				    sizeof(u32) + sizeof(u32) +
-				    sizeof(ap->prefix.s6_addr);
-			else
+			if (ap->ia_type == D6_OPTION_IA_PD) {
+				if (!(ifo->options & DHCPCD_NOPFXDLG))
+					len += sizeof(*o) + sizeof(u8) +
+					    sizeof(u32) + sizeof(u32) +
+					    sizeof(ap->prefix.s6_addr);
+			} else if (!(ifo->options & DHCPCD_PFXDLGONLY))
 				len += sizeof(*o) + sizeof(ap->addr.s6_addr) +
 				    sizeof(u32) + sizeof(u32);
 		}
 		/* FALLTHROUGH */
 	case DH6S_INIT:
-		len += ifo->ia_len * (sizeof(*o) + (sizeof(u32) * 3));
+		for (l = 0; l < ifo->ia_len; l++) {
+			if (ifo->ia[l].ia_type == D6_OPTION_IA_PD) {
+				if (ifo->options & DHCPCD_NOPFXDLG)
+					continue;
+			} else if (ifo->options & DHCPCD_PFXDLGONLY)
+				continue;
+			len += sizeof(*o) + (sizeof(u32) * 3);
+		}
 		IA = 1;
 		break;
 	default:
@@ -560,6 +568,11 @@
 	}
 
 	for (l = 0; IA && l < ifo->ia_len; l++) {
+		if (ifo->ia[l].ia_type == D6_OPTION_IA_PD) {
+			if (ifo->options & DHCPCD_NOPFXDLG)
+				continue;
+		} else if (ifo->options & DHCPCD_PFXDLGONLY)
+			continue;
 		o = D6_NEXT_OPTION(o);
 		o->code = htons(ifo->ia[l].ia_type);
 		o->len = htons(sizeof(u32) + sizeof(u32) + sizeof(u32));
@@ -1697,13 +1710,15 @@
 			continue;
 		}
 		if (code == D6_OPTION_IA_PD) {
-			if (dhcp6_findpd(ifp, iaid, p, ol) == 0) {
+			if (!(ifo->options & DHCPCD_NOPFXDLG) &&
+			    dhcp6_findpd(ifp, iaid, p, ol) == 0)
+			{
 				syslog(LOG_WARNING,
 				    "%s: %s: DHCPv6 REPLY missing Prefix",
 				    ifp->name, sfrom);
 				continue;
 			}
-		} else {
+		} else if (!(ifo->options & DHCPCD_PFXDLGONLY)) {
 			if (dhcp6_findna(ifp, code, iaid, p, ol) == 0) {
 				syslog(LOG_WARNING,
 				    "%s: %s: DHCPv6 REPLY missing IA Address",
@@ -2823,7 +2838,8 @@
 
 	state->state = init_state;
 	snprintf(state->leasefile, sizeof(state->leasefile),
-	    LEASEFILE6, ifp->name);
+	    LEASEFILE6, ifp->name,
+	    ifp->options->options & DHCPCD_PFXDLGONLY ? ".pd" : "");
 
 	if (ipv6_linklocal(ifp) == NULL) {
 		syslog(LOG_DEBUG,
@@ -3090,7 +3106,8 @@
 		goto eexit;
 	TAILQ_INIT(&state->addrs);
 	snprintf(state->leasefile, sizeof(state->leasefile),
-	    LEASEFILE6, ifp->name);
+	    LEASEFILE6, ifp->name,
+	    ifp->options->options & DHCPCD_PFXDLGONLY ? ".pd" : "");
 	r = dhcp6_readlease(ifp);
 	if (r == -1 && errno == ENOENT) {
 		strlcpy(state->leasefile, ifp->name, sizeof(state->leasefile));
--- a/dhcpcd.8.in	Thu Jul 03 23:11:00 2014 +0000
+++ b/dhcpcd.8.in	Fri Jul 04 11:53:56 2014 +0000
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd June 2, 2014
+.Dd July 4, 2014
 .Dt DHCPCD 8
 .Os
 .Sh NAME
@@ -68,6 +68,10 @@
 .Fl U, Fl Fl dumplease
 .Ar interface
 .Nm
+.Fl Fl pfxdlgonly
+.Nm
+.Fl Fl nopfxdlg
+.Nm
 .Fl Fl version
 .Nm
 .Fl x , Fl Fl exit
@@ -614,6 +618,30 @@
 so that
 .Nm
 knows which process to signal.
+.Pp
+.Li RFC3633
+DHCPv6 Prefix Delegation does not work in the same state or session as
+Normal or Temporary Addresses.
+.Nm
+is designed for a single state per protocol and as such
+.Li draft-ietf-dhc-dhcpv6-stateful-issues-06
+is supported by default, but that is not a published RFC yet.
+To allow RFC conformance,
+.Nm
+supports the
+.Fl Fl pfxdlgonly
+and
+.Fl Fl nopfxdlg
+options which allow the spawning of two
+.Nm
+instances to separate the Prefix Delegation state from the others.
+You may wish to disable
+.Xr dhcpcd-run-hooks 8
+on the
+.Fl Fl pfxdlgonly
+instance using the
+.Fl Fl script \"\"
+option.
 .Sh FILES
 .Bl -ohang
 .It Pa @SYSCONFDIR@/dhcpcd.conf
--- a/dhcpcd.c	Thu Jul 03 23:11:00 2014 +0000
+++ b/dhcpcd.c	Fri Jul 04 11:53:56 2014 +0000
@@ -648,7 +648,7 @@
 
 	if (ifo->options & DHCPCD_IPV6) {
 		if (ifo->options & DHCPCD_IPV6RS &&
-		    !(ifo->options & DHCPCD_INFORM))
+		    !(ifo->options & (DHCPCD_INFORM | DHCPCD_PFXDLGONLY)))
 			ipv6nd_startrs(ifp);
 
 		if (!(ifo->options & DHCPCD_IPV6RS) ||
@@ -680,6 +680,8 @@
 				    "%s: dhcp6_start: %m", ifp->name);
 		}
 	}
+	if (ifo->options & DHCPCD_PFXDLGONLY)
+		return;
 
 	if (ifo->options & DHCPCD_IPV4)
 		dhcp_start(ifp);
@@ -1370,9 +1372,10 @@
 			}
 			snprintf(pidfile, sizeof(pidfile),
 			    PIDFILE, "-", argv[optind], per);
-		}
-		else {
-			snprintf(pidfile, sizeof(pidfile), PIDFILE, "", "", "");
+		} else {
+			snprintf(pidfile, sizeof(pidfile), PIDFILE,
+			    ctx.options & DHCPCD_PFXDLGONLY ? ".pd" : "",
+			    "", "");
 			ctx.options |= DHCPCD_MASTER;
 		}
 	}
@@ -1425,7 +1428,7 @@
 	}
 
 #ifdef USE_SIGNALS
-	if (!(ctx.options & DHCPCD_TEST) &&
+	if (!(ctx.options & (DHCPCD_TEST | DHCPCD_PFXDLGONLY)) &&
 	    (sig == 0 || ctx.ifc != 0))
 	{
 #endif
@@ -1541,7 +1544,7 @@
 	}
 
 
-	if (ctx.options & DHCPCD_MASTER) {
+	if (ctx.options & DHCPCD_MASTER && !(ctx.options & DHCPCD_PFXDLGONLY)) {
 		if (control_start(&ctx, NULL) == -1)
 			syslog(LOG_ERR, "control_start: %m");
 	}
--- a/dhcpcd.conf.5.in	Thu Jul 03 23:11:00 2014 +0000
+++ b/dhcpcd.conf.5.in	Fri Jul 04 11:53:56 2014 +0000
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd July 1, 2014
+.Dd July 4, 2014
 .Dt DHCPCD.CONF 5
 .Os
 .Sh NAME
@@ -290,6 +290,12 @@
 .D1 interface eth1
 .D1 ipv4
 .D1 ipv6rs
+.Pp
+Using this option with other IA options in the same interface block is not
+currently RFC conformant.
+Please see the
+.Li BUGS
+section below.
 .It Ic ipv4only
 Only configure IPv4.
 .It Ic ipv6only
@@ -749,6 +755,14 @@
 for details.
 .Nm dhcpcd
 strives to comply with this document and will be updated when finally published.
+To enable RFC conformance, spawn separate
+.Nm dhcpcd
+instances using the
+.Fl Fl pfxdlgonly
+and
+.Fl Fl nopfxdlg
+options as described in
+.Xr dhcpcd 8 .
 .Pp
 Please report them to
 .Lk http://roy.marples.name/projects/dhcpcd
--- a/if-options.c	Thu Jul 03 23:11:00 2014 +0000
+++ b/if-options.c	Fri Jul 04 11:53:56 2014 +0000
@@ -93,6 +93,8 @@
 #define O_CONTROLGRP		O_BASE + 34
 #define O_SLAAC			O_BASE + 35
 #define O_GATEWAY		O_BASE + 36
+#define O_NOPFXDLG		O_BASE + 37
+#define O_PFXDLGONLY		O_BASE + 38
 
 const struct option cf_options[] = {
 	{"background",      no_argument,       NULL, 'b'},
@@ -179,6 +181,8 @@
 	{"controlgroup",    required_argument, NULL, O_CONTROLGRP},
 	{"slaac",           required_argument, NULL, O_SLAAC},
 	{"gateway",         no_argument,       NULL, O_GATEWAY},
+	{"nopfxdlg",        no_argument,       NULL, O_NOPFXDLG},
+	{"pfxdlgonly",      no_argument,       NULL, O_PFXDLGONLY},
 	{NULL,              0,                 NULL, '\0'}
 };
 
@@ -1909,6 +1913,12 @@
 		else
 			ifo->options &= ~DHCPCD_SLAACPRIVATE;
 		break;
+	case O_NOPFXDLG:
+		ifo->options |= DHCPCD_NOPFXDLG;
+		break;
+	case O_PFXDLGONLY:
+		ifo->options |= DHCPCD_PFXDLGONLY;
+		break;
 	default:
 		return 0;
 	}
--- a/if-options.h	Thu Jul 03 23:11:00 2014 +0000
+++ b/if-options.h	Fri Jul 04 11:53:56 2014 +0000
@@ -102,6 +102,8 @@
 #define DHCPCD_IAID			(1ULL << 48)
 #define DHCPCD_DHCP			(1ULL << 49)
 #define DHCPCD_DHCP6			(1ULL << 50)
+#define DHCPCD_NOPFXDLG			(1ULL << 51)
+#define DHCPCD_PFXDLGONLY		(1ULL << 52)
 
 extern const struct option cf_options[];