summaryrefslogtreecommitdiffstats
path: root/dhcpcd.c
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2008-09-04 14:08:14 +0000
committerRoy Marples <roy@marples.name>2008-09-04 14:08:14 +0000
commit064dd58ee2542ff28fdc0e6615c434529c6c92a0 (patch)
treef2015bcd66b57205b609565fcf683fec43245229 /dhcpcd.c
parent335b626a1731fed77776bae520a922435d94807a (diff)
downloaddhcpcd-064dd58ee2542ff28fdc0e6615c434529c6c92a0.tar.xz
Enable detection of addition and removal of interfaces on Linux.
Diffstat (limited to 'dhcpcd.c')
-rw-r--r--dhcpcd.c85
1 files changed, 58 insertions, 27 deletions
diff --git a/dhcpcd.c b/dhcpcd.c
index 306f4d02..fdfb1163 100644
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -197,7 +197,7 @@ stop_interface(struct interface *iface)
{
struct interface *ifp, *ifl = NULL;
- logger(LOG_ERR, "%s: removing interface", iface->name);
+ logger(LOG_INFO, "%s: removing interface", iface->name);
drop_config(iface, "STOP");
close_sockets(iface);
delete_timeout(NULL, iface);
@@ -593,9 +593,14 @@ open_sockets(struct interface *iface)
}
static void
-handle_carrier(struct interface *iface)
+handle_carrier(const char *ifname)
{
- if (!(iface->state->options->options & DHCPCD_LINK))
+ struct interface *iface;
+
+ for (iface = ifaces; iface; iface = iface->next)
+ if (strcmp(iface->name, ifname) == 0)
+ break;
+ if (!iface || !(iface->state->options->options & DHCPCD_LINK))
return;
switch (carrier_status(iface->name)) {
case -1:
@@ -772,39 +777,59 @@ init_state(struct interface *iface, int argc, char **argv)
}
static void
-handle_new_interface(const char *name)
+handle_new_interface(const char *ifname)
{
- struct interface *ifs, *ifp;
- const char * const argv[] = { "dhcpcd", name };
+ struct interface *ifs, *ifp, *ifn, *ifl = NULL;
+ const char * const argv[] = { "dhcpcd", ifname };
int i;
/* If running off an interface list, check it's in it. */
if (ifc) {
for (i = 0; i < ifc; i++)
- if (strcmp(ifv[i], name) == 0)
+ if (strcmp(ifv[i], ifname) == 0)
break;
if (i >= ifc)
return;
}
if ((ifs = discover_interfaces(2, UNCONST(argv)))) {
- for (ifp = ifs; ifp; ifp = ifp->next)
+ for (ifp = ifs; ifp; ifp = ifp->next) {
+ /* Check if we already have the interface */
+ for (ifn = ifaces; ifn; ifn = ifn->next) {
+ if (strcmp(ifn->name, ifp->name) == 0)
+ break;
+ ifl = ifn;
+ }
+ if (ifn)
+ continue;
init_state(ifp, 2, UNCONST(argv));
- if (ifaces) {
- ifp = ifaces;
- while (ifp->next)
- ifp = ifp->next;
- ifp->next = ifs;
- } else
- ifaces = ifs;
+ if (ifl)
+ ifl->next = ifp;
+ else
+ ifaces = ifp;
+ }
}
}
static void
+handle_remove_interface(const char *ifname)
+{
+ struct interface *iface;
+
+ for (iface = ifaces; iface; iface = iface->next)
+ if (strcmp(iface->name, ifname) == 0)
+ break;
+ if (iface && iface->state->options->options & DHCPCD_LINK)
+ stop_interface(iface);
+}
+
+static void
handle_link(_unused void *arg)
{
- if (manage_link(linkfd, ifaces, handle_carrier,
- handle_new_interface, stop_interface) == -1)
+ if (manage_link(linkfd,
+ handle_carrier,
+ handle_new_interface,
+ handle_remove_interface) == -1)
logger(LOG_ERR, "manage_link: %s", strerror(errno));
}
@@ -855,7 +880,7 @@ handle_signal(_unused void *arg)
int
handle_args(int argc, char **argv)
{
- struct interface *ifs, *ifp, *ifl = NULL;
+ struct interface *ifs, *ifp, *ifl = NULL, *ifn;
int do_exit = 0, do_release = 0, do_reboot = 0, opt, oi = 0;
optind = 0;
@@ -892,6 +917,7 @@ handle_args(int argc, char **argv)
if (do_release)
send_release(ifp);
if (do_exit || do_release) {
+ logger(LOG_INFO, "%s: removing interface", ifp->name);
drop_config(ifp, do_release ? "RELEASE" : "STOP");
close_sockets(ifp);
delete_timeout(NULL, ifp);
@@ -911,15 +937,20 @@ handle_args(int argc, char **argv)
if ((ifs = discover_interfaces(argc, argv))) {
argc += optind;
argv -= optind;
- for (ifp = ifs; ifp; ifp = ifp->next)
- init_state(ifp, argc, argv);
- if (ifaces) {
- ifp = ifaces;
- while (ifp->next)
- ifp = ifp->next;
- ifp->next = ifs;
- } else
- ifaces = ifs;
+ for (ifp = ifs; ifp; ifp = ifp->next) {
+ for (ifn = ifaces; ifn; ifn = ifn->next) {
+ if (strcmp(ifn->name, ifp->name) == 0)
+ break;
+ ifl = ifn;
+ }
+ if (!ifn) {
+ init_state(ifp, argc, argv);
+ if (ifl)
+ ifl->next = ifp;
+ else
+ ifaces = ifp;
+ }
+ }
}
return 0;
}