From: Roy Marples Date: Sun, 3 Feb 2013 22:55:45 +0000 (+0000) Subject: Move if_state into interface->if_data as dhcp_state. X-Git-Tag: v5.99.6~80 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=95fdd136aefd8926154175feb3bf6714549a50f5;p=thirdparty%2Fdhcpcd.git Move if_state into interface->if_data as dhcp_state. This should reduce memory usage for non IPv4 interfaces. --- diff --git a/arp.c b/arp.c index 190a5183..9bf1a597 100644 --- a/arp.c +++ b/arp.c @@ -79,24 +79,25 @@ arp_send(const struct interface *ifp, int op, in_addr_t sip, in_addr_t tip) static void arp_failure(struct interface *ifp) { + const struct dhcp_state *state = D_CSTATE(ifp); /* If we failed without a magic cookie then we need to try * and defend our IPv4LL address. */ - if ((ifp->state->offer != NULL && - ifp->state->offer->cookie != htonl(MAGIC_COOKIE)) || - (ifp->state->new != NULL && - ifp->state->new->cookie != htonl(MAGIC_COOKIE))) + if ((state->offer != NULL && + state->offer->cookie != htonl(MAGIC_COOKIE)) || + (state->new != NULL && + state->new->cookie != htonl(MAGIC_COOKIE))) { ipv4ll_handle_failure(ifp); return; } - unlink(ifp->state->leasefile); - if (!ifp->state->lease.frominfo) + unlink(state->leasefile); + if (!state->lease.frominfo) dhcp_decline(ifp); dhcp_close(ifp); eloop_timeout_delete(NULL, ifp); - if (ifp->state->lease.frominfo) + if (state->lease.frominfo) start_interface(ifp); else eloop_timeout_add_sec(DHCP_ARP_FAIL, start_interface, ifp); @@ -112,11 +113,12 @@ arp_packet(void *arg) uint32_t reply_t; uint8_t *hw_s, *hw_t; ssize_t bytes; - struct if_state *state = ifp->state; + struct dhcp_state *state; struct if_options *opts = ifp->options; const char *hwaddr; struct in_addr ina; + state = D_STATE(ifp); state->fail.s_addr = 0; for(;;) { bytes = get_raw_packet(ifp, ETHERTYPE_ARP, @@ -202,7 +204,7 @@ void arp_announce(void *arg) { struct interface *ifp = arg; - struct if_state *state = ifp->state; + struct dhcp_state *state = D_STATE(ifp); struct timeval tv; if (state->new == NULL) @@ -249,7 +251,7 @@ void arp_probe(void *arg) { struct interface *ifp = arg; - struct if_state *state = ifp->state; + struct dhcp_state *state = D_STATE(ifp); struct in_addr addr; struct timeval tv; int arping = 0; @@ -305,8 +307,9 @@ arp_probe(void *arg) void arp_start(struct interface *ifp) { + struct dhcp_state *state = D_STATE(ifp); - ifp->state->probes = 0; - ifp->state->arping_index = 0; + state->probes = 0; + state->arping_index = 0; arp_probe(ifp); } diff --git a/dhcp.c b/dhcp.c index 3e87c57b..f217073d 100644 --- a/dhcp.c +++ b/dhcp.c @@ -46,7 +46,9 @@ #include "config.h" #include "common.h" #include "dhcp.h" +#include "dhcpcd.h" #include "dhcp-common.h" +#include "duid.h" #include "eloop.h" #include "ipv4.h" #include "ipv4ll.h" @@ -261,6 +263,7 @@ static void free_option_buffer(void) { + free(packet); free(opt_buffer); } #endif @@ -825,9 +828,9 @@ make_message(struct dhcp_message **message, const char *hp; const struct dhcp_opt *opt; const struct if_options *ifo = iface->options; - const struct if_state *ifs = iface->state; - const struct dhcp_lease *lease = &ifs->lease; - time_t up = uptime() - ifs->start_uptime; + const struct dhcp_state *state = D_CSTATE(iface); + const struct dhcp_lease *lease = &state->lease; + time_t up = uptime() - state->start_uptime; dhcp = xzalloc(sizeof (*dhcp)); m = (uint8_t *)dhcp; @@ -835,13 +838,13 @@ make_message(struct dhcp_message **message, if ((type == DHCP_INFORM || type == DHCP_RELEASE || (type == DHCP_REQUEST && - ifs->net.s_addr == lease->net.s_addr && - (ifs->new == NULL || - ifs->new->cookie == htonl(MAGIC_COOKIE))))) + state->net.s_addr == lease->net.s_addr && + (state->new == NULL || + state->new->cookie == htonl(MAGIC_COOKIE))))) { - dhcp->ciaddr = ifs->addr.s_addr; + dhcp->ciaddr = state->addr.s_addr; /* In-case we haven't actually configured the address yet */ - if (type == DHCP_INFORM && ifs->addr.s_addr == 0) + if (type == DHCP_INFORM && state->addr.s_addr == 0) dhcp->ciaddr = lease->addr.s_addr; } @@ -867,23 +870,23 @@ make_message(struct dhcp_message **message, else dhcp->secs = htons(up); } - dhcp->xid = htonl(ifs->xid); + dhcp->xid = htonl(state->xid); dhcp->cookie = htonl(MAGIC_COOKIE); *p++ = DHO_MESSAGETYPE; *p++ = 1; *p++ = type; - if (ifs->clientid) { + if (state->clientid) { *p++ = DHO_CLIENTID; - memcpy(p, ifs->clientid, ifs->clientid[0] + 1); - p += ifs->clientid[0] + 1; + memcpy(p, state->clientid, state->clientid[0] + 1); + p += state->clientid[0] + 1; } if (lease->addr.s_addr && lease->cookie == htonl(MAGIC_COOKIE)) { if (type == DHCP_DECLINE || (type == DHCP_REQUEST && - lease->addr.s_addr != ifs->addr.s_addr)) + lease->addr.s_addr != state->addr.s_addr)) { PUTADDR(DHO_IPADDRESS, lease->addr); if (lease->server.s_addr) @@ -1026,7 +1029,7 @@ make_message(struct dhcp_message **message, } ssize_t -write_lease(const struct interface *iface, const struct dhcp_message *dhcp) +write_lease(const struct interface *ifp, const struct dhcp_message *dhcp) { int fd; ssize_t bytes = sizeof(*dhcp); @@ -1034,17 +1037,18 @@ write_lease(const struct interface *iface, const struct dhcp_message *dhcp) const uint8_t *e = p + sizeof(dhcp->options); uint8_t l; uint8_t o = 0; + const struct dhcp_state *state = D_CSTATE(ifp); /* We don't write BOOTP leases */ if (is_bootp(dhcp)) { - unlink(iface->state->leasefile); + unlink(state->leasefile); return 0; } syslog(LOG_DEBUG, "%s: writing lease `%s'", - iface->name, iface->state->leasefile); + ifp->name, state->leasefile); - fd = open(iface->state->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0444); + fd = open(state->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0444); if (fd == -1) return -1; @@ -1067,21 +1071,22 @@ write_lease(const struct interface *iface, const struct dhcp_message *dhcp) } struct dhcp_message * -read_lease(const struct interface *iface) +read_lease(const struct interface *ifp) { int fd; struct dhcp_message *dhcp; + const struct dhcp_state *state = D_CSTATE(ifp); ssize_t bytes; - fd = open(iface->state->leasefile, O_RDONLY); + fd = open(state->leasefile, O_RDONLY); if (fd == -1) { if (errno != ENOENT) syslog(LOG_ERR, "%s: open `%s': %m", - iface->name, iface->state->leasefile); + ifp->name, state->leasefile); return NULL; } syslog(LOG_DEBUG, "%s: reading lease `%s'", - iface->name, iface->state->leasefile); + ifp->name, state->leasefile); dhcp = xmalloc(sizeof(*dhcp)); memset(dhcp, 0, sizeof(*dhcp)); bytes = read(fd, dhcp, sizeof(*dhcp)); @@ -1253,30 +1258,35 @@ dhcp_xid(const struct interface *ifp) void dhcp_close(struct interface *ifp) { - struct if_state *ifs = ifp->state; + struct dhcp_state *state = D_STATE(ifp); + + if (state == NULL) + return; - if (ifs->arp_fd != -1) { - eloop_event_delete(ifs->arp_fd); - close(ifs->arp_fd); - ifs->arp_fd = -1; + if (state->arp_fd != -1) { + eloop_event_delete(state->arp_fd); + close(state->arp_fd); + state->arp_fd = -1; } - if (ifs->raw_fd != -1) { - eloop_event_delete(ifs->raw_fd); - close(ifs->raw_fd); - ifs->raw_fd = -1; + if (state->raw_fd != -1) { + eloop_event_delete(state->raw_fd); + close(state->raw_fd); + state->raw_fd = -1; } - if (ifs->udp_fd != -1) { + if (state->udp_fd != -1) { /* we don't listen to events on the udp */ - close(ifs->udp_fd); - ifs->udp_fd = -1; + close(state->udp_fd); + state->udp_fd = -1; } + + state->interval = 0; } static void send_message(struct interface *iface, int type, void (*callback)(void *)) { - struct if_state *state = iface->state; + struct dhcp_state *state = D_STATE(iface); struct if_options *ifo = iface->options; struct dhcp_message *dhcp; uint8_t *udp; @@ -1401,29 +1411,28 @@ void dhcp_discover(void *arg) { struct interface *iface = arg; + struct dhcp_state *state = D_STATE(iface); struct if_options *ifo = iface->options; int timeout = ifo->timeout; /* If we're rebooting and we're not daemonised then we need * to shorten the normal timeout to ensure we try correctly * for a fallback or IPv4LL address. */ - if (iface->state->state == DHS_REBOOT && - !(options & DHCPCD_DAEMONISED)) - { + if (state->state == DHS_REBOOT && !(options & DHCPCD_DAEMONISED)) { timeout -= ifo->reboot; if (timeout <= 0) timeout = 2; } - iface->state->state = DHS_DISCOVER; - iface->state->xid = dhcp_xid(iface); + state->state = DHS_DISCOVER; + state->xid = dhcp_xid(iface); eloop_timeout_delete(NULL, iface); if (ifo->fallback) eloop_timeout_add_sec(timeout, dhcp_fallback, iface); else if (ifo->options & DHCPCD_IPV4LL && - !IN_LINKLOCAL(htonl(iface->state->addr.s_addr))) + !IN_LINKLOCAL(htonl(state->addr.s_addr))) { - if (IN_LINKLOCAL(htonl(iface->state->fail.s_addr))) + if (IN_LINKLOCAL(htonl(state->fail.s_addr))) eloop_timeout_add_sec(RATE_LIMIT_INTERVAL, ipv4ll_start, iface); else @@ -1440,52 +1449,53 @@ dhcp_discover(void *arg) static void dhcp_request(void *arg) { - struct interface *iface = arg; + struct interface *ifp = arg; + struct dhcp_state *state = D_STATE(ifp); - iface->state->state = DHS_REQUEST; - send_request(iface); + state->state = DHS_REQUEST; + send_request(ifp); } static void dhcp_expire(void *arg) { - struct interface *iface = arg; + struct interface *ifp = arg; + struct dhcp_state *state = D_STATE(ifp); - iface->state->interval = 0; - if (iface->state->addr.s_addr == 0) { + state->interval = 0; + if (state->addr.s_addr == 0) { /* We failed to reboot, so enter discovery. */ - iface->state->lease.addr.s_addr = 0; - dhcp_discover(iface); + state->lease.addr.s_addr = 0; + dhcp_discover(ifp); return; } - syslog(LOG_ERR, "%s: lease expired", iface->name); - eloop_timeout_delete(NULL, iface); - dhcp_drop(iface, "EXPIRE"); - unlink(iface->state->leasefile); - if (iface->carrier != LINK_DOWN) - start_interface(iface); + syslog(LOG_ERR, "%s: lease expired", ifp->name); + eloop_timeout_delete(NULL, ifp); + dhcp_drop(ifp, "EXPIRE"); + unlink(state->leasefile); + if (ifp->carrier != LINK_DOWN) + start_interface(ifp); } void -dhcp_release(struct interface *iface) +dhcp_release(struct interface *ifp) { + struct dhcp_state *state = D_STATE(ifp); struct timespec ts; - if (iface->state->new != NULL && - iface->state->new->cookie == htonl(MAGIC_COOKIE)) - { + if (state->new != NULL && state->new->cookie == htonl(MAGIC_COOKIE)) { syslog(LOG_INFO, "%s: releasing lease of %s", - iface->name, inet_ntoa(iface->state->lease.addr)); - iface->state->xid = dhcp_xid(iface); - send_message(iface, DHCP_RELEASE, NULL); + ifp->name, inet_ntoa(state->lease.addr)); + state->xid = dhcp_xid(ifp); + send_message(ifp, DHCP_RELEASE, NULL); /* Give the packet a chance to go before dropping the ip */ ts.tv_sec = RELEASE_DELAY_S; ts.tv_nsec = RELEASE_DELAY_NS; nanosleep(&ts, NULL); - dhcp_drop(iface, "RELEASE"); + dhcp_drop(ifp, "RELEASE"); } - unlink(iface->state->leasefile); + unlink(state->leasefile); } void @@ -1498,40 +1508,42 @@ dhcp_decline(struct interface *ifp) static void dhcp_renew(void *arg) { - struct interface *iface = arg; - struct dhcp_lease *lease = &iface->state->lease; + struct interface *ifp = arg; + struct dhcp_state *state = D_STATE(ifp); + struct dhcp_lease *lease = &state->lease; syslog(LOG_INFO, "%s: renewing lease of %s", - iface->name, inet_ntoa(lease->addr)); + ifp->name, inet_ntoa(lease->addr)); syslog(LOG_DEBUG, "%s: rebind in %u seconds, expire in %u seconds", - iface->name, lease->rebindtime - lease->renewaltime, + ifp->name, lease->rebindtime - lease->renewaltime, lease->leasetime - lease->renewaltime); - iface->state->state = DHS_RENEW; - iface->state->xid = dhcp_xid(iface); - send_renew(iface); + state->state = DHS_RENEW; + state->xid = dhcp_xid(ifp); + send_renew(ifp); } static void dhcp_rebind(void *arg) { - struct interface *iface = arg; - struct dhcp_lease *lease = &iface->state->lease; + struct interface *ifp = arg; + struct dhcp_state *state = D_STATE(ifp); + struct dhcp_lease *lease = &state->lease; syslog(LOG_ERR, "%s: failed to renew, attempting to rebind", - iface->name); + ifp->name); syslog(LOG_DEBUG, "%s: expire in %u seconds", - iface->name, lease->leasetime - lease->rebindtime); - iface->state->state = DHS_REBIND; - eloop_timeout_delete(send_renew, iface); - iface->state->lease.server.s_addr = 0; - send_rebind(iface); + ifp->name, lease->leasetime - lease->rebindtime); + state->state = DHS_REBIND; + eloop_timeout_delete(send_renew, ifp); + state->lease.server.s_addr = 0; + send_rebind(ifp); } void dhcp_bind(void *arg) { struct interface *iface = arg; - struct if_state *state = iface->state; + struct dhcp_state *state = D_STATE(iface); struct if_options *ifo = iface->options; struct dhcp_lease *lease = &state->lease; struct timeval tv; @@ -1610,7 +1622,7 @@ dhcp_bind(void *arg) } if (options & DHCPCD_TEST) { state->reason = "TEST"; - script_run(iface); + script_runreason(iface, state->reason); exit(EXIT_SUCCESS); } if (state->reason == NULL) { @@ -1649,11 +1661,12 @@ dhcp_bind(void *arg) static void dhcp_timeout(void *arg) { - struct interface *iface = arg; + struct interface *ifp = arg; + struct dhcp_state *state = D_STATE(ifp); - dhcp_bind(iface); - iface->state->interval = 0; - dhcp_discover(iface); + dhcp_bind(ifp); + state->interval = 0; + dhcp_discover(ifp); } struct dhcp_message * @@ -1676,125 +1689,146 @@ dhcp_message_new(struct in_addr *addr, struct in_addr *mask) } static int -handle_3rdparty(struct interface *iface) +handle_3rdparty(struct interface *ifp) { struct if_options *ifo; + struct dhcp_state *state; struct in_addr addr, net, dst; - ifo = iface->options; + ifo = ifp->options; if (ifo->req_addr.s_addr != INADDR_ANY) return 0; - if (get_address(iface->name, &addr, &net, &dst) == 1) - ipv4_handleifa(RTM_NEWADDR, iface->name, &addr, &net, &dst); + if (get_address(ifp->name, &addr, &net, &dst) == 1) + ipv4_handleifa(RTM_NEWADDR, ifp->name, &addr, &net, &dst); else { syslog(LOG_INFO, "%s: waiting for 3rd party to configure IP address", - iface->name); - iface->state->reason = "3RDPARTY"; - script_run(iface); + ifp->name); + state = D_STATE(ifp); + state->reason = "3RDPARTY"; + script_runreason(ifp, state->reason); } return 1; } static void -dhcp_static(struct interface *iface) +dhcp_static(struct interface *ifp) { struct if_options *ifo; + struct dhcp_state *state; - if (handle_3rdparty(iface)) + if (handle_3rdparty(ifp)) return; - ifo = iface->options; - iface->state->offer = - dhcp_message_new(&ifo->req_addr, &ifo->req_mask); - eloop_timeout_delete(NULL, iface); - dhcp_bind(iface); + ifo = ifp->options; + state = D_STATE(ifp); + state->offer = dhcp_message_new(&ifo->req_addr, &ifo->req_mask); + eloop_timeout_delete(NULL, ifp); + dhcp_bind(ifp); } void -dhcp_inform(struct interface *iface) +dhcp_inform(struct interface *ifp) { + struct dhcp_state *state; - if (handle_3rdparty(iface)) + if (handle_3rdparty(ifp)) return; + state = D_STATE(ifp); if (options & DHCPCD_TEST) { - iface->state->addr.s_addr = iface->options->req_addr.s_addr; - iface->state->net.s_addr = iface->options->req_mask.s_addr; + state->addr.s_addr = ifp->options->req_addr.s_addr; + state->net.s_addr = ifp->options->req_mask.s_addr; } else { - iface->options->options |= DHCPCD_STATIC; - dhcp_static(iface); + ifp->options->options |= DHCPCD_STATIC; + dhcp_static(ifp); } - iface->state->state = DHS_INFORM; - iface->state->xid = dhcp_xid(iface); - send_inform(iface); + state->state = DHS_INFORM; + state->xid = dhcp_xid(ifp); + send_inform(ifp); } -static void -dhcp_reboot(struct interface *iface) +void +dhcp_reboot(struct interface *ifp, int oldopts) { - struct if_options *ifo = iface->options; + struct if_options *ifo = ifp->options; + struct dhcp_state *state = D_STATE(ifp); + + ifo = ifp->options; + state->interval = 0; + if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) && + state->addr.s_addr != ifo->req_addr.s_addr) || + (oldopts & (DHCPCD_INFORM | DHCPCD_STATIC) && + !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)))) + { + dhcp_drop(ifp, "EXPIRE"); + } else { + free(state->offer); + state->offer = NULL; + } - if (ifo->options & DHCPCD_LINK && iface->carrier == LINK_DOWN) { - syslog(LOG_INFO, "%s: waiting for carrier", iface->name); + if (ifo->options & DHCPCD_LINK && ifp->carrier == LINK_DOWN) { + syslog(LOG_INFO, "%s: waiting for carrier", ifp->name); return; } if (ifo->options & DHCPCD_STATIC) { - dhcp_static(iface); + dhcp_static(ifp); return; } - if (ifo->reboot == 0 || iface->state->offer == NULL) { - dhcp_discover(iface); + if (ifo->reboot == 0 || state->offer == NULL) { + dhcp_discover(ifp); return; } if (ifo->options & DHCPCD_INFORM) { syslog(LOG_INFO, "%s: informing address of %s", - iface->name, inet_ntoa(iface->state->lease.addr)); - } else if (iface->state->offer->cookie == 0) { + ifp->name, inet_ntoa(state->lease.addr)); + } else if (state->offer->cookie == 0) { if (ifo->options & DHCPCD_IPV4LL) { - iface->state->claims = 0; - arp_announce(iface); + state->claims = 0; + arp_announce(ifp); } else - dhcp_discover(iface); + dhcp_discover(ifp); return; } else { syslog(LOG_INFO, "%s: rebinding lease of %s", - iface->name, inet_ntoa(iface->state->lease.addr)); + ifp->name, inet_ntoa(state->lease.addr)); } - iface->state->state = DHS_REBOOT; - iface->state->xid = dhcp_xid(iface); - iface->state->lease.server.s_addr = 0; - eloop_timeout_delete(NULL, iface); + state->state = DHS_REBOOT; + state->xid = dhcp_xid(ifp); + state->lease.server.s_addr = 0; + eloop_timeout_delete(NULL, ifp); if (ifo->fallback) - eloop_timeout_add_sec(ifo->reboot, dhcp_fallback, iface); - else if (ifo->options & DHCPCD_LASTLEASE && - iface->state->lease.frominfo) - eloop_timeout_add_sec(ifo->reboot, dhcp_timeout, iface); + eloop_timeout_add_sec(ifo->reboot, dhcp_fallback, ifp); + else if (ifo->options & DHCPCD_LASTLEASE && state->lease.frominfo) + eloop_timeout_add_sec(ifo->reboot, dhcp_timeout, ifp); else if (!(ifo->options & DHCPCD_INFORM && options & (DHCPCD_MASTER | DHCPCD_DAEMONISED))) - eloop_timeout_add_sec(ifo->reboot, dhcp_expire, iface); + eloop_timeout_add_sec(ifo->reboot, dhcp_expire, ifp); /* Don't bother ARP checking as the server could NAK us first. */ if (ifo->options & DHCPCD_INFORM) - dhcp_inform(iface); + dhcp_inform(ifp); else - dhcp_request(iface); + dhcp_request(ifp); } void dhcp_drop(struct interface *iface, const char *reason) { + struct dhcp_state *state = D_STATE(iface); + if (state == NULL) + return; eloop_timeouts_delete(iface, dhcp_expire, NULL); - free(iface->state->old); - iface->state->old = iface->state->new; - iface->state->new = NULL; - iface->state->reason = reason; + free(state->old); + state->old = state->new; + state->new = NULL; + state->reason = reason; ipv4_applyaddr(iface); - free(iface->state->old); - iface->state->old = NULL; - iface->state->lease.addr.s_addr = 0; + free(state->old); + state->old = NULL; + state->lease.addr.s_addr = 0; } static void @@ -1863,7 +1897,7 @@ static void dhcp_handle(struct interface *iface, struct dhcp_message **dhcpp, const struct in_addr *from) { - struct if_state *state = iface->state; + struct dhcp_state *state = D_STATE(iface); struct if_options *ifo = iface->options; struct dhcp_message *dhcp = *dhcpp; struct dhcp_lease *lease = &state->lease; @@ -1890,7 +1924,7 @@ dhcp_handle(struct interface *iface, struct dhcp_message **dhcpp, log_dhcp(LOG_WARNING, "NAK:", iface, dhcp, from); if (!(options & DHCPCD_TEST)) { dhcp_drop(iface, "NAK"); - unlink(iface->state->leasefile); + unlink(state->leasefile); } dhcp_close(iface); /* If we constantly get NAKS then we should slowly back off */ @@ -1951,7 +1985,7 @@ dhcp_handle(struct interface *iface, struct dhcp_message **dhcpp, state->new = state->offer; state->offer = NULL; state->reason = "TEST"; - script_run(iface); + script_runreason(iface, state->reason); exit(EXIT_SUCCESS); } eloop_timeout_delete(send_discover, iface); @@ -2030,6 +2064,7 @@ dhcp_handlepacket(void *arg) ssize_t bytes; struct in_addr from; int i, partialcsum = 0; + const struct dhcp_state *state = D_CSTATE(iface); /* We loop through until our buffer is empty. * The benefit is that if we get >1 DHCP packet in our buffer and @@ -2061,7 +2096,7 @@ dhcp_handlepacket(void *arg) continue; } if (iface->flags & IFF_POINTOPOINT && - iface->state->dst.s_addr != from.s_addr) + state->dst.s_addr != from.s_addr) { syslog(LOG_WARNING, "%s: server %s is not destination", @@ -2083,10 +2118,10 @@ dhcp_handlepacket(void *arg) continue; } /* Ensure it's the right transaction */ - if (iface->state->xid != ntohl(dhcp->xid)) { + if (state->xid != ntohl(dhcp->xid)) { syslog(LOG_DEBUG, "%s: wrong xid 0x%x (expecting 0x%x) from %s", - iface->name, ntohl(dhcp->xid), iface->state->xid, + iface->name, ntohl(dhcp->xid), state->xid, inet_ntoa(from)); continue; } @@ -2100,7 +2135,7 @@ dhcp_handlepacket(void *arg) continue; } dhcp_handle(iface, &dhcp, &from); - if (iface->state->raw_fd == -1) + if (state->raw_fd == -1) break; } free(packet); @@ -2112,19 +2147,19 @@ static int dhcp_open(struct interface *ifp) { int r = 0; - struct if_state *ifs; + struct dhcp_state *state; - ifs = ifp->state; - if (ifs->raw_fd == -1) { + state = D_STATE(ifp); + if (state->raw_fd == -1) { if ((r = open_socket(ifp, ETHERTYPE_IP)) == -1) syslog(LOG_ERR, "%s: %s: %m", __func__, ifp->name); else - eloop_event_add(ifs->raw_fd, dhcp_handlepacket, ifp); + eloop_event_add(state->raw_fd, dhcp_handlepacket, ifp); } - if (ifs->udp_fd == -1 && - ifs->addr.s_addr != 0 && - ifs->new != NULL && - (ifs->new->cookie == htonl(MAGIC_COOKIE) || + if (state->udp_fd == -1 && + state->addr.s_addr != 0 && + state->new != NULL && + (state->new->cookie == htonl(MAGIC_COOKIE) || ifp->options->options & DHCPCD_INFORM)) { if (open_udp_socket(ifp) == -1 && errno != EADDRINUSE) { @@ -2135,10 +2170,134 @@ dhcp_open(struct interface *ifp) return r; } +int +dhcp_dump(const char *ifname) +{ + struct interface *ifp; + struct dhcp_state *state; + + ifaces = ifp = xzalloc(sizeof(*ifp)); + ifp->if_data[IF_DATA_DHCP] = state = xzalloc(sizeof(*state)); + ifp->options = xzalloc(sizeof(*ifp->options)); + strlcpy(ifp->name, ifname, sizeof(ifp->name)); + snprintf(state->leasefile, sizeof(state->leasefile), + LEASEFILE, ifp->name); + strlcpy(ifp->options->script, if_options->script, + sizeof(ifp->options->script)); + state->new = read_lease(ifp); + if (state->new == NULL && errno == ENOENT) { + strlcpy(state->leasefile, ifname, sizeof(state->leasefile)); + state->new = read_lease(ifp); + } + if (state->new == NULL) { + if (errno == ENOENT) + syslog(LOG_ERR, "%s: no lease to dump", ifname); + return -1; + } + state->reason = "DUMP"; + return script_runreason(ifp, state->reason); +} + +void +dhcp_free(struct interface *ifp) +{ + struct dhcp_state *state = D_STATE(ifp); + + if (state) { + free(state->old); + free(state->new); + free(state->offer); + free(state->buffer); + free(state->clientid); + free(state); + ifp->if_data[IF_DATA_DHCP] = NULL; + } +} + +static int +dhcp_init(struct interface *ifp) +{ + struct dhcp_state *state; + const struct if_options *ifo; + unsigned char *duid; + size_t len, ifl; + + state = D_STATE(ifp); + if (state == NULL) { + ifp->if_data[IF_DATA_DHCP] = calloc(1, sizeof(*state)); + state = D_STATE(ifp); + } + if (state == NULL) + return -1; + + state->state = DHS_INIT; + state->reason = "PREINIT"; + state->nakoff = 0; + snprintf(state->leasefile, sizeof(state->leasefile), + LEASEFILE, ifp->name); + /* 0 is a valid fd, so init to -1 */ + state->raw_fd = state->udp_fd = state->arp_fd = -1; + + ifo = ifp->options; + /* We need to drop the leasefile so that start_interface + * doesn't load it. */ + if (ifo->options & DHCPCD_REQUEST) + unlink(state->leasefile); + + free(state->clientid); + state->clientid = NULL; + + if (*ifo->clientid) { + state->clientid = xmalloc(ifo->clientid[0] + 1); + memcpy(state->clientid, ifo->clientid, ifo->clientid[0] + 1); + } else if (ifo->options & DHCPCD_CLIENTID) { + len = 0; + if (ifo->options & DHCPCD_DUID) { + duid = xmalloc(DUID_LEN); + if ((len = get_duid(duid, ifp)) == 0) + syslog(LOG_ERR, "get_duid: %m"); + } else + duid = NULL; + if (len > 0) { + state->clientid = xmalloc(len + 6); + state->clientid[0] = len + 5; + state->clientid[1] = 255; /* RFC 4361 */ + ifl = strlen(ifp->name); + if (ifl < 5) { + memcpy(state->clientid + 2, ifp->name, ifl); + if (ifl < 4) + memset(state->clientid + 2 + ifl, + 0, 4 - ifl); + } else { + ifl = htonl(ifp->index); + memcpy(state->clientid + 2, &ifl, 4); + } + memcpy(state->clientid + 6, duid, len); + } else if (len == 0) { + len = ifp->hwlen + 1; + state->clientid = xmalloc(len + 1); + state->clientid[0] = len; + state->clientid[1] = ifp->family; + memcpy(state->clientid + 2, ifp->hwaddr, + ifp->hwlen); + } + free(duid); + } + if (ifo->options & DHCPCD_CLIENTID) + syslog(LOG_DEBUG, "%s: using ClientID %s", ifp->name, + hwaddr_ntoa(state->clientid + 1, state->clientid[0])); + else if (ifp->hwlen) + syslog(LOG_DEBUG, "%s: using hwaddr %s", ifp->name, + hwaddr_ntoa(ifp->hwaddr, ifp->hwlen)); + + return 0; +} + void dhcp_start(struct interface *ifp) { struct if_options *ifo = ifp->options; + struct dhcp_state *state; struct stat st; struct timeval now; uint32_t l; @@ -2147,6 +2306,21 @@ dhcp_start(struct interface *ifp) if (!(ifo->options & DHCPCD_IPV4)) return; + if (dhcp_init(ifp) == -1) { + syslog(LOG_ERR, "%s: dhcp_init: %m", ifp->name); + return; + } + + state = D_STATE(ifp); + state->start_uptime = uptime(); + free(state->offer); + state->offer = NULL; + + if (state->arping_index < ifo->arping_len) { + arp_start(ifp); + return; + } + if (ifo->options & DHCPCD_STATIC) { dhcp_static(ifp); return; @@ -2168,47 +2342,45 @@ dhcp_start(struct interface *ifp) return; } /* We don't want to read the old lease if we NAK an old test */ - nolease = ifp->state->offer && options & DHCPCD_TEST; + nolease = state->offer && options & DHCPCD_TEST; if (!nolease) - ifp->state->offer = read_lease(ifp); - if (ifp->state->offer) { - get_lease(&ifp->state->lease, ifp->state->offer); - ifp->state->lease.frominfo = 1; - if (ifp->state->offer->cookie == 0) { - if (ifp->state->offer->yiaddr == - ifp->state->addr.s_addr) - { - free(ifp->state->offer); - ifp->state->offer = NULL; + state->offer = read_lease(ifp); + if (state->offer) { + get_lease(&state->lease, state->offer); + state->lease.frominfo = 1; + if (state->offer->cookie == 0) { + if (state->offer->yiaddr == state->addr.s_addr) { + free(state->offer); + state->offer = NULL; } - } else if (ifp->state->lease.leasetime != ~0U && - stat(ifp->state->leasefile, &st) == 0) + } else if (state->lease.leasetime != ~0U && + stat(state->leasefile, &st) == 0) { /* Offset lease times and check expiry */ gettimeofday(&now, NULL); - if ((time_t)ifp->state->lease.leasetime < + if ((time_t)state->lease.leasetime < now.tv_sec - st.st_mtime) { syslog(LOG_DEBUG, "%s: discarding expired lease", ifp->name); - free(ifp->state->offer); - ifp->state->offer = NULL; - ifp->state->lease.addr.s_addr = 0; + free(state->offer); + state->offer = NULL; + state->lease.addr.s_addr = 0; } else { l = now.tv_sec - st.st_mtime; - ifp->state->lease.leasetime -= l; - ifp->state->lease.renewaltime -= l; - ifp->state->lease.rebindtime -= l; + state->lease.leasetime -= l; + state->lease.renewaltime -= l; + state->lease.rebindtime -= l; } } } - if (ifp->state->offer == NULL) + if (state->offer == NULL) dhcp_discover(ifp); - else if (ifp->state->offer->cookie == 0 && + else if (state->offer->cookie == 0 && ifp->options->options & DHCPCD_IPV4LL) ipv4ll_start(ifp); else - dhcp_reboot(ifp); + dhcp_reboot(ifp, ifp->options->options); } diff --git a/dhcp.h b/dhcp.h index f83722bb..d5bab1cd 100644 --- a/dhcp.h +++ b/dhcp.h @@ -31,6 +31,7 @@ #include #include +#include #include #include "common.h" @@ -166,6 +167,60 @@ struct dhcp_lease { uint32_t cookie; }; +enum DHS { + DHS_INIT, + DHS_DISCOVER, + DHS_REQUEST, + DHS_BOUND, + DHS_RENEW, + DHS_REBIND, + DHS_REBOOT, + DHS_INFORM, + DHS_RENEW_REQUESTED, + DHS_INIT_IPV4LL, + DHS_PROBE +}; + +struct dhcp_state { + enum DHS state; + struct dhcp_message *sent; + struct dhcp_message *offer; + struct dhcp_message *new; + struct dhcp_message *old; + struct dhcp_lease lease; + const char *reason; + time_t interval; + time_t nakoff; + uint32_t xid; + int socket; + int probes; + int claims; + int conflicts; + time_t defend; + struct in_addr fail; + size_t arping_index; + + int raw_fd; + int udp_fd; + int arp_fd; + size_t buffer_size, buffer_len, buffer_pos; + unsigned char *buffer; + + struct in_addr addr; + struct in_addr net; + struct in_addr dst; + + char leasefile[PATH_MAX]; + time_t start_uptime; + + unsigned char *clientid; +}; + +#define D_STATE(ifp) \ + ((struct dhcp_state *)(ifp)->if_data[IF_DATA_DHCP]) +#define D_CSTATE(ifp) \ + ((const struct dhcp_state *)(ifp)->if_data[IF_DATA_DHCP]) + #include "dhcpcd.h" #include "if-options.h" #include "net.h" @@ -209,6 +264,9 @@ void dhcp_discover(void *); void dhcp_inform(struct interface *); void dhcp_release(struct interface *); void dhcp_bind(void *); +void dhcp_reboot(struct interface *, int); void dhcp_close(struct interface *); +void dhcp_free(struct interface *); +int dhcp_dump(const char *); #endif diff --git a/dhcpcd.c b/dhcpcd.c index 4f3ca3fb..9f8779e9 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -54,12 +54,10 @@ const char copyright[] = "Copyright (c) 2006-2013 Roy Marples"; #include "control.h" #include "dhcpcd.h" #include "dhcp6.h" -#include "duid.h" #include "eloop.h" #include "if-options.h" #include "if-pref.h" #include "ipv4.h" -#include "ipv4ll.h" #include "ipv6.h" #include "ipv6ns.h" #include "ipv6rs.h" @@ -68,9 +66,6 @@ const char copyright[] = "Copyright (c) 2006-2013 Roy Marples"; #include "script.h" #include "signals.h" -/* We should define a maximum for the NAK exponential backoff */ -#define NAKOFF_MAX 60 - /* Wait N nanoseconds between sending a RELEASE and dropping the address. * This gives the kernel enough time to actually send it. */ #define RELEASE_DELAY_S 0 @@ -79,6 +74,7 @@ const char copyright[] = "Copyright (c) 2006-2013 Roy Marples"; char vendor[VENDORCLASSID_MAX_LEN]; int pidfd = -1; struct interface *ifaces = NULL; +struct if_options *if_options = NULL; int ifac = 0; char **ifav = NULL; int ifdc = 0; @@ -87,7 +83,6 @@ char **ifdv = NULL; sigset_t dhcpcd_sigset; static char *cffile; -static struct if_options *if_options; static char *pidfile; static int linkfd = -1, ipv6rsfd = -1, ipv6nsfd = -1; static char **ifv; @@ -155,7 +150,6 @@ cleanup(void) for (i = 0; i < ifdc; i++) free(ifdv[i]); free(ifdv); - free(packet); #endif if (linkfd != -1) @@ -299,10 +293,7 @@ stop_interface(struct interface *iface) static void configure_interface1(struct interface *ifp) { - struct if_state *ifs = ifp->state; struct if_options *ifo = ifp->options; - uint8_t *duid; - size_t len, ifl; /* Do any platform specific configuration */ if_conf(ifp); @@ -340,54 +331,6 @@ configure_interface1(struct interface *ifp) ifo->options |= DHCPCD_CLIENTID | DHCPCD_BROADCAST; break; } - - free(ifs->clientid); - ifs->clientid = NULL; - if (!(ifo->options & DHCPCD_IPV4)) - return; - - if (*ifo->clientid) { - ifs->clientid = xmalloc(ifo->clientid[0] + 1); - memcpy(ifs->clientid, ifo->clientid, ifo->clientid[0] + 1); - } else if (ifo->options & DHCPCD_CLIENTID) { - len = 0; - if (ifo->options & DHCPCD_DUID) { - duid = xmalloc(DUID_LEN); - if ((len = get_duid(duid, ifp)) == 0) - syslog(LOG_ERR, "get_duid: %m"); - } else - duid = NULL; - if (len > 0) { - ifs->clientid = xmalloc(len + 6); - ifs->clientid[0] = len + 5; - ifs->clientid[1] = 255; /* RFC 4361 */ - ifl = strlen(ifp->name); - if (ifl < 5) { - memcpy(ifs->clientid + 2, ifp->name, ifl); - if (ifl < 4) - memset(ifs->clientid + 2 + ifl, - 0, 4 - ifl); - } else { - ifl = htonl(ifp->index); - memcpy(ifs->clientid + 2, &ifl, 4); - } - memcpy(ifs->clientid + 6, duid, len); - } else if (len == 0) { - len = ifp->hwlen + 1; - ifs->clientid = xmalloc(len + 1); - ifs->clientid[0] = len; - ifs->clientid[1] = ifp->family; - memcpy(ifs->clientid + 2, ifp->hwaddr, - ifp->hwlen); - } - free(duid); - } - if (ifo->options & DHCPCD_CLIENTID) - syslog(LOG_DEBUG, "%s: using ClientID %s", ifp->name, - hwaddr_ntoa(ifs->clientid + 1, ifs->clientid[0])); - else if (ifp->hwlen) - syslog(LOG_DEBUG, "%s: using hwaddr %s", ifp->name, - hwaddr_ntoa(ifp->hwaddr, ifp->hwlen)); } int @@ -404,12 +347,11 @@ select_profile(struct interface *ifp, const char *profile) goto exit; } if (profile != NULL) { - strlcpy(ifp->state->profile, profile, - sizeof(ifp->state->profile)); + strlcpy(ifp->profile, profile, sizeof(ifp->profile)); syslog(LOG_INFO, "%s: selected profile %s", ifp->name, profile); } else - *ifp->state->profile = '\0'; + *ifp->profile = '\0'; free_options(ifp->options); ifp->options = ifo; @@ -471,9 +413,7 @@ handle_carrier(int action, int flags, const char *ifname) if (ifp->wireless) getifssid(ifp->name, ifp->ssid); configure_interface(ifp, margc, margv); - ifp->state->interval = 0; - ifp->state->reason = "CARRIER"; - script_run(ifp); + script_runreason(ifp, "CARRIER"); start_interface(ifp); } } @@ -492,19 +432,10 @@ start_interface(void *arg) return; } - ifp->state->start_uptime = uptime(); - free(ifp->state->offer); - ifp->state->offer = NULL; - if (options & DHCPCD_IPV6RS && ifo->options & DHCPCD_IPV6RS && !(ifo->options & DHCPCD_INFORM)) ipv6rs_start(ifp); - if (ifp->state->arping_index < ifo->arping_len) { - arp_start(ifp); - return; - } - if (ifo->options & DHCPCD_IPV6) { if (ifo->options & DHCPCD_INFORM) nolease = dhcp6_start(ifp, 0); @@ -523,46 +454,28 @@ start_interface(void *arg) static void init_state(struct interface *ifp, int argc, char **argv) { - struct if_state *ifs; - - if (ifp->state) - ifs = ifp->state; - else - ifs = ifp->state = xzalloc(sizeof(*ifs)); - - ifs->state = DHS_INIT; - ifs->reason = "PREINIT"; - ifs->nakoff = 0; - snprintf(ifs->leasefile, sizeof(ifs->leasefile), - LEASEFILE, ifp->name); - /* 0 is a valid fd, so init to -1 */ - ifs->raw_fd = ifs->udp_fd = ifs->arp_fd = -1; + const char *reason = NULL; configure_interface(ifp, argc, argv); if (!(options & DHCPCD_TEST)) - script_run(ifp); - - /* We need to drop the leasefile so that start_interface - * doesn't load it. */ - if (ifp->options->options & DHCPCD_REQUEST) - unlink(ifs->leasefile); + script_runreason(ifp, "PREINIT"); if (ifp->options->options & DHCPCD_LINK) { switch (carrier_status(ifp)) { case 0: ifp->carrier = LINK_DOWN; - ifs->reason = "NOCARRIER"; + reason = "NOCARRIER"; break; case 1: ifp->carrier = LINK_UP; - ifs->reason = "CARRIER"; + reason = "CARRIER"; break; default: ifp->carrier = LINK_UNKNOWN; return; } - if (!(options & DHCPCD_TEST)) - script_run(ifp); + if (reason && !(options & DHCPCD_TEST)) + script_runreason(ifp, reason); } else ifp->carrier = LINK_UNKNOWN; } @@ -666,24 +579,11 @@ handle_link(_unused void *arg) static void if_reboot(struct interface *ifp, int argc, char **argv) { - const struct if_options *ifo; - int opt; - - ifo = ifp->options; - opt = ifo->options; + int oldopts; + + oldopts = ifp->options->options; configure_interface(ifp, argc, argv); - ifo = ifp->options; - ifp->state->interval = 0; - if ((ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC) && - ifp->state->addr.s_addr != ifo->req_addr.s_addr) || - (opt & (DHCPCD_INFORM | DHCPCD_STATIC) && - !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC)))) - { - dhcp_drop(ifp, "EXPIRE"); - } else { - free(ifp->state->offer); - ifp->state->offer = NULL; - } + dhcp_reboot(ifp, oldopts); start_interface(ifp); } @@ -706,7 +606,7 @@ reconf_reboot(int action, int argc, char **argv, int oi) if (ifn) { if (action) if_reboot(ifn, argc, argv); - else if (ifn->state->new) + else ipv4_applyaddr(ifn); free_interface(ifp); } else { @@ -768,8 +668,7 @@ handle_signal(int sig) case SIGUSR1: syslog(LOG_INFO, "received SIGUSR, reconfiguring"); for (ifp = ifaces; ifp; ifp = ifp->next) - if (ifp->state->new) - ipv4_applyaddr(ifp); + ipv4_applyaddr(ifp); return; case SIGPIPE: syslog(LOG_WARNING, "received SIGPIPE"); @@ -946,7 +845,6 @@ int main(int argc, char **argv) { struct interface *iface; - struct if_state *ifs; uint16_t family = 0; int opt, oi = 0, sig = 0, i, control_fd; size_t len; @@ -1079,28 +977,8 @@ main(int argc, char **argv) syslog(LOG_ERR, "dumplease requires an interface"); exit(EXIT_FAILURE); } - ifaces = iface = xzalloc(sizeof(*iface)); - iface->state = ifs = xzalloc(sizeof(*iface->state)); - iface->options = xzalloc(sizeof(*iface->options)); - strlcpy(iface->name, argv[optind], sizeof(iface->name)); - snprintf(ifs->leasefile, sizeof(ifs->leasefile), - LEASEFILE, iface->name); - strlcpy(iface->options->script, if_options->script, - sizeof(iface->options->script)); - iface->state->new = read_lease(iface); - if (iface->state->new == NULL && errno == ENOENT) { - strlcpy(ifs->leasefile, argv[optind], - sizeof(ifs->leasefile)); - iface->state->new = read_lease(iface); - } - if (iface->state->new == NULL) { - if (errno == ENOENT) - syslog(LOG_ERR, "%s: no lease to dump", - iface->name); + if (dhcp_dump(argv[optind]) == -1) exit(EXIT_FAILURE); - } - iface->state->reason = "DUMP"; - script_run(iface); exit(EXIT_SUCCESS); } diff --git a/dhcpcd.h b/dhcpcd.h index 41bb7351..c734360c 100644 --- a/dhcpcd.h +++ b/dhcpcd.h @@ -41,20 +41,6 @@ #define IF_SSIDSIZE 33 #define PROFILE_LEN 64 -enum DHS { - DHS_INIT, - DHS_DISCOVER, - DHS_REQUEST, - DHS_BOUND, - DHS_RENEW, - DHS_REBIND, - DHS_REBOOT, - DHS_INFORM, - DHS_RENEW_REQUESTED, - DHS_INIT_IPV4LL, - DHS_PROBE -}; - #define LINK_UP 1 #define LINK_UNKNOWN 0 #define LINK_DOWN -1 @@ -64,47 +50,8 @@ enum DHS { #define IF_DATA_DHCP6 2 #define IF_DATA_MAX 3 -struct if_state { - enum DHS state; - char profile[PROFILE_LEN]; - struct dhcp_message *sent; - struct dhcp_message *offer; - struct dhcp_message *new; - struct dhcp_message *old; - struct dhcp_lease lease; - const char *reason; - time_t interval; - time_t nakoff; - uint32_t xid; - int socket; - int probes; - int claims; - int conflicts; - time_t defend; - struct in_addr fail; - size_t arping_index; - - int raw_fd; - int udp_fd; - int arp_fd; - size_t buffer_size, buffer_len, buffer_pos; - unsigned char *buffer; - - struct in_addr addr; - struct in_addr net; - struct in_addr dst; - - char leasefile[PATH_MAX]; - time_t start_uptime; - - unsigned char *clientid; -}; - struct interface { char name[IF_NAMESIZE]; - struct if_state *state; - void *if_data[IF_DATA_MAX]; - unsigned int index; int flags; sa_family_t family; @@ -115,8 +62,9 @@ struct interface { int wireless; char ssid[IF_SSIDSIZE]; + char profile[PROFILE_LEN]; struct if_options *options; - + void *if_data[IF_DATA_MAX]; struct interface *next; }; @@ -127,6 +75,7 @@ extern int ifac; extern char **ifav; extern int ifdc; extern char **ifdv; +extern struct if_options *if_options; extern struct interface *ifaces; pid_t daemonise(void); diff --git a/if-linux.c b/if-linux.c index 41be95f1..34248d0c 100644 --- a/if-linux.c +++ b/if-linux.c @@ -542,7 +542,7 @@ if_route(const struct rt *rt, int action) { struct nlmr *nlm; int retval = 0; - struct if_state *ifs; + struct dhcp_state *state; nlm = xzalloc(sizeof(*nlm)); nlm->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); @@ -557,14 +557,15 @@ if_route(const struct rt *rt, int action) nlm->rt.rtm_family = AF_INET; nlm->rt.rtm_table = RT_TABLE_MAIN; - ifs = rt->iface->state; + state = D_STATE(rt->iface); if (action == -1 || action == -2) nlm->rt.rtm_scope = RT_SCOPE_NOWHERE; else { nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; /* We only change route metrics for kernel routes */ - if (rt->dest.s_addr == (ifs->addr.s_addr & ifs->net.s_addr) && - rt->net.s_addr == ifs->net.s_addr) + if (rt->dest.s_addr == + (state->addr.s_addr & state->net.s_addr) && + rt->net.s_addr == state->net.s_addr) nlm->rt.rtm_protocol = RTPROT_KERNEL; else nlm->rt.rtm_protocol = RTPROT_BOOT; @@ -582,7 +583,7 @@ if_route(const struct rt *rt, int action) &rt->dest.s_addr, sizeof(rt->dest.s_addr)); if (nlm->rt.rtm_protocol == RTPROT_KERNEL) { add_attr_l(&nlm->hdr, sizeof(*nlm), RTA_PREFSRC, - &ifs->addr.s_addr, sizeof(ifs->addr.s_addr)); + &state->addr.s_addr, sizeof(state->addr.s_addr)); } /* If destination == gateway then don't add the gateway */ if (rt->dest.s_addr != rt->gate.s_addr || diff --git a/if-pref.c b/if-pref.c index 6169dbe9..9e95fba5 100644 --- a/if-pref.c +++ b/if-pref.c @@ -28,32 +28,35 @@ #include #include "config.h" -#include "dhcpcd.h" +#include "dhcp.h" #include "if-pref.h" #include "net.h" /* Interface comparer for working out ordering. */ static int -ifcmp(struct interface *si, struct interface *ti) +ifcmp(const struct interface *si, const struct interface *ti) { int sill, till; + const struct dhcp_state *sis, *tis; - if (si->state && !ti->state) + sis = D_CSTATE(si); + tis = D_CSTATE(ti); + if (sis && !tis) return -1; - if (!si->state && ti->state) + if (!sis && tis) return 1; - if (!si->state && !ti->state) + if (!sis && !tis) return 0; /* If one has a lease and the other not, it takes precedence. */ - if (si->state->new && !ti->state->new) + if (sis->new && !tis->new) return -1; - if (!si->state->new && ti->state->new) + if (!sis->new && tis->new) return 1; /* If we are either, they neither have a lease, or they both have. * We need to check for IPv4LL and make it non-preferred. */ - if (si->state->new && ti->state->new) { - sill = (si->state->new->cookie == htonl(MAGIC_COOKIE)); - till = (ti->state->new->cookie == htonl(MAGIC_COOKIE)); + if (sis->new && tis->new) { + sill = (sis->new->cookie == htonl(MAGIC_COOKIE)); + till = (tis->new->cookie == htonl(MAGIC_COOKIE)); if (!sill && till) return 1; if (sill && !till) diff --git a/ipv4.c b/ipv4.c index a5475e51..e2170acf 100644 --- a/ipv4.c +++ b/ipv4.c @@ -118,7 +118,7 @@ ipv4_routedeleted(const struct rt *rt) static int n_route(struct rt *rt) { - struct if_state *s; + const struct dhcp_state *s; /* Don't set default routes if not asked to */ if (rt->dest.s_addr == 0 && @@ -130,7 +130,7 @@ n_route(struct rt *rt) if (!add_route(rt)) return 0; if (errno == EEXIST) { - s = rt->iface->state; + s = D_CSTATE(rt->iface); /* Pretend we added the subnet route */ if (rt->dest.s_addr == (s->addr.s_addr & s->net.s_addr) && rt->net.s_addr == s->net.s_addr && @@ -201,9 +201,9 @@ static struct rt * add_subnet_route(struct rt *rt, const struct interface *iface) { struct rt *r; - struct if_state *s; + const struct dhcp_state *s; - s = iface->state; + s = D_CSTATE(iface); if (s->net.s_addr == INADDR_BROADCAST || s->net.s_addr == INADDR_ANY || (iface->options->options & @@ -243,7 +243,7 @@ get_routes(struct interface *ifp) return nrt; } - return get_option_routes(ifp, ifp->state->new); + return get_option_routes(ifp, D_STATE(ifp)->new); } /* Some DHCP servers add set host routes by setting the gateway @@ -255,7 +255,7 @@ massage_host_routes(struct rt *rt, const struct interface *ifp) struct rt *r; for (r = rt; r; r = r->next) { - if (r->gate.s_addr == ifp->state->addr.s_addr && + if (r->gate.s_addr == D_CSTATE(ifp)->addr.s_addr && r->net.s_addr == INADDR_BROADCAST) r->gate.s_addr = r->dest.s_addr; } @@ -273,7 +273,7 @@ add_destination_route(struct rt *rt, const struct interface *iface) r = xmalloc(sizeof(*r)); r->dest.s_addr = INADDR_ANY; r->net.s_addr = INADDR_ANY; - r->gate.s_addr = iface->state->dst.s_addr; + r->gate.s_addr = D_CSTATE(iface)->dst.s_addr; r->next = rt; return r; } @@ -335,9 +335,11 @@ ipv4_buildroutes(void) { struct rt *nrs = NULL, *dnr, *or, *rt, *rtn, *rtl, *lrt = NULL; struct interface *ifp; + const struct dhcp_state *state; for (ifp = ifaces; ifp; ifp = ifp->next) { - if (ifp->state->new == NULL) + state = D_CSTATE(ifp); + if (state == NULL || state->new == NULL) continue; dnr = get_routes(ifp); dnr = massage_host_routes(dnr, ifp); @@ -352,11 +354,11 @@ ipv4_buildroutes(void) /* Is this route already in our table? */ if ((find_route(nrs, rt, NULL, NULL)) != NULL) continue; - rt->src.s_addr = ifp->state->addr.s_addr; + rt->src.s_addr = state->addr.s_addr; /* Do we already manage it? */ if ((or = find_route(routes, rt, &rtl, NULL))) { if (or->iface != ifp || - or->src.s_addr != ifp->state->addr.s_addr || + or->src.s_addr != state->addr.s_addr || rt->gate.s_addr != or->gate.s_addr || rt->metric != or->metric) { @@ -398,54 +400,60 @@ delete_address(struct interface *iface) { int retval; struct if_options *ifo; + struct dhcp_state *state; + state = D_STATE(iface); ifo = iface->options; if (ifo->options & DHCPCD_INFORM || (ifo->options & DHCPCD_STATIC && ifo->req_addr.s_addr == 0)) return 0; syslog(LOG_DEBUG, "%s: deleting IP address %s/%d", - iface->name, - inet_ntoa(iface->state->addr), - inet_ntocidr(iface->state->net)); - retval = del_address(iface, &iface->state->addr, &iface->state->net); + iface->name, inet_ntoa(state->addr), inet_ntocidr(state->net)); + retval = del_address(iface, &state->addr, &state->net); if (retval == -1 && errno != EADDRNOTAVAIL) syslog(LOG_ERR, "del_address: %m"); - iface->state->addr.s_addr = 0; - iface->state->net.s_addr = 0; + state->addr.s_addr = 0; + state->net.s_addr = 0; return retval; } void ipv4_applyaddr(void *arg) { - struct interface *iface = arg; - struct dhcp_message *dhcp = iface->state->new; - struct dhcp_lease *lease = &iface->state->lease; - struct if_options *ifo = iface->options; + struct interface *ifp = arg; + struct dhcp_state *state = D_STATE(ifp); + struct dhcp_message *dhcp; + struct dhcp_lease *lease; + struct if_options *ifo = ifp->options; struct rt *rt; /* As we are now adjusting an interface, we need to ensure * we have them in the right order for routing and configuration. */ sort_interfaces(); + if (state == NULL) + return; + dhcp = state->new; + lease = &state->lease; + if (dhcp == NULL) { if (!(ifo->options & DHCPCD_PERSISTENT)) { ipv4_buildroutes(); - if (iface->state->addr.s_addr != 0) - delete_address(iface); - script_run(iface); + if (state->addr.s_addr != 0) + delete_address(ifp); + script_runreason(ifp, state->reason); } return; } /* This also changes netmask */ if (!(ifo->options & DHCPCD_INFORM) || - !has_address(iface->name, &lease->addr, &lease->net)) + !has_address(ifp->name, &lease->addr, &lease->net)) { syslog(LOG_DEBUG, "%s: adding IP address %s/%d", - iface->name, inet_ntoa(lease->addr), + ifp->name, inet_ntoa(lease->addr), inet_ntocidr(lease->net)); - if (add_address(iface, + if (add_address(ifp, &lease->addr, &lease->net, &lease->brd) == -1 && errno != EEXIST) { @@ -455,18 +463,18 @@ ipv4_applyaddr(void *arg) } /* Now delete the old address if different */ - if (iface->state->addr.s_addr != lease->addr.s_addr && - iface->state->addr.s_addr != 0) - delete_address(iface); + if (state->addr.s_addr != lease->addr.s_addr && + state->addr.s_addr != 0) + delete_address(ifp); - iface->state->addr.s_addr = lease->addr.s_addr; - iface->state->net.s_addr = lease->net.s_addr; + state->addr.s_addr = lease->addr.s_addr; + state->net.s_addr = lease->net.s_addr; /* We need to delete the subnet route to have our metric or * prefer the interface. */ rt = get_subnet_route(dhcp); if (rt != NULL) { - rt->iface = iface; + rt->iface = ifp; rt->metric = 0; if (!find_route(routes, rt, NULL, NULL)) del_route(rt); @@ -474,11 +482,11 @@ ipv4_applyaddr(void *arg) } ipv4_buildroutes(); - if (!iface->state->lease.frominfo && + if (!state->lease.frominfo && !(ifo->options & (DHCPCD_INFORM | DHCPCD_STATIC))) - if (write_lease(iface, dhcp) == -1) + if (write_lease(ifp, dhcp) == -1) syslog(LOG_ERR, "%s: write_lease: %m", __func__); - script_run(iface); + script_runreason(ifp, state->reason); } void @@ -487,6 +495,7 @@ ipv4_handleifa(int type, const char *ifname, { struct interface *ifp; struct if_options *ifo; + struct dhcp_state *state; int i; if (addr->s_addr == INADDR_ANY) @@ -497,12 +506,13 @@ ipv4_handleifa(int type, const char *ifname, if (ifp == NULL) return; + state = D_STATE(ifp); if (type == RTM_DELADDR) { - if (ifp->state->new && - ifp->state->new->yiaddr == addr->s_addr) + if (state->new && + state->new->yiaddr == addr->s_addr) syslog(LOG_INFO, "%s: removing IP address %s/%d", - ifp->name, inet_ntoa(ifp->state->lease.addr), - inet_ntocidr(ifp->state->lease.net)); + ifp->name, inet_ntoa(state->lease.addr), + inet_ntocidr(state->lease.net)); return; } @@ -514,25 +524,24 @@ ipv4_handleifa(int type, const char *ifname, ifo->req_addr.s_addr != INADDR_ANY) return; - free(ifp->state->old); - ifp->state->old = ifp->state->new; - ifp->state->new = dhcp_message_new(addr, net); - ifp->state->dst.s_addr = dst ? dst->s_addr : INADDR_ANY; + free(state->old); + state->old = state->new; + state->new = dhcp_message_new(addr, net); + state->dst.s_addr = dst ? dst->s_addr : INADDR_ANY; if (dst) { for (i = 1; i < 255; i++) if (i != DHO_ROUTER && has_option_mask(ifo->dstmask,i)) - dhcp_message_add_addr(ifp->state->new, i, *dst); + dhcp_message_add_addr(state->new, i, *dst); } - ifp->state->reason = "STATIC"; + state->reason = "STATIC"; ipv4_buildroutes(); - script_run(ifp); + script_runreason(ifp, state->reason); if (ifo->options & DHCPCD_INFORM) { - ifp->state->state = DHS_INFORM; - ifp->state->xid = dhcp_xid(ifp); - ifp->state->lease.server.s_addr = - dst ? dst->s_addr : INADDR_ANY; - ifp->state->addr = *addr; - ifp->state->net = *net; + state->state = DHS_INFORM; + state->xid = dhcp_xid(ifp); + state->lease.server.s_addr = dst ? dst->s_addr : INADDR_ANY; + state->addr = *addr; + state->net = *net; dhcp_inform(ifp); } } diff --git a/ipv4ll.c b/ipv4ll.c index a1214756..970293f2 100644 --- a/ipv4ll.c +++ b/ipv4ll.c @@ -34,7 +34,7 @@ #include "arp.h" #include "common.h" -#include "dhcpcd.h" +#include "dhcp.h" #include "eloop.h" #include "if-options.h" #include "ipv4ll.h" @@ -86,24 +86,25 @@ void ipv4ll_start(void *arg) { struct interface *ifp = arg; + struct dhcp_state *state = D_STATE(ifp); uint32_t addr; eloop_timeout_delete(NULL, ifp); - ifp->state->probes = 0; - ifp->state->claims = 0; - if (ifp->state->addr.s_addr) { - ifp->state->conflicts = 0; - if (IN_LINKLOCAL(htonl(ifp->state->addr.s_addr))) { + state->probes = 0; + state->claims = 0; + if (state->addr.s_addr) { + state->conflicts = 0; + if (IN_LINKLOCAL(htonl(state->addr.s_addr))) { arp_announce(ifp); return; } } - if (ifp->state->offer == NULL) + if (state->offer == NULL) addr = 0; else { - addr = ifp->state->offer->yiaddr; - free(ifp->state->offer); + addr = state->offer->yiaddr; + free(state->offer); } /* We maybe rebooting an IPv4LL address. */ if (!IN_LINKLOCAL(htonl(addr))) { @@ -112,10 +113,10 @@ ipv4ll_start(void *arg) addr = 0; } if (addr == 0) - ifp->state->offer = ipv4ll_find_lease(addr); + state->offer = ipv4ll_find_lease(addr); else - ifp->state->offer = ipv4ll_make_lease(addr); - ifp->state->lease.frominfo = 0; + state->offer = ipv4ll_make_lease(addr); + state->lease.frominfo = 0; arp_probe(ifp); } @@ -123,32 +124,33 @@ void ipv4ll_handle_failure(void *arg) { struct interface *ifp = arg; + struct dhcp_state *state = D_STATE(ifp); time_t up; - if (ifp->state->fail.s_addr == ifp->state->addr.s_addr) { + if (state->fail.s_addr == state->addr.s_addr) { up = uptime(); - if (ifp->state->defend + DEFEND_INTERVAL > up) { + if (state->defend + DEFEND_INTERVAL > up) { syslog(LOG_DEBUG, "%s: IPv4LL %d second defence failed", ifp->name, DEFEND_INTERVAL); dhcp_drop(ifp, "EXPIRE"); - ifp->state->conflicts = -1; + state->conflicts = -1; } else { syslog(LOG_DEBUG, "%s: defended IPv4LL address", ifp->name); - ifp->state->defend = up; + state->defend = up; return; } } dhcp_close(ifp); - free(ifp->state->offer); - ifp->state->offer = NULL; + free(state->offer); + state->offer = NULL; eloop_timeout_delete(NULL, ifp); - if (++ifp->state->conflicts > MAX_CONFLICTS) { + if (++state->conflicts > MAX_CONFLICTS) { syslog(LOG_ERR, "%s: failed to acquire an IPv4LL address", ifp->name); - ifp->state->interval = RATE_LIMIT_INTERVAL / 2; + state->interval = RATE_LIMIT_INTERVAL / 2; dhcp_discover(ifp); } else { eloop_timeout_add_sec(PROBE_WAIT, ipv4ll_start, ifp); diff --git a/lpf.c b/lpf.c index e313cf37..4c98ade9 100644 --- a/lpf.c +++ b/lpf.c @@ -65,7 +65,7 @@ static const uint8_t ipv4_bcast_addr[] = { }; int -open_socket(struct interface *iface, int protocol) +open_socket(struct interface *ifp, int protocol) { int s; union sockunion { @@ -76,6 +76,7 @@ open_socket(struct interface *iface, int protocol) } su; struct sock_fprog pf; int *fd; + struct dhcp_state *state; #ifdef PACKET_AUXDATA int n; #endif @@ -86,7 +87,7 @@ open_socket(struct interface *iface, int protocol) memset(&su, 0, sizeof(su)); su.sll.sll_family = PF_PACKET; su.sll.sll_protocol = htons(protocol); - su.sll.sll_ifindex = iface->index; + su.sll.sll_ifindex = ifp->index; /* Install the DHCP filter */ memset(&pf, 0, sizeof(pf)); if (protocol == ETHERTYPE_ARP) { @@ -111,10 +112,11 @@ open_socket(struct interface *iface, int protocol) goto eexit; if (bind(s, &su.sa, sizeof(su)) == -1) goto eexit; + state = D_STATE(ifp); if (protocol == ETHERTYPE_ARP) - fd = &iface->state->arp_fd; + fd = &state->arp_fd; else - fd = &iface->state->raw_fd; + fd = &state->raw_fd; if (*fd != -1) close(*fd); *fd = s; @@ -126,9 +128,10 @@ eexit: } ssize_t -send_raw_packet(const struct interface *iface, int protocol, +send_raw_packet(const struct interface *ifp, int protocol, const void *data, ssize_t len) { + const struct dhcp_state *state; union sockunion { struct sockaddr sa; struct sockaddr_ll sll; @@ -139,24 +142,25 @@ send_raw_packet(const struct interface *iface, int protocol, memset(&su, 0, sizeof(su)); su.sll.sll_family = AF_PACKET; su.sll.sll_protocol = htons(protocol); - su.sll.sll_ifindex = iface->index; - su.sll.sll_hatype = htons(iface->family); - su.sll.sll_halen = iface->hwlen; - if (iface->family == ARPHRD_INFINIBAND) + su.sll.sll_ifindex = ifp->index; + su.sll.sll_hatype = htons(ifp->family); + su.sll.sll_halen = ifp->hwlen; + if (ifp->family == ARPHRD_INFINIBAND) memcpy(&su.sll.sll_addr, &ipv4_bcast_addr, sizeof(ipv4_bcast_addr)); else - memset(&su.sll.sll_addr, 0xff, iface->hwlen); + memset(&su.sll.sll_addr, 0xff, ifp->hwlen); + state = D_CSTATE(ifp); if (protocol == ETHERTYPE_ARP) - fd = iface->state->arp_fd; + fd = state->arp_fd; else - fd = iface->state->raw_fd; + fd = state->raw_fd; return sendto(fd, data, len, 0, &su.sa, sizeof(su)); } ssize_t -get_raw_packet(struct interface *iface, int protocol, +get_raw_packet(struct interface *ifp, int protocol, void *data, ssize_t len, int *partialcsum) { struct iovec iov = { @@ -167,6 +171,7 @@ get_raw_packet(struct interface *iface, int protocol, .msg_iov = &iov, .msg_iovlen = 1, }; + struct dhcp_state *state; #ifdef PACKET_AUXDATA unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))]; struct cmsghdr *cmsg; @@ -181,10 +186,11 @@ get_raw_packet(struct interface *iface, int protocol, msg.msg_controllen = sizeof(cmsgbuf); #endif + state = D_STATE(ifp); if (protocol == ETHERTYPE_ARP) - fd = iface->state->arp_fd; + fd = state->arp_fd; else - fd = iface->state->raw_fd; + fd = state->raw_fd; bytes = recvmsg(fd, &msg, 0); if (bytes == -1) return errno == EAGAIN ? 0 : -1; diff --git a/net.c b/net.c index 7379ea23..11662a2b 100644 --- a/net.c +++ b/net.c @@ -189,17 +189,10 @@ free_interface(struct interface *ifp) if (ifp == NULL) return; + dhcp_free(ifp); dhcp6_free(ifp); ipv6rs_free(ifp); free_options(ifp->options); - if (ifp->state) { - free(ifp->state->old); - free(ifp->state->new); - free(ifp->state->offer); - free(ifp->state->buffer); - free(ifp->state->clientid); - free(ifp->state); - } free(ifp); } @@ -572,6 +565,7 @@ open_udp_socket(struct interface *iface) int s; struct sockaddr_in sin; int n; + struct dhcp_state *state; #ifdef SO_BINDTODEVICE struct ifreq ifr; char *p; @@ -599,14 +593,15 @@ open_udp_socket(struct interface *iface) n = 1; if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &n, sizeof(n)) == -1) goto eexit; + state = D_STATE(iface); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(DHCP_CLIENT_PORT); - sin.sin_addr.s_addr = iface->state->addr.s_addr; + sin.sin_addr.s_addr = state->addr.s_addr; if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) goto eexit; - iface->state->udp_fd = s; + state->udp_fd = s; set_cloexec(s); return 0; @@ -625,7 +620,7 @@ send_packet(const struct interface *iface, struct in_addr to, sin.sin_family = AF_INET; sin.sin_addr.s_addr = to.s_addr; sin.sin_port = htons(DHCP_SERVER_PORT); - return sendto(iface->state->udp_fd, data, len, 0, + return sendto(D_CSTATE(iface)->udp_fd, data, len, 0, (struct sockaddr *)&sin, sizeof(sin)); } diff --git a/script.c b/script.c index cf286e1d..895c1964 100644 --- a/script.c +++ b/script.c @@ -182,10 +182,12 @@ make_env(const struct interface *ifp, const char *reason, char ***argv) const struct if_options *ifo = ifp->options; const struct interface *ifp2; int dhcp, dhcp6, ra; + const struct dhcp_state *state; const struct dhcp6_state *d6_state; dhcp = dhcp6 = ra = 0; - d6_state = D6_STATE(ifp); + state = D_STATE(ifp); + d6_state = D6_CSTATE(ifp); if (strcmp(reason, "TEST") == 0) { if (d6_state && d6_state->new) dhcp6 = 1; @@ -247,8 +249,8 @@ make_env(const struct interface *ifp, const char *reason, char ***argv) if (strcmp(reason, "TEST") == 0) { env[8] = strdup("if_up=false"); env[9] = strdup("if_down=false"); - } else if ((dhcp && ifp->state->new) || - (dhcp6 && d6_state->new) || + } else if ((dhcp && state && state->new) || + (dhcp6 && d6_state && d6_state->new) || (ra && ipv6rs_has_ra(ifp))) { env[8] = strdup("if_up=true"); @@ -257,39 +259,35 @@ make_env(const struct interface *ifp, const char *reason, char ***argv) env[8] = strdup("if_up=false"); env[9] = strdup("if_down=true"); } - if (*ifp->state->profile) { - e = strlen("profile=") + strlen(ifp->state->profile) + 2; + if (*ifp->profile) { + e = strlen("profile=") + strlen(ifp->profile) + 2; env[elen] = xmalloc(e); - snprintf(env[elen++], e, "profile=%s", ifp->state->profile); + snprintf(env[elen++], e, "profile=%s", ifp->profile); } if (ifp->wireless) { e = strlen("new_ssid=") + strlen(ifp->ssid) + 2; - if (ifp->state->new != NULL || - strcmp(ifp->state->reason, "CARRIER") == 0) - { + if (strcmp(reason, "CARRIER") == 0) { env = xrealloc(env, sizeof(char *) * (elen + 2)); env[elen] = xmalloc(e); snprintf(env[elen++], e, "new_ssid=%s", ifp->ssid); } - if (ifp->state->old != NULL || - strcmp(ifp->state->reason, "NOCARRIER") == 0) - { + else if (strcmp(reason, "NOCARRIER") == 0) { env = xrealloc(env, sizeof(char *) * (elen + 2)); env[elen] = xmalloc(e); snprintf(env[elen++], e, "old_ssid=%s", ifp->ssid); } } - if (dhcp && ifp->state->old) { - e = configure_env(NULL, NULL, ifp->state->old, ifp); + if (dhcp && state && state->old) { + e = configure_env(NULL, NULL, state->old, ifp); if (e > 0) { env = xrealloc(env, sizeof(char *) * (elen + e + 1)); elen += configure_env(env + elen, "old", - ifp->state->old, ifp); + state->old, ifp); } append_config(&env, &elen, "old", (const char *const *)ifo->config); } - if (dhcp6 && d6_state->old) { + if (dhcp6 && d6_state && d6_state->old) { e = dhcp6_env(NULL, NULL, ifp, d6_state->old, d6_state->old_len); if (e > 0) { @@ -300,17 +298,17 @@ make_env(const struct interface *ifp, const char *reason, char ***argv) } dumplease: - if (dhcp && ifp->state->new) { - e = configure_env(NULL, NULL, ifp->state->new, ifp); + if (dhcp && state && state->new) { + e = configure_env(NULL, NULL, state->new, ifp); if (e > 0) { env = xrealloc(env, sizeof(char *) * (elen + e + 1)); elen += configure_env(env + elen, "new", - ifp->state->new, ifp); + state->new, ifp); } append_config(&env, &elen, "new", (const char *const *)ifo->config); } - if (dhcp6 && d6_state->new) { + if (dhcp6 && d6_state && d6_state->new) { e = dhcp6_env(NULL, NULL, ifp, d6_state->new, d6_state->new_len); if (e > 0) { @@ -373,7 +371,9 @@ int send_interface(int fd, const struct interface *iface) { int retval = 0; - if (send_interface1(fd, iface, iface->state->reason) == -1) + const struct dhcp_state *state = D_CSTATE(iface); + + if (state && send_interface1(fd, iface, state->reason) == -1) retval = -1; if (ipv6rs_has_ra(iface)) { if (send_interface1(fd, iface, "ROUTERADVERT") == -1) @@ -403,8 +403,11 @@ script_runreason(const struct interface *ifp, const char *reason) strcmp(ifp->options->script, "/dev/null") == 0) return 0; - if (reason == NULL) - reason = ifp->state->reason; + if (reason == NULL) { + const struct dhcp_state *state = D_CSTATE(ifp); + if (state) + reason = state->reason; + } syslog(LOG_DEBUG, "%s: executing `%s', reason %s", ifp->name, argv[0], reason); diff --git a/script.h b/script.h index 50e142cc..5979355c 100644 --- a/script.h +++ b/script.h @@ -34,5 +34,4 @@ void if_printoptions(void); int send_interface(int, const struct interface *); int script_runreason(const struct interface *, const char *); -#define script_run(ifp) script_runreason(ifp, (ifp)->state->reason); #endif