Florian Obser <flor...@openbsd.org> writes: > On 2024-06-17 15:02 +02, Sebastien Marie <sema...@kapouay.eu.org> wrote: >> Hi, >> >> I am using dhcp6leased on my gateway to get ipv6-pd over pppoe from my >> ISP. >> >> The problem is when the pppoe0 disconnect/reconnect due to LCP keepalive >> timeout, my ISP consider the dhcp leased as not valid anymore, and I >> need to re-ask a fresh one (running `dhcp6leasectl pppoe0` is enough) to >> have ipv6 working again. >> >> During the disconnect/reconnect, the status switch from 'active' to 'no >> carrier' and come back to 'active'. I wonder if dhcp6leased would be >> able to detect such state to reinit itself ? > > yes, past me was lazy / not yet done with dhcp6leased. > > Can you try this please? I don't have pppoe(4) but it does the right > thing for ifconfig vio0 down / up. > > (We need to keep the "route" pledge in frontend.c for getifaddrs(3)). > > OK?
I artificially generated a pppoe0 timeout (by unplugging and replugging the link between openbsd router and upstream), and all was fine. I had the "LCP keepalive timeout" in dmesg, and dhcp6leased properly get the things going back right. Below curated output of 'dhcp6leased -dvv' for transitions: state_transition[pppoe0] Bound -> Down, timo: -1 state_transition[pppoe0] Down -> Down, timo: -1 state_transition[pppoe0] Down -> Down, timo: -1 state_transition[pppoe0] Down -> Rebooting, timo: 1 state_transition[pppoe0] Rebooting -> Rebooting, timo: 2 state_transition[pppoe0] Rebooting -> Init, timo: 1 state_transition[pppoe0] Init -> Requesting, timo: 1 state_transition[pppoe0] Requesting -> Bound, timo: 302400 ok semarie@ > diff --git engine.c engine.c > index 180847406b1..4847158aabf 100644 > --- engine.c > +++ engine.c > @@ -1034,27 +1034,9 @@ state_transition(struct dhcp6leased_iface *iface, enum > if_state new_state) > > switch (new_state) { > case IF_DOWN: > -#if 0 > -XXXX > - if (iface->requested_ip.s_addr == INADDR_ANY) { > - /* nothing to do until iface comes up */ > - iface->timo.tv_sec = -1; > - break; > - } > - if (old_state == IF_DOWN) { > - /* nameservers already withdrawn when if went down */ > - deconfigure_interfaces(iface); > - /* nothing more to do until iface comes back */ > - iface->timo.tv_sec = -1; > - } else { > - clock_gettime(CLOCK_MONOTONIC, &now); > - timespecsub(&now, &iface->request_time, &res); > - iface->timo.tv_sec = iface->lease_time - res.tv_sec; > - if (iface->timo.tv_sec < 0) > - iface->timo.tv_sec = 0; /* deconfigure now */ > - } > -#endif > - /* nothing to do until iface comes up */ > + /* > + * Nothing to do until iface comes up. IP addresses will expire. > + */ > iface->timo.tv_sec = -1; > break; > case IF_INIT: > diff --git frontend.c frontend.c > index b5e349ccae0..9d39edd49e4 100644 > --- frontend.c > +++ frontend.c > @@ -69,7 +69,6 @@ struct iface { > > __dead void frontend_shutdown(void); > void frontend_sig_handler(int, short, void *); > -void rtsock_update_iface(struct if_msghdr *, struct sockaddr_dl *); > void frontend_startup(void); > void update_iface(uint32_t); > void route_receive(int, short, void *); > @@ -595,64 +594,6 @@ update_iface(uint32_t if_index) > sizeof(iface->ifinfo)); > } > > -void > -rtsock_update_iface(struct if_msghdr *ifm, struct sockaddr_dl *sdl) > -{ > -#if 0 > -XXX > - struct iface *iface; > - struct imsg_ifinfo ifinfo; > - uint32_t if_index; > - int flags; > - char ifnamebuf[IF_NAMESIZE], *if_name; > - > - if_index = ifm->ifm_index; > - > - flags = ifm->ifm_flags; > - > - iface = get_iface_by_id(if_index); > - if_name = if_indextoname(if_index, ifnamebuf); > - > - if (if_name == NULL) { > - if (iface != NULL) { > - log_debug("interface with idx %d removed", if_index); > - frontend_imsg_compose_engine(IMSG_REMOVE_IF, 0, 0, > - &if_index, sizeof(if_index)); > - remove_iface(if_index); > - } > - return; > - } > - > - memset(&ifinfo, 0, sizeof(ifinfo)); > - ifinfo.if_index = if_index; > - ifinfo.link_state = ifm->ifm_data.ifi_link_state; > - ifinfo.rdomain = ifm->ifm_tableid; > - ifinfo.running = (flags & (IFF_UP | IFF_RUNNING)) == > - (IFF_UP | IFF_RUNNING); > - > - if (iface == NULL) { > - if ((iface = calloc(1, sizeof(*iface))) == NULL) > - fatal("calloc"); > - iface->udpsock = -1; > - LIST_INSERT_HEAD(&interfaces, iface, entries); > - frontend_imsg_compose_main(IMSG_OPEN_UDPSOCK, 0, > - &if_index, sizeof(if_index)); > - } else { > - if (iface->ifinfo.rdomain != ifinfo.rdomain && > - iface->udpsock != -1) { > - close(iface->udpsock); > - iface->udpsock = -1; > - } > - } > - > - if (memcmp(&iface->ifinfo, &ifinfo, sizeof(iface->ifinfo)) != 0) { > - memcpy(&iface->ifinfo, &ifinfo, sizeof(iface->ifinfo)); > - frontend_imsg_compose_main(IMSG_UPDATE_IF, 0, &iface->ifinfo, > - sizeof(iface->ifinfo)); > - } > -#endif > -} > - > void > frontend_startup(void) > { > @@ -660,8 +601,6 @@ frontend_startup(void) > fatalx("%s: did not receive a route socket from the main " > "process", __func__); > > - if (pledge("stdio unix recvfd", NULL) == -1) > - fatal("pledge"); > event_add(&ev_route, NULL); > } > > @@ -707,16 +646,13 @@ route_receive(int fd, short events, void *arg) > void > handle_route_message(struct rt_msghdr *rtm, struct sockaddr **rti_info) > { > - struct sockaddr_dl *sdl = NULL; > struct if_announcemsghdr *ifan; > uint32_t if_index; > > switch (rtm->rtm_type) { > case RTM_IFINFO: > - if (rtm->rtm_addrs & RTA_IFP && rti_info[RTAX_IFP]->sa_family > - == AF_LINK) > - sdl = (struct sockaddr_dl *)rti_info[RTAX_IFP]; > - rtsock_update_iface((struct if_msghdr *)rtm, sdl); > + if_index = ((struct if_msghdr *)rtm)->ifm_index; > + update_iface(if_index); > break; > case RTM_IFANNOUNCE: > ifan = (struct if_announcemsghdr *)rtm; -- Sebastien Marie