This is based on a diff by Patrick Coleman.
Quoting his correct analysis:
> I believe ospfd/ospf6d are incorrectly handling states for loopback
> interfaces - basically, if the interface is down when the daemon is
> started, it comes up in state LOOP anyway. if_fsm then throws the
> error "if_fsm: interface lo1, event UP not expected in state LOOP"
> when the interface comes up, as it's receiving an UP event on an
> interface it thinks is up already.
So instead of special casing loopbacks at init time and nailing them UP we
do the normal init and call if_act_start() when the interface comes up.
As a benefit the interface uptime is now also reported correctly.
This also make the special case for reloads obsolete.
--
:wq Claudio
Index: ospfd/interface.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/interface.c,v
retrieving revision 1.70
diff -u -p -r1.70 interface.c
--- ospfd/interface.c 3 Jul 2010 04:44:52 -0000 1.70
+++ ospfd/interface.c 5 May 2011 13:55:35 -0000
@@ -189,7 +189,6 @@ if_new(struct kif *kif, struct kif_addr
iface->type = IF_TYPE_BROADCAST;
if (kif->flags & IFF_LOOPBACK) {
iface->type = IF_TYPE_POINTOPOINT;
- iface->state = IF_STA_LOOPBACK;
iface->passive = 1;
}
@@ -351,14 +350,18 @@ if_act_start(struct iface *iface)
iface->passive = 1;
}
+ gettimeofday(&now, NULL);
+ iface->uptime = now.tv_sec;
+
+ /* loopback interfaces have a special state and are passive */
+ if (iface->flags & IFF_LOOPBACK)
+ iface->state = IF_STA_LOOPBACK;
+
if (iface->passive) {
/* for an update of stub network entries */
orig_rtr_lsa(iface->area);
return (0);
}
-
- gettimeofday(&now, NULL);
- iface->uptime = now.tv_sec;
switch (iface->type) {
case IF_TYPE_POINTOPOINT:
Index: ospfd/ospfd.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/ospfd.c,v
retrieving revision 1.76
diff -u -p -r1.76 ospfd.c
--- ospfd/ospfd.c 24 Mar 2011 08:35:59 -0000 1.76
+++ ospfd/ospfd.c 5 May 2011 13:47:37 -0000
@@ -836,8 +836,7 @@ merge_interfaces(struct area *a, struct
LIST_REMOVE(xi, entry);
LIST_INSERT_HEAD(&a->iface_list, xi, entry);
xi->area = a;
- if (ospfd_process == PROC_OSPF_ENGINE &&
- !(xi->state == IF_STA_LOOPBACK))
+ if (ospfd_process == PROC_OSPF_ENGINE)
xi->state = IF_STA_NEW;
continue;
}
Index: ospf6d/interface.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospf6d/interface.c,v
retrieving revision 1.15
diff -u -p -r1.15 interface.c
--- ospf6d/interface.c 20 Sep 2009 20:45:06 -0000 1.15
+++ ospf6d/interface.c 5 May 2011 13:52:24 -0000
@@ -250,7 +250,7 @@ if_update(struct iface *iface, int mtu,
iface->type = IF_TYPE_BROADCAST;
if (flags & IFF_LOOPBACK) {
iface->type = IF_TYPE_POINTOPOINT;
- iface->state = IF_STA_LOOPBACK;
+ iface->cflags |= F_IFACE_PASSIVE;
}
}
@@ -386,14 +386,18 @@ if_act_start(struct iface *iface)
iface->cflags |= F_IFACE_PASSIVE;
}
+ gettimeofday(&now, NULL);
+ iface->uptime = now.tv_sec;
+
+ /* loopback interfaces have a special state */
+ if (iface->flags & IFF_LOOPBACK)
+ iface->state = IF_STA_LOOPBACK;
+
if (iface->cflags & F_IFACE_PASSIVE) {
/* for an update of stub network entries */
orig_rtr_lsa(iface);
return (0);
}
-
- gettimeofday(&now, NULL);
- iface->uptime = now.tv_sec;
switch (iface->type) {
case IF_TYPE_POINTOPOINT: