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;
}
}
}