--- a/ospfd/ospf_nsm.c
+++ b/ospfd/ospf_nsm.c
@@ -375,6 +375,8 @@
 
 	if (CHECK_FLAG(nbr->options, OSPF_OPTION_O))
 		UNSET_FLAG(nbr->options, OSPF_OPTION_O);
+
+	ospf_hello_reset_send(nbr->oi);
 }
 
 static int nsm_kill_nbr(struct ospf_neighbor *nbr)
@@ -388,9 +390,10 @@
 	if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_nbma != NULL) {
 		struct ospf_nbr_nbma *nbr_nbma = nbr->nbr_nbma;
 
+		ospf_hello_reset_send(nbr->oi);
+
 		nbr_nbma->nbr = NULL;
 		nbr_nbma->state_change = nbr->state_change;
-
 		nbr->nbr_nbma = NULL;
 
 		OSPF_POLL_TIMER_ON(nbr_nbma->t_poll, ospf_poll_timer,
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -76,6 +76,17 @@
 #define WANT_OSPF_WRITE_FRAGMENT
 #endif
 
+
+#ifdef DEBUG
+#define OSPF_DEBUG_FFL		do {					\
+		if (IS_DEBUG_OSPF_EVENT) { 				\
+			zlog_debug("trace: file %s func %s line %d",	\
+				__FILE__, __func__, __LINE__); }	\
+	} while (0)
+#else
+#define OSPF_DEBUG_FFL do { 0 } while (0)
+#endif
+
 /* Packet Type String. */
 const struct message ospf_packet_type_str[] = {
 	{OSPF_MSG_HELLO, "Hello"},
@@ -1077,6 +1088,7 @@
 	if (IPV4_ADDR_SAME(&nbr->address.u.prefix4, &hello->d_router))
 		if (hello->bd_router.s_addr == INADDR_ANY
 		    && oi->state == ISM_Waiting)
+
 			OSPF_ISM_EVENT_SCHEDULE(oi, ISM_BackupSeen);
 
 	/* neighbor itself declares BDR. */
@@ -1128,6 +1140,10 @@
 	stream_forward_getp(s, OSPF_DB_DESC_MIN_SIZE);
 	for (size -= OSPF_DB_DESC_MIN_SIZE; size >= OSPF_LSA_HEADER_SIZE;
 	     size -= OSPF_LSA_HEADER_SIZE) {
+
+		if (size < OSPF_LSA_HEADER_SIZE)
+			break;
+
 		lsah = (struct lsa_header *)stream_pnt(s);
 		stream_forward_getp(s, OSPF_LSA_HEADER_SIZE);
 
@@ -1455,20 +1471,23 @@
 		break;
 	case NSM_Exchange:
 		if (ospf_db_desc_is_dup(dd, nbr)) {
-			if (IS_SET_DD_MS(nbr->dd_flags))
-				/* Master: discard duplicated DD packet. */
-				zlog_info(
-					"Packet[DD] (Master): Neighbor %pI4 packet duplicated.",
-					&nbr->router_id);
-			else
+			zlog_info(
+				"Packet[DD] (%s): Neighbor %pI4 packet with %s duplicated.",
+				IS_SET_DD_MS(nbr->dd_flags) ? "Master" : "Slave",
+					inet_ntoa(nbr->router_id),
+				size >= OSPF_LSA_HEADER_SIZE ? "LSAs" : "no LSAs");
 			/* Slave: cause to retransmit the last Database
 			   Description. */
-			{
-				zlog_info(
-					"Packet[DD] [Slave]: Neighbor %pI4 packet duplicated.",
-					&nbr->router_id);
+			if (!(IS_SET_DD_MS(nbr->dd_flags)))
 				ospf_db_desc_resend(nbr);
-			}
+#if 0
+			if (size >= OSPF_LSA_HEADER_SIZE) {
+			/* Master: discards duplicated DD packet. */
+				break;
+			} else
+				/* Continue processing rest of packet. */
+				ospf_db_desc_proc(s, oi, nbr, dd, size);
+#endif
 			break;
 		}
 
@@ -1850,6 +1869,8 @@
 				&ospfh->router_id,
 				lookup_msg(ospf_nsm_state_msg, nbr->state,
 					   NULL));
+		if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_nbma)
+			ospf_hello_reset_send(nbr->oi);
 		return;
 	}
 
@@ -2252,6 +2273,8 @@
 				&ospfh->router_id,
 				lookup_msg(ospf_nsm_state_msg, nbr->state,
 					   NULL));
+		if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_nbma)
+			ospf_hello_reset_send(nbr->oi);
 		return;
 	}
 
@@ -3137,6 +3160,22 @@
 		return OSPF_READ_CONTINUE;
 	}
 
+	/* Register nbma for unconfigured nbma  */
+	if (iph->ip_dst.s_addr != htonl(OSPF_ALLDROUTERS)
+	    && (oi->type == OSPF_IFTYPE_NBMA)) {
+		struct ospf_neighbor *nbr;
+
+		nbr = ospf_nbr_lookup(oi, iph, ospfh);
+		if (nbr && !nbr->nbr_nbma) {
+			if (IS_DEBUG_OSPF_PACKET(0, RECV))
+				zlog_debug(
+					"ospf_read[%s]: Unconfigured NMBA neighbor, "
+					"configuring.",
+					inet_ntoa(iph->ip_src));
+			(void) ospf_nbr_nbma_set(oi->ospf, iph->ip_src);
+		}
+	}
+
 	/* Verify more OSPF header fields. */
 	ret = ospf_verify_header(ibuf, oi, iph, ospfh);
 	if (ret < 0) {
@@ -3355,7 +3394,7 @@
 
 	/* Add neighbor seen. */
 	for (rn = route_top(oi->nbrs); rn; rn = route_next(rn))
-		if ((nbr = rn->info))
+		if ((nbr = rn->info)) {
 			if (nbr->router_id.s_addr
 			    != INADDR_ANY) /* Ignore 0.0.0.0 node. */
 				if (nbr->state
@@ -3397,6 +3436,7 @@
 									.s_addr);
 							length += 4;
 						}
+		}
 
 	/* Let neighbor generate BackupSeen. */
 	if (flag == 1)
@@ -3771,6 +3811,34 @@
 	return 0;
 }
 
+void ospf_hello_reset_send(struct ospf_interface *oi) {
+	struct ospf_neighbor *nbr;
+	struct route_node *rn;
+
+	if (OSPF_IF_PASSIVE_STATUS(oi) == OSPF_IF_PASSIVE)
+		return;
+
+	if (oi->type != OSPF_IFTYPE_NBMA)
+		return;
+
+	for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
+		if (!(nbr = rn->info))
+			continue;
+		if (nbr == oi->nbr_self)
+			continue;
+		if (nbr->state >= NSM_Exchange)
+			continue;
+		/* Do whatever it takes for the other side to reset the neighbor */
+		nbr->router_id.s_addr = INADDR_ANY;
+		OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_BadLSReq);
+		OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
+		ospf_hello_send_sub(oi, nbr->address.u.prefix4.s_addr);
+		OSPF_ISM_TIMER_MSEC_ON(oi->t_hello, ospf_hello_timer, 1);
+		OSPF_ISM_TIMER_OFF(oi->t_wait);
+		OSPF_ISM_TIMER_ON(oi->t_ls_ack, ospf_ls_ack_timer,oi->v_ls_ack);
+	}
+}
+
 /* Send OSPF Hello. */
 void ospf_hello_send(struct ospf_interface *oi)
 {
--- a/ospfd/ospf_packet.h
+++ b/ospfd/ospf_packet.h
@@ -141,6 +141,7 @@
 
 extern int ospf_read(struct thread *);
 extern void ospf_hello_send(struct ospf_interface *);
+extern void ospf_hello_reset_send(struct ospf_interface *);
 extern void ospf_db_desc_send(struct ospf_neighbor *);
 extern void ospf_db_desc_resend(struct ospf_neighbor *);
 extern void ospf_ls_req_send(struct ospf_neighbor *);
