]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Add --pfxdlgonly and --nopfxdlg options to spawn separate dhcpcd instances
authorRoy Marples <roy@marples.name>
Fri, 4 Jul 2014 11:53:56 +0000 (11:53 +0000)
committerRoy Marples <roy@marples.name>
Fri, 4 Jul 2014 11:53:56 +0000 (11:53 +0000)
to allow for RFC conformance when you need to configure a Prefix Delegation
and a Normal Address for DHCPv6 on the same interface.

defs.h
dhcp6.c
dhcpcd.8.in
dhcpcd.c
dhcpcd.conf.5.in
if-options.c
if-options.h

diff --git a/defs.h b/defs.h
index 28652fc76e26243a7cc03a8d000cf080f6bc4413..1453292a5ef5b2f9fe571dd69343de52b174b587 100644 (file)
--- 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 9cd9e734322a8439703a9dfc96f7397a5bb5f3eb..0287fc72fdbe97c4ccc5dd6adc889cf1b362b66d 100644 (file)
--- 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));
index cf15227cd157a1b20a1c6af6cacd81eaa9d3b55f..5ef665f818230b9e1125953d73e57e5017ba9ecd 100644 (file)
@@ -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
 .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
index 3ed932b133192d2eaa78291d2321ae02db09dff2..5d71d3a8bf5406da440cb60b1523793ab9c22ae9 100644 (file)
--- 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");
        }
index 9c1dccf9f4ff8c5b645f15a8fb63970a62cac837..f2182bb195d8831ddd178c14dc089c1cd747e5df 100644 (file)
@@ -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
index fa20513e0f60e70d7cb465f72bb4b4319a1d9dea..f4f795128bb3e7247a29b1d1a5a3920929f503ea 100644 (file)
@@ -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;
        }
index 63618fc4f2a86d9d8ad8483833bdb727ee1d90a8..387cd7c3a03a9b90e638c752a84bcbe0547d886e 100644 (file)
 #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[];