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	4 Jan 2011 08:44:10 -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	4 Jan 2011 08:44:11 -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,17 @@ 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 */
+			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 +1466,27 @@ 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:
+		 *  - have a link state that is not up, or
+		 *  - are down (kernel flags), or
+		 *  - are in the down state, and are not [carp or marked as passive], or
+		 *  - are unknown and are carp
+		 *
+		 * This will not advertise backup carp interfaces (which have a link
+		 * state of down). 
+		 */
+		if (!(LINK_STATE_IS_UP(iface->linkstate)) ||
+		    !(iface->flags & IFF_UP) ||
+		    ((iface->state & IF_STA_DOWN) && 
+		    !((iface->media_type == IFT_CARP) || 
+		    (iface->cflags & F_IFACE_PASSIVE))) || 
+		    ((iface->linkstate == LINK_STATE_UNKNOWN) && 
+		    (iface->media_type == IFT_CARP))) {
+			log_debug("orig_intra_lsa_rtr: area %s, interface %s: not including"
+			    " in LSA", inet_ntoa(area->id), iface->name);
 			continue;
+		}
 
 		/* Broadcast links with adjacencies are handled
 		 * by orig_intra_lsa_net(), ignore. */
