void handle_carrier(int carrier, int flags, const char *ifname) { struct interface *ifp; if (!(options & DHCPCD_LINK)) return; ifp = find_interface(ifname); if (ifp == NULL) { handle_interface(1, ifname); return; } if (!(ifp->options->options & DHCPCD_LINK)) return; if (carrier == LINK_UNKNOWN) carrier = carrier_status(ifp); /* will set ifp->flags */ else ifp->flags = flags; if (carrier == LINK_UNKNOWN) syslog(LOG_ERR, "%s: carrier_status: %m", ifname); /* IFF_RUNNING is checked, if needed, earlier and is OS dependant */ else if (carrier == LINK_DOWN || (ifp->flags & IFF_UP) == 0) { if (ifp->carrier != LINK_DOWN) { if (ifp->carrier == LINK_UP) syslog(LOG_INFO, "%s: carrier lost", ifp->name); ifp->carrier = LINK_DOWN; dhcp_close(ifp); dhcp6_drop(ifp, "EXPIRE6"); ipv6rs_drop(ifp); /* Don't blindly delete our knowledge of LL addresses. * We need to listen to what the kernel does with * them as some OS's will remove, mark tentative or * do nothing. */ ipv6_free_ll_callbacks(ifp); dhcp_drop(ifp, "NOCARRIER"); } } else if (carrier == LINK_UP && ifp->flags & IFF_UP) { if (ifp->carrier != LINK_UP) { syslog(LOG_INFO, "%s: carrier acquired", ifp->name); ifp->carrier = LINK_UP; #if !defined(__linux__) && !defined(__NetBSD__) /* BSD does not emit RTM_NEWADDR or RTM_CHGADDR when the * hardware address changes so we have to go * through the disovery process to work it out. */ handle_interface(0, ifp->name); #endif if (ifp->wireless) getifssid(ifp->name, ifp->ssid); configure_interface(ifp, margc, margv); script_runreason(ifp, "CARRIER"); start_interface(ifp); } } }
static void if_reboot(struct interface *ifp, int argc, char **argv) { int oldopts; oldopts = ifp->options->options; script_runreason(ifp, "RECONFIGURE"); configure_interface(ifp, argc, argv); dhcp_reboot_newopts(ifp, oldopts); dhcp6_reboot(ifp); start_interface(ifp); }
static void init_state(struct interface *ifp, int argc, char **argv) { struct if_options *ifo; const char *reason = NULL; configure_interface(ifp, argc, argv); ifo = ifp->options; if (ifo->options & DHCPCD_IPV4 && ipv4_init() == -1) { syslog(LOG_ERR, "ipv4_init: %m"); ifo->options &= ~DHCPCD_IPV4; } if (ifo->options & DHCPCD_IPV6 && ipv6_init() == -1) { syslog(LOG_ERR, "ipv6_init: %m"); ifo->options &= ~DHCPCD_IPV6RS; } if (!(options & DHCPCD_TEST)) script_runreason(ifp, "PREINIT"); if (ifo->options & DHCPCD_LINK) { switch (carrier_status(ifp)) { case 0: ifp->carrier = LINK_DOWN; reason = "NOCARRIER"; break; case 1: ifp->carrier = LINK_UP; reason = "CARRIER"; break; default: ifp->carrier = LINK_UNKNOWN; return; } if (reason && !(options & DHCPCD_TEST)) script_runreason(ifp, reason); } else ifp->carrier = LINK_UNKNOWN; }
static void stop_interface(struct interface *ifp) { syslog(LOG_INFO, "%s: removing interface", ifp->name); ifp->options->options |= DHCPCD_STOPPING; // Remove the interface from our list TAILQ_REMOVE(ifaces, ifp, next); dhcp6_drop(ifp, NULL); ipv6rs_drop(ifp); dhcp_drop(ifp, "STOP"); dhcp_close(ifp); eloop_timeout_delete(NULL, ifp); if (ifp->options->options & DHCPCD_DEPARTED) script_runreason(ifp, "DEPARTED"); free_interface(ifp); if (!(options & (DHCPCD_MASTER | DHCPCD_TEST))) exit(EXIT_FAILURE); }
static void ipv6ns_unreachable(void *arg) { struct ra *rap = arg; struct timeval tv; /* We could add an unreachable flag and persist the information, * but that is more effort than it's probably worth. */ syslog(LOG_WARNING, "%s: %s is unreachable, expiring it", rap->iface->name, rap->sfrom); rap->expired = 1; ipv6_buildroutes(); script_runreason(rap->iface, "ROUTERADVERT"); /* XXX not RA */ /* We should still test if it's reachable or not so * incase it comes back to life and it's preferable. */ if (rap->reachable) { ms_to_tv(&tv, rap->reachable); } else { tv.tv_sec = REACHABLE_TIME; tv.tv_usec = 0; } eloop_timeout_add_tv(&tv, ipv6ns_proberouter, rap); }