2005-02-08 Andrew J. Schorr <ajschorr@alumni.princeton.edu>

	* ospf_interface.h: Improve passive_interface comment.  Add new
	  multicast_memberships bitmask to struct ospf_interface to track
	  active multicast subscriptions.  Declare new function
	  ospf_if_set_multicast.
	* ospf_interface.c: (ospf_if_set_multicast) New function to configure
	  multicast memberships properly based on the current
	  multicast_memberships status and the current values of the
	  ospf_interface state, type, and passive_interface status.
	  (ospf_if_up) Remove call to ospf_if_add_allspfrouters (this is
	  now handled by ism_change_state's call to ospf_if_set_multicast).
	  (ospf_if_down) Remove call to ospf_if_drop_allspfrouters (now
	  handled by ism_change_state).
	* ospf_ism.c: (ospf_dr_election) Remove logic to join or leave
	  the DRouters multicast group (now handled by ism_change_state's call
	  to ospf_if_set_multicast).
	  (ism_change_state) Add call to ospf_if_set_multicast to change
	  multicast memberships as necessary to reflect the new interface state.
	* ospf_packet.c: (ospf_hello) When a Hello packet is received on a
	  passive interface: 1. Increase the severity of the error message
	  from LOG_INFO to LOG_WARNING; 2. Add more information to the error
	  message (packet destination address and interface address);
	  and 3. If the packet was sent to ospf-all-routers, then try
	  to fix the multicast group memberships.
	  (ospf_read) When a packet is received on an interface whose state
	  is ISM_Down, enhance the warning message to show the packet
	  destination address, and try to update/fix the multicast group
	  memberships if the packet was sent to a multicast address.
	  When a packet is received for ospf-designated-routers, but the
	  current interface state is not DR or BDR, then increase the
	  severity level of the error message from LOG_INFO to LOG_WARNING,
	  and try to fix the multicast group memberships.
	* ospf_vty.c: (ospf_passive_interface) Call ospf_if_set_multicast for
	  any ospf interface that may have changed from active to passive.
	  (no_ospf_passive_interface) Call ospf_if_set_multicast for
	  any ospf interface that may have changed from passive to active.
	  (show_ip_ospf_interface_sub) Show multicast group memberships.
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index 341c31b..4700329 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -774,8 +774,19 @@
 
   /* If incoming interface is passive one, ignore Hello. */
   if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) {
-    zlog_info ("Packet %s [HELLO:RECV]: oi is passive",
-               inet_ntoa (ospfh->router_id));
+    char buf[3][INET_ADDRSTRLEN];
+    zlog_warn("Warning: ignoring HELLO from router %s sent to %s; we "
+	      "should not receive hellos on passive interface %s!",
+	      inet_ntop(AF_INET, &ospfh->router_id, buf[0], sizeof(buf[0])),
+	      inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
+	      inet_ntop(AF_INET, &oi->address->u.prefix4,
+	      		buf[2], sizeof(buf[2])));
+    if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
+      {
+        /* Try to fix multicast membership. */
+        SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
+        ospf_if_set_multicast(oi);
+      }
     return;
   }
 
@@ -2428,10 +2439,20 @@
     }
   else if (oi->state == ISM_Down)
     {
-      zlog_warn ("Ignoring packet from [%s] received on interface that is "
+      char buf[2][INET_ADDRSTRLEN];
+      zlog_warn ("Ignoring packet from %s to %s received on interface that is "
       		 "down [%s]; interface flags are %s",
-                 inet_ntoa (iph->ip_src), ifp->name, if_flag_dump(ifp->flags));
+		 inet_ntop(AF_INET, &iph->ip_src, buf[0], sizeof(buf[0])),
+		 inet_ntop(AF_INET, &iph->ip_dst, buf[1], sizeof(buf[1])),
+	         ifp->name, if_flag_dump(ifp->flags));
       stream_free (ibuf);
+      /* Fix multicast memberships? */
+      if (iph->ip_dst.s_addr == htonl(OSPF_ALLSPFROUTERS))
+	SET_FLAG(oi->multicast_memberships, MEMBER_ALLROUTERS);
+      else if (iph->ip_dst.s_addr == htonl(OSPF_ALLDROUTERS))
+	SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
+      if (oi->multicast_memberships)
+	ospf_if_set_multicast(oi);
       return 0;
     }
 
@@ -2443,10 +2464,13 @@
   if (iph->ip_dst.s_addr == htonl (OSPF_ALLDROUTERS)
   && (oi->state != ISM_DR && oi->state != ISM_Backup))
     {
-      zlog_info ("Packet for AllDRouters from [%s] via [%s] (ISM: %s)",
+      zlog_warn ("Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
                  inet_ntoa (iph->ip_src), IF_NAME (oi),
                  LOOKUP (ospf_ism_state_msg, oi->state));
       stream_free (ibuf);
+      /* Try to fix multicast membership. */
+      SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
+      ospf_if_set_multicast(oi);
       return 0;
     }