On Wed, Jan 5, 2011 at 8:32 PM, Jan Johansson <janj+open...@wenf.org> wrote:
>
> So I found a bug here.
>
> Your mk2 patch (didn't try the mk1) does not advertise gif
> tunnels this works with the unpatched binary.

Apologies for the delay on this one - finally got around to setting up
a test environment today. See [1] for an updated patch.

I've reworked the logic a bit (basically, it wasn't correctly dealing
with interfaces with unknown physical link states before). I've tested
the patch and it works with CARP and loopback interfaces, and gif
interfaces should work the same.

Comments appreciated.

Cheers,

Patrick

1. Also uploaded to
http://patrick.ld.net.au/ospf6d-fix-passive-interfaces-mk3.patch

Index: interface.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospf6d/interface.c,v
retrieving revision 1.15
diff -u -p -r1.15 interface.c
--- interface.c 20 Sep 2009 20:45:06 -0000      1.15
+++ interface.c 25 Apr 2011 10:35:00 -0000
@@ -145,11 +145,15 @@ if_fsm(struct iface *iface, enum iface_e
        if (iface->state != old_state) {
                orig_rtr_lsa(iface);
                orig_link_lsa(iface);
-
-               /* state change inform RDE */
-               ospfe_imsg_compose_rde(IMSG_IFINFO,
-                   iface->self->peerid, 0, iface, sizeof(struct iface));
        }
+       
+       /*
+        * Send interface update to RDE regardless of whether state changes - a
+        * passive interface will remain in the DOWN state but may need to have
+        * prefix LSAs sent regardless.
+        */
+       ospfe_imsg_compose_rde(IMSG_IFINFO,
+           iface->self->peerid, 0, iface, sizeof(struct iface));

        if (old_state & (IF_STA_MULTI | IF_STA_POINTTOPOINT) &&
            (iface->state & (IF_STA_MULTI | IF_STA_POINTTOPOINT)) == 0)
Index: rde.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospf6d/rde.c,v
retrieving revision 1.50
diff -u -p -r1.50 rde.c
--- rde.c       22 Aug 2010 20:55:10 -0000      1.50
+++ rde.c       25 Apr 2011 10:35:03 -0000
@@ -22,6 +22,7 @@
 #include <sys/socket.h>
 #include <sys/queue.h>
 #include <sys/param.h>
+#include <net/if_types.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <err.h>
@@ -587,11 +588,20 @@ rde_dispatch_imsg(int fd, short event, v
                        iface = if_find(ifp->ifindex);
                        if (iface == NULL)
                                fatalx("interface lost in rde");
-                       iface->flags = ifp->flags;
-                       iface->linkstate = ifp->linkstate;
                        iface->nh_reachable = ifp->nh_reachable;
-                       if (iface->state != ifp->state) {
+
+                       /*
+                        * Resend LSAs if interface flags change - carp/passive 
interfaces
+                        * can come up and down without changing state.
+                        */
+                       if ((iface->state != ifp->state) ||
+                           (iface->linkstate != ifp->linkstate) ||
+                           (iface->flags != ifp->flags)) {
+
                                iface->state = ifp->state;
+                               iface->flags = ifp->flags;
+                               iface->linkstate = ifp->linkstate;
+
                                area = area_find(rdeconf, iface->area_id);
                                if (!area)
                                        fatalx("interface lost area");
@@ -1459,8 +1469,43 @@ orig_intra_lsa_rtr(struct area *area, st

        numprefix = 0;
        LIST_FOREACH(iface, &area->iface_list, entry) {
-               if (iface->state & IF_STA_DOWN)
+               /*
+                * Do not send a LSA for interfaces that:
+                *  - are down (kernel flags)
+                *
+                *  - are not carp and have a physical link state of down, 
excluding
+                *    unknown interfaces: if an interface has a link state of 
unknown
+                *    then the driver supplies no information about the 
physical link
+                *    state
+                *
+                *  - are carp and have a physical link state of down or 
unknown: carp
+                *    uses the DOWN state for the backup interface, and the 
UNKNOWN link
+                *    state if something broke
+                *
+                *  - are in the down state, and are not [carp or marked as 
passive]:
+                *    carp and passive interfaces will always have an OSPF 
state of
+                *    DOWN.
+                *
+                * Note we recheck interface flags and link state here in 
addition to
+                * if_act_* as passive interfaces can change link state while 
remaining
+                * in IF_STA_DOWN.
+                */
+               if (!(iface->flags & IFF_UP) ||
+                   ((iface->media_type != IFT_CARP) &&
+                   !(LINK_STATE_IS_UP(iface->linkstate)) &&
+                   (iface->linkstate != LINK_STATE_UNKNOWN)) ||
+                   ((iface->media_type == IFT_CARP) &&
+                   !(LINK_STATE_IS_UP(iface->linkstate))) ||
+                   ((iface->state & IF_STA_DOWN) &&
+                   !((iface->media_type == IFT_CARP) ||
+                   (iface->cflags & F_IFACE_PASSIVE)))) {
+                       log_debug("orig_intra_lsa_rtr: area %s, interface %s: 
not including"
+                           " in intra-area-prefix LSA", inet_ntoa(area->id), 
iface->name);
                        continue;
+               } else {
+                       log_debug("orig_intra_lsa_rtr: area %s, interface %s: 
including"
+                           " in intra-area-prefix LSA", inet_ntoa(area->id), 
iface->name);
+               }

                /* Broadcast links with adjacencies are handled
                 * by orig_intra_lsa_net(), ignore. */

Reply via email to