summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2009-04-18 21:43:23 +0000
committerRoy Marples <roy@marples.name>2009-04-18 21:43:23 +0000
commitff021b0b5dc1b9060b45e0451d02f1bf58cc75fc (patch)
tree31b5d125a355b438139fd26364582a9508cdc61a
parent623330decced8f8eeb1868a57ae687d40c39dad1 (diff)
downloaddhcpcd-ff021b0b5dc1b9060b45e0451d02f1bf58cc75fc.tar.xz
Add an option to fallback to a profile when DHCP fails.
-rw-r--r--dhcpcd.c23
-rw-r--r--dhcpcd.conf.5.in9
-rw-r--r--if-options.c8
-rw-r--r--if-options.h1
4 files changed, 35 insertions, 6 deletions
diff --git a/dhcpcd.c b/dhcpcd.c
index b7653883..11107daf 100644
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -766,6 +766,17 @@ select_profile(struct interface *iface, const char *profile)
}
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)
{
select_profile(iface, NULL);
@@ -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)))
diff --git a/dhcpcd.conf.5.in b/dhcpcd.conf.5.in
index 51793773..ec58b866 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 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.
diff --git a/if-options.c b/if-options.c
index 8f52d931..81226978 100644
--- a/if-options.c
+++ b/if-options.c
@@ -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);
}
}
diff --git a/if-options.h b/if-options.h
index c6fcf882..8fa122ab 100644
--- a/if-options.h
+++ b/if-options.h
@@ -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 *,