]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
Add an option to fallback to a profile when DHCP fails.
authorRoy Marples <roy@marples.name>
Sat, 18 Apr 2009 21:43:23 +0000 (21:43 +0000)
committerRoy Marples <roy@marples.name>
Sat, 18 Apr 2009 21:43:23 +0000 (21:43 +0000)
dhcpcd.c
dhcpcd.conf.5.in
if-options.c
if-options.h

index b76538839cd541d683064704857b520b270c5ac7..11107daf2e51c2a0d70ceb7b783a0ff45767126f 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -765,6 +765,17 @@ select_profile(struct interface *iface, const char *profile)
        return 0;
 }
 
+static void
+start_fallback(void *arg)
+{
+       struct interface *iface;
+
+       iface = (struct interface *)arg;
+       select_profile(iface, iface->state->options->fallback);
+       configure_interface1(iface);
+       start_interface(iface);
+}
+
 static void
 configure_interface(struct interface *iface, int argc, char **argv)
 {
@@ -773,12 +784,13 @@ configure_interface(struct interface *iface, int argc, char **argv)
        configure_interface1(iface);
 }
 
-
 static void
 handle_carrier(const char *ifname)
 {
        struct interface *iface;
 
+       if (!(options & DHCPCD_LINK))
+               return;
        for (iface = ifaces; iface; iface = iface->next)
                if (strcmp(iface->name, ifname) == 0)
                        break;
@@ -823,7 +835,9 @@ start_discover(void *arg)
        iface->state->xid = arc4random();
        open_sockets(iface);
        delete_timeout(NULL, iface);
-       if (ifo->options & DHCPCD_IPV4LL &&
+       if (ifo->fallback)
+               add_timeout_sec(ifo->timeout, start_fallback, iface);
+       else if (ifo->options & DHCPCD_IPV4LL &&
            !IN_LINKLOCAL(htonl(iface->addr.s_addr)))
        {
                if (IN_LINKLOCAL(htonl(iface->state->fail.s_addr)))
@@ -974,7 +988,10 @@ start_reboot(struct interface *iface)
        iface->state->xid = arc4random();
        iface->state->lease.server.s_addr = 0;
        delete_timeout(NULL, iface);
-       if (ifo->options & DHCPCD_LASTLEASE && iface->state->lease.frominfo)
+       if (ifo->fallback)
+               add_timeout_sec(ifo->reboot, start_fallback, iface);
+       else if (ifo->options & DHCPCD_LASTLEASE &&
+           iface->state->lease.frominfo)
                add_timeout_sec(ifo->reboot, start_timeout, iface);
        else if (!(ifo->options & DHCPCD_INFORM &&
                options & (DHCPCD_MASTER | DHCPCD_DAEMONISED)))
index 51793773f068fad71b3aa2a1c20b604db606caf6..ec58b866019b2f9cf80a6c4d12adb9d40a0025eb 100644 (file)
@@ -22,7 +22,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd March 31, 2009
+.Dd April 18, 2009
 .Dt DHCPCD.CONF 5 SMM
 .Os
 .Sh NAME
@@ -59,7 +59,7 @@ which is a space or comma separated list of patterns passed to
 .Xr fnmatch 3 .
 .It Ic arping Ar address Op address
 .Nm dhcpcd
-will arping each address in order.
+will arping each address in order before attempting DHCP.
 If an address is found, we will select the replying hardware address as the
 profile, otherwise the ip address.
 Example:
@@ -98,9 +98,12 @@ not enabled by default.
 The duid generated will be held in
 .Pa @SYSCONFDIR@/dhcpcd.duid
 and should not be copied to other hosts.
+.It Ic fallback Ar profile
+Fallback to using this profile if DHCP fails.
+This allows you to configure a static profile instead of using ZeroConf.
 .It Ic hostname Ar name
 Sends specified
-.Ar hostname 
+.Ar hostname
 to the DHCP server so it can be registered in DNS. If
 .Ar hostname
 if a FQDN (ie, contains a .) then it will be encoded as such.
index 8f52d9311412cb4dac5dd34535cdb1c26b4c5a5d..8122697810730cb8f37e818f62e818cc65f8f18c 100644 (file)
@@ -49,6 +49,7 @@
    valid short options for them */
 #define O_BASE         MAX('z', 'Z') + 1
 #define O_ARPING       O_BASE + 1
+#define O_FALLBACK     O_BASE + 2
 
 const struct option cf_options[] = {
        {"background",      no_argument,       NULL, 'b'},
@@ -92,6 +93,7 @@ const struct option cf_options[] = {
        {"blacklist",       required_argument, NULL, 'X'},
        {"denyinterfaces",  required_argument, NULL, 'Z'},
        {"arping",          required_argument, NULL, O_ARPING},
+       {"fallback",        required_argument, NULL, O_FALLBACK},
        {NULL,              0,                 NULL, '\0'}
 };
 
@@ -673,6 +675,10 @@ parse_option(struct if_options *ifo, int opt, const char *arg)
                    sizeof(in_addr_t) * (ifo->arping_len + 1));
                ifo->arping[ifo->arping_len++] = addr.s_addr;
                break;
+       case O_FALLBACK:
+               free(ifo->fallback);
+               ifo->fallback = xstrdup(arg);
+               break;
        default:
                return 0;
        }
@@ -831,7 +837,9 @@ free_options(struct if_options *ifo)
                        free(ifo->config);
                }
                free_routes(ifo->routes);
+               free(ifo->arping);
                free(ifo->blacklist);
+               free(ifo->fallback);
                free(ifo);
        }
 }
index c6fcf882ba7c1fbe279eab2201ef5edb04580d79..8fa122ab43db100d8c0869f6982871b0500deb89 100644 (file)
@@ -102,6 +102,7 @@ struct if_options {
        in_addr_t *blacklist;
        size_t arping_len;
        in_addr_t *arping;
+       char *fallback;
 };
 
 struct if_options *read_config(const char *,