}
static void
-dhcpcd_drop(struct interface *ifp, int stop)
+dhcpcd_drop_af(struct interface *ifp, int stop, int af)
{
+ if (af == AF_UNSPEC || af == AF_INET6) {
#ifdef DHCP6
- dhcp6_drop(ifp, stop ? NULL : "EXPIRE6");
+ dhcp6_drop(ifp, stop ? NULL : "EXPIRE6");
#endif
#ifdef INET6
- ipv6nd_drop(ifp);
- ipv6_drop(ifp);
+ ipv6nd_drop(ifp);
+ ipv6_drop(ifp);
#endif
+ }
+
+ if (af == AF_UNSPEC || af == AF_INET) {
#ifdef IPV4LL
- ipv4ll_drop(ifp);
+ ipv4ll_drop(ifp);
#endif
#ifdef INET
- dhcp_drop(ifp, stop ? "STOP" : "EXPIRE");
+ dhcp_drop(ifp, stop ? "STOP" : "EXPIRE");
#endif
#ifdef ARP
- arp_drop(ifp);
+ arp_drop(ifp);
+ }
#endif
+
#if !defined(DHCP6) && !defined(DHCP)
UNUSED(stop);
#endif
}
+static void
+dhcpcd_drop(struct interface *ifp, int stop)
+{
+
+ dhcpcd_drop_af(ifp, stop, AF_UNSPEC);
+}
+
static void
stop_interface(struct interface *ifp, const char *reason)
{
int argc, char **argv)
{
struct interface *ifp;
- unsigned long long opts;
+ struct if_options *ifo;
+ unsigned long long opts, orig_opts;
int opt, oi, oifind, do_reboot, do_renew, af = AF_UNSPEC;
size_t len, l, nifaces;
char *tmp, *p;
}
if (opts & (DHCPCD_EXITING | DHCPCD_RELEASE)) {
- if (oifind == argc) {
+ if (oifind == argc && af == AF_UNSPEC) {
stop_all_interfaces(ctx, opts);
eloop_exit(ctx->eloop, EXIT_SUCCESS);
return 0;
}
- for (oi = oifind; oi < argc; oi++) {
- if ((ifp = if_find(ctx->ifaces, argv[oi])) == NULL)
- continue;
+
+ TAILQ_FOREACH(ifp, ctx->ifaces, next) {
if (!ifp->active)
continue;
- ifp->options->options |= opts;
+ for (oi = oifind; oi < argc; oi++) {
+ if (strcmp(ifp->name, argv[oi]) == 0)
+ break;
+ }
+ if (oi == argc)
+ continue;
+
+ ifo = ifp->options;
+ orig_opts = ifo->options;
+ ifo->options |= opts;
if (opts & DHCPCD_RELEASE)
- ifp->options->options &= ~DHCPCD_PERSISTENT;
- stop_interface(ifp, NULL);
+ ifo->options &= ~DHCPCD_PERSISTENT;
+ switch (af) {
+ case AF_INET:
+ ifo->options &= ~DHCPCD_IPV4;
+ break;
+ case AF_INET6:
+ ifo->options &= ~DHCPCD_IPV6;
+ break;
+ }
+ if (af != AF_UNSPEC)
+ dhcpcd_drop_af(ifp, 1, af);
+ else
+ stop_interface(ifp, NULL);
+ ifo->options = orig_opts;
}
return 0;
}
ctx.options |= DHCPCD_MANAGER;
/*
- * If we are given any interfaces, we
+ * If we are given any interfaces or a family, we
* cannot send a signal as that would impact
* other interfaces.
*/
- if (optind != argc)
+ if (optind != argc || family != AF_UNSPEC)
sig = 0;
}
if (ctx.options & DHCPCD_PRINT_PIDFILE) {