Hi,
ospf6d does not resend LSAs when a carp interface goes into backup state.
This is unfortunate since other routers may still use the route to the
backup router or they even do ECMP and send traffic to the master and backup.
This minimal diff adds braces to fix it:
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospf6d/rde.c,v
retrieving revision 1.74
diff -u -p -r1.74 rde.c
--- rde.c 10 Jun 2018 14:39:38 -0000 1.74
+++ rde.c 11 Jun 2018 13:45:48 -0000
@@ -717,8 +717,8 @@ rde_dispatch_parent(int fd, short event,
ifp->linkstate, ifp->baudrate);
/* Resend LSAs if interface state changes. */
- if (wasvalid != (iface->flags & IFF_UP) &&
- LINK_STATE_IS_UP(iface->linkstate)) {
+ if (wasvalid != ((iface->flags & IFF_UP) &&
+ LINK_STATE_IS_UP(iface->linkstate))) {
area = area_find(rdeconf, iface->area_id);
if (!area)
fatalx("interface lost area");
Below diff is a bit more "verbose" and might be easier to understand.
I prefer the 2nd one.
OK?
Remi
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospf6d/rde.c,v
retrieving revision 1.74
diff -u -p -r1.74 rde.c
--- rde.c 10 Jun 2018 14:39:38 -0000 1.74
+++ rde.c 11 Jun 2018 14:04:18 -0000
@@ -640,7 +640,7 @@ rde_dispatch_parent(int fd, short event,
struct lsa *lsa;
struct vertex *v;
ssize_t n;
- int shut = 0, wasvalid;
+ int shut = 0, link_ok, prev_link_ok;
unsigned int ifindex;
if (event & EV_READ) {
@@ -710,20 +710,23 @@ rde_dispatch_parent(int fd, short event,
if (iface == NULL)
fatalx("interface lost in rde");
- wasvalid = (iface->flags & IFF_UP) &&
+ prev_link_ok = (iface->flags & IFF_UP) &&
LINK_STATE_IS_UP(iface->linkstate);
if_update(iface, ifp->mtu, ifp->flags, ifp->if_type,
ifp->linkstate, ifp->baudrate);
/* Resend LSAs if interface state changes. */
- if (wasvalid != (iface->flags & IFF_UP) &&
- LINK_STATE_IS_UP(iface->linkstate)) {
- area = area_find(rdeconf, iface->area_id);
- if (!area)
- fatalx("interface lost area");
- orig_intra_area_prefix_lsas(area);
- }
+ link_ok = (iface->flags & IFF_UP ) &&
+ LINK_STATE_IS_UP(iface->linkstate);
+ if (prev_link_ok == link_ok)
+ break;
+
+ area = area_find(rdeconf, iface->area_id);
+ if (!area)
+ fatalx("interface lost area");
+ orig_intra_area_prefix_lsas(area);
+
break;
case IMSG_IFADD:
if ((iface = malloc(sizeof(struct iface))) == NULL)