From: Roy Marples Date: Fri, 4 Jul 2014 11:53:56 +0000 (+0000) Subject: Add --pfxdlgonly and --nopfxdlg options to spawn separate dhcpcd instances X-Git-Tag: v6.4.1~26 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=fb8a0db7c059a10447185153812c253cba27744c;p=thirdparty%2Fdhcpcd.git 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. --- diff --git a/defs.h b/defs.h index 28652fc7..1453292a 100644 --- a/defs.h +++ b/defs.h @@ -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" diff --git a/dhcp6.c b/dhcp6.c index 9cd9e734..0287fc72 100644 --- a/dhcp6.c +++ b/dhcp6.c @@ -445,17 +445,25 @@ dhcp6_makemessage(struct interface *ifp) 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 @@ dhcp6_makemessage(struct interface *ifp) } 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 @@ dhcp6_findia(struct interface *ifp, const struct dhcp6_message *m, size_t l, 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 @@ dhcp6_start(struct interface *ifp, enum DH6S init_state) 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 @@ dhcp6_dump(struct interface *ifp) 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)); diff --git a/dhcpcd.8.in b/dhcpcd.8.in index cf15227c..5ef665f8 100644 --- a/dhcpcd.8.in +++ b/dhcpcd.8.in @@ -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 @@ to rebind, reconfigure or exit need to include the same restrictive flags 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 diff --git a/dhcpcd.c b/dhcpcd.c index 3ed932b1..5d71d3a8 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -648,7 +648,7 @@ dhcpcd_startinterface(void *arg) 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 @@ dhcpcd_startinterface(void *arg) "%s: dhcp6_start: %m", ifp->name); } } + if (ifo->options & DHCPCD_PFXDLGONLY) + return; if (ifo->options & DHCPCD_IPV4) dhcp_start(ifp); @@ -1370,9 +1372,10 @@ main(int argc, char **argv) } 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 @@ main(int argc, char **argv) } #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 @@ main(int argc, char **argv) } - 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"); } diff --git a/dhcpcd.conf.5.in b/dhcpcd.conf.5.in index 9c1dccf9..f2182bb1 100644 --- a/dhcpcd.conf.5.in +++ b/dhcpcd.conf.5.in @@ -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 @@ IPv6RS should be disabled globally when requesting a Prefix Delegation like so: .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 @@ See 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 diff --git a/if-options.c b/if-options.c index fa20513e..f4f79512 100644 --- a/if-options.c +++ b/if-options.c @@ -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 @@ const struct option cf_options[] = { {"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 @@ err_sla: 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; } diff --git a/if-options.h b/if-options.h index 63618fc4..387cd7c3 100644 --- a/if-options.h +++ b/if-options.h @@ -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[];