static void stop_adverts(int sock, struct Interface *ifaces) { flog(LOG_INFO, "sending stop adverts"); /* * send final RA (a SHOULD in RFC4861 section 6.2.5) */ for_each_iface(ifaces, stop_advert_foo, &sock); }
/* handle a script termination and update the state accordingly */ void ifsm_scriptdone(pid_t pid, int exitstatus) { int exitok = WIFEXITED(exitstatus) && WEXITSTATUS(exitstatus) == 0; struct if_info *info; assert(WIFEXITED(exitstatus) || WIFSIGNALED(exitstatus)); int find_pid(struct if_info *i) { if (i->worker == pid) { info = i; return 1; } return 0; } info = NULL; for_each_iface(find_pid); if (info == NULL) { do_log(LOG_INFO, "Unexpected child %d exited with status %d", pid, exitstatus); return; } do_log(LOG_INFO, "%s: state %s pid %d exited status %d", info->name, statename(info->state), pid, exitstatus); info->worker = -1; switch(info->state) { case ST_PROBING: /* If we're still in PROBING state, then it means that the interface flags have not come up, even though the script finished. Go back to DOWN and wait for the UP flag setting. */ if (!exitok) do_log(LOG_WARNING, "Could not bring %s back up", info->name); info->state = ST_DOWN; break; case ST_PROBING_UP: /* regardless of script's exit status, the interface is actually up now, so just make it inactive */ info->state = ST_INACTIVE; break; case ST_DOWNANDOUT: /* we were just waiting for the out script to finish - start a probe script for this interface */ info->state = ST_PROBING; assert(info->worker == -1); info->worker = run_netplug_bg(info->name, "probe"); break; case ST_INNING: if (exitok) info->state = ST_ACTIVE; else info->state = ST_INSANE; /* ??? */ break; case ST_OUTING: /* What if !exitok? What if interface is still active? ->ST_INSANE? */ info->state = ST_INACTIVE; break; case ST_WAIT_IN: assert(info->worker == -1); info->worker = run_netplug_bg(info->name, "out"); info->state = ST_OUTING; break; case ST_INACTIVE: case ST_ACTIVE: case ST_INSANE: case ST_DOWN: do_log(LOG_ERR, "ifsm_scriptdone: %s: bad state %s for script termination", info->name, statename(info->state)); exit(1); } do_log(LOG_DEBUG, "%s: moved to state %s", info->name, statename(info->state)); }
static void reset_prefix_lifetimes(struct Interface *ifaces) { for_each_iface(ifaces, reset_prefix_lifetimes_foo, 0); }
static void setup_ifaces(int sock, struct Interface *ifaces) { for_each_iface(ifaces, setup_iface_foo, &sock); }