Hi, ospfd does not react nicely when running "sh /etc/netstart if".
This is because adding the same address again do an interface results in RTM_DELADDR and RTM_NEWADDR. ospfd handles the former but the later. If this happens ospfd says "interface vether0:192.168.250.1 gone". Adjacencies on that interface are down and ospfd can not recover. The below patch adds IMSG_IFADDRADD to deal with that. With it ospfd logs the following after "ifconfig vether0 192.168.250.1/24" (same address as active before): orig_rtr_lsa: area 0.0.0.0 orig_rtr_lsa: stub net, interface iwm0 orig_rtr_lsa: stub net, interface vether0 orig_rtr_lsa: transit net, interface pair0 if_fsm: event DOWN resulted in action RESET and changing state for interface vether0 from DR to DOWN interface vether0:192.168.250.1 gone orig_rtr_lsa: area 0.0.0.0 orig_rtr_lsa: stub net, interface iwm0 orig_rtr_lsa: stub net, interface vether0 orig_rtr_lsa: transit net, interface pair0 if_fsm: event UP resulted in action START and changing state for interface vether0 from DOWN to WAIT interface vether0:192.168.250.1 returned In addition the patch also deals with a changed netmask if the address stays the same. A complete new address still needs a change in ospfd.conf and a reload. Remi Index: kroute.c =================================================================== RCS file: /cvs/src/usr.sbin/ospfd/kroute.c,v retrieving revision 1.107 diff -u -p -r1.107 kroute.c --- kroute.c 27 Dec 2016 09:15:16 -0000 1.107 +++ kroute.c 25 Jun 2017 20:58:33 -0000 @@ -1046,6 +1046,7 @@ if_newaddr(u_short ifindex, struct socka { struct kif_node *kif; struct kif_addr *ka; + struct ifaddrnew ifn; if (ifa == NULL || ifa->sin_family != AF_INET) return; @@ -1066,6 +1067,12 @@ if_newaddr(u_short ifindex, struct socka ka->dstbrd.s_addr = INADDR_NONE; TAILQ_INSERT_TAIL(&kif->addrs, ka, entry); + + ifn.addr = ka->addr; + ifn.mask = ka->mask; + ifn.dst = ka->dstbrd; + ifn.ifindex = ifindex; + main_imsg_compose_ospfe(IMSG_IFADDRADD, 0, &ifn, sizeof(ifn)); } void Index: ospfd.h =================================================================== RCS file: /cvs/src/usr.sbin/ospfd/ospfd.h,v retrieving revision 1.97 diff -u -p -r1.97 ospfd.h --- ospfd.h 24 Jan 2017 04:24:25 -0000 1.97 +++ ospfd.h 25 Jun 2017 20:58:33 -0000 @@ -132,6 +132,7 @@ enum imsg_type { IMSG_RECONF_REDIST, IMSG_RECONF_END, IMSG_DEMOTE, + IMSG_IFADDRADD, IMSG_IFADDRDEL }; @@ -358,6 +359,13 @@ struct iface { u_int8_t linkstate; u_int8_t priority; u_int8_t passive; +}; + +struct ifaddrnew { + struct in_addr addr; + struct in_addr mask; + struct in_addr dst; + unsigned int ifindex; }; struct ifaddrdel { Index: ospfe.c =================================================================== RCS file: /cvs/src/usr.sbin/ospfd/ospfe.c,v retrieving revision 1.99 diff -u -p -r1.99 ospfe.c --- ospfe.c 24 Jan 2017 04:24:25 -0000 1.99 +++ ospfe.c 25 Jun 2017 20:58:33 -0000 @@ -278,6 +278,7 @@ ospfe_dispatch_main(int fd, short event, { static struct area *narea; static struct iface *niface; + struct ifaddrnew *ifn; struct ifaddrdel *ifc; struct imsg imsg; struct imsgev *iev = bula; @@ -345,6 +346,28 @@ ospfe_dispatch_main(int fd, short event, " down", iface->name); } + } + } + } + break; + case IMSG_IFADDRADD: + if (imsg.hdr.len != IMSG_HEADER_SIZE + + sizeof(struct ifaddrnew)) + fatalx("IFADDRADD imsg with wrong len"); + ifn = imsg.data; + + LIST_FOREACH(area, &oeconf->area_list, entry) { + LIST_FOREACH(iface, &area->iface_list, entry) { + if (ifn->ifindex == iface->ifindex && + ifn->addr.s_addr == + iface->addr.s_addr) { + iface->mask = ifn->mask; + iface->dst = ifn->dst; + if_fsm(iface, IF_EVT_UP); + log_warnx("interface %s:%s " + "returned", iface->name, + inet_ntoa(iface->addr)); + break; } } }