Browse Source

ospf6d: add p2p interface support

Signed-off-by: Dinesh G Dutt <ddutt at cumulusnetworks.com>
Signed-off-by: Ayan Banerjee <ayabaner at gmail.com>
Reviewed-by: Scott Feldman <sfeldma at cumulusnetworks.com>
Reviewed-by: James Li <jli at cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Dinesh Dutt 6 years ago
parent
commit
c5926a9223
8 changed files with 270 additions and 100 deletions
  1. 4 0
      doc/ospf6d.texi
  2. 10 0
      lib/libospf.h
  3. 2 1
      ospf6d/ospf6_flood.c
  4. 104 1
      ospf6d/ospf6_interface.c
  5. 3 0
      ospf6d/ospf6_interface.h
  6. 6 2
      ospf6d/ospf6_intra.c
  7. 141 88
      ospf6d/ospf6_message.c
  8. 0 8
      ospfd/ospf_interface.h

+ 4 - 0
doc/ospf6d.texi

@@ -98,6 +98,10 @@ Sets interface's Router Priority.  Default value is 1.
 Sets interface's Inf-Trans-Delay.  Default value is 1.
 @end deffn
 
+@deffn {Interface Command} {ipv6 ospf6 network (broadcast|point-to-point)} {}
+Set explicitly network type for specifed interface.
+@end deffn
+
 @node Redistribute routes to OSPF6
 @section Redistribute routes to OSPF6
 

+ 10 - 0
lib/libospf.h

@@ -50,6 +50,16 @@
 #define OSPF_INITIAL_SEQUENCE_NUMBER    0x80000001
 #define OSPF_MAX_SEQUENCE_NUMBER        0x7fffffff
 
+/* OSPF Interface Types */
+#define OSPF_IFTYPE_NONE		0
+#define OSPF_IFTYPE_POINTOPOINT		1
+#define OSPF_IFTYPE_BROADCAST		2
+#define OSPF_IFTYPE_NBMA		3
+#define OSPF_IFTYPE_POINTOMULTIPOINT	4
+#define OSPF_IFTYPE_VIRTUALLINK		5
+#define OSPF_IFTYPE_LOOPBACK            6
+#define OSPF_IFTYPE_MAX			7
+
 /* OSPF interface default values. */
 #define OSPF_OUTPUT_COST_DEFAULT           10
 #define OSPF_OUTPUT_COST_INFINITE	   UINT16_MAX

+ 2 - 1
ospf6d/ospf6_flood.c

@@ -366,7 +366,8 @@ ospf6_flood_interface (struct ospf6_neighbor *from,
   /* (5) flood the LSA out the interface. */
   if (is_debug)
     zlog_debug ("Schedule flooding for the interface");
-  if (if_is_broadcast (oi->interface))
+  if ((oi->type == OSPF_IFTYPE_BROADCAST) ||
+      (oi->type == OSPF_IFTYPE_POINTOPOINT))
     {
       ospf6_lsdb_add (ospf6_lsa_copy (lsa), oi->lsupdate_list);
       if (oi->thread_send_lsupdate == NULL)

+ 104 - 1
ospf6d/ospf6_interface.c

@@ -94,6 +94,17 @@ ospf6_interface_lsdb_hook (struct ospf6_lsa *lsa)
     }
 }
 
+static u_char
+ospf6_default_iftype(struct interface *ifp)
+{
+  if (if_is_pointopoint (ifp))
+    return OSPF_IFTYPE_POINTOPOINT;
+  else if (if_is_loopback (ifp))
+    return OSPF_IFTYPE_LOOPBACK;
+  else
+    return OSPF_IFTYPE_BROADCAST;
+}
+
 /* Create new ospf6 interface structure */
 struct ospf6_interface *
 ospf6_interface_create (struct interface *ifp)
@@ -122,6 +133,7 @@ ospf6_interface_create (struct interface *ifp)
   oi->dead_interval = OSPF_ROUTER_DEAD_INTERVAL_DEFAULT;
   oi->rxmt_interval = OSPF_RETRANSMIT_INTERVAL_DEFAULT;
   oi->cost = OSPF6_INTERFACE_COST;
+  oi->type = ospf6_default_iftype (ifp);
   oi->state = OSPF6_INTERFACE_DOWN;
   oi->flag = 0;
   oi->mtu_ignore = 0;
@@ -407,6 +419,7 @@ ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi)
       (next_state != OSPF6_INTERFACE_DR &&
        next_state != OSPF6_INTERFACE_BDR))
     ospf6_sso (oi->interface->ifindex, &alldrouters6, IPV6_LEAVE_GROUP);
+
   if ((prev_state != OSPF6_INTERFACE_DR &&
        prev_state != OSPF6_INTERFACE_BDR) &&
       (next_state == OSPF6_INTERFACE_DR ||
@@ -640,8 +653,10 @@ interface_up (struct thread *thread)
     thread_add_event (master, ospf6_hello_send, oi, 0);
 
   /* decide next interface state */
-  if (if_is_pointopoint (oi->interface))
+  if ((if_is_pointopoint (oi->interface)) ||
+      (oi->type == OSPF_IFTYPE_POINTOPOINT)) {
     ospf6_interface_state_change (OSPF6_INTERFACE_POINTTOPOINT, oi);
+  }
   else if (oi->priority == 0)
     ospf6_interface_state_change (OSPF6_INTERFACE_DROTHER, oi);
   else
@@ -1522,6 +1537,86 @@ DEFUN (no_ipv6_ospf6_advertise_prefix_list,
   return CMD_SUCCESS;
 }
 
+DEFUN (ipv6_ospf6_network,
+       ipv6_ospf6_network_cmd,
+       "ipv6 ospf6 network (broadcast|point-to-point)",
+       IP6_STR
+       OSPF6_STR
+       "Network Type\n"
+       "Specify OSPFv6 broadcast network\n"
+       "Specify OSPF6 point-to-point network\n"
+       )
+{
+  struct ospf6_interface *oi;
+  struct interface *ifp;
+
+  ifp = (struct interface *) vty->index;
+  assert (ifp);
+
+  oi = (struct ospf6_interface *) ifp->info;
+  if (oi == NULL) {
+    oi = ospf6_interface_create (ifp);
+  }
+  assert (oi);
+
+  if (strncmp (argv[0], "b", 1) == 0)
+    {
+      if (oi->type == OSPF_IFTYPE_BROADCAST)
+	return CMD_SUCCESS;
+
+      oi->type = OSPF_IFTYPE_BROADCAST;
+    }
+    else if (strncmp (argv[0], "point-to-p", 10) == 0)
+      {
+	if (oi->type == OSPF_IFTYPE_POINTOPOINT) {
+	  return CMD_SUCCESS;
+	}
+	oi->type = OSPF_IFTYPE_POINTOPOINT;
+      }
+
+  /* Reset the interface */
+  thread_add_event (master, interface_down, oi, 0);
+  thread_add_event (master, interface_up, oi, 0);
+
+  return CMD_SUCCESS;
+}
+
+DEFUN (no_ipv6_ospf6_network,
+       no_ipv6_ospf6_network_cmd,
+       "no ipv6 ospf6 network",
+       NO_STR
+       IP6_STR
+       OSPF6_STR
+       "Network Type\n"
+       "Default to whatever interface type system specifies"
+       )
+{
+  struct ospf6_interface *oi;
+  struct interface *ifp;
+  int type;
+
+  ifp = (struct interface *) vty->index;
+  assert (ifp);
+
+  oi = (struct ospf6_interface *) ifp->info;
+  if (oi == NULL) {
+    return CMD_SUCCESS;
+  }
+
+  type = ospf6_default_iftype (ifp);
+  if (oi->type == type)
+    {
+      return CMD_SUCCESS;
+    }
+  oi->type = type;
+
+  /* Reset the interface */
+  thread_add_event (master, interface_down, oi, 0);
+  thread_add_event (master, interface_up, oi, 0);
+
+  return CMD_SUCCESS;
+}
+
 static int
 config_write_ospf6_interface (struct vty *vty)
 {
@@ -1581,6 +1676,11 @@ config_write_ospf6_interface (struct vty *vty)
       if (oi->mtu_ignore)
         vty_out (vty, " ipv6 ospf6 mtu-ignore%s", VNL);
 
+      if (oi->type == OSPF_IFTYPE_POINTOPOINT)
+        vty_out (vty, " ipv6 ospf6 network point-to-point%s", VNL);
+      else if (oi->type == OSPF_IFTYPE_BROADCAST)
+	vty_out (vty, " ipv6 ospf6 network broadcast%s", VNL);
+
       vty_out (vty, "!%s", VNL);
     }
   return 0;
@@ -1638,6 +1738,9 @@ ospf6_interface_init (void)
 
   install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
   install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd);
+
+  install_element (INTERFACE_NODE, &ipv6_ospf6_network_cmd);
+  install_element (INTERFACE_NODE, &no_ipv6_ospf6_network_cmd);
 }
 
 DEFUN (debug_ospf6_interface,

+ 3 - 0
ospf6d/ospf6_interface.h

@@ -56,6 +56,9 @@ struct ospf6_interface
   /* I/F transmission delay */
   u_int32_t transdelay;
 
+  /* Network Type */
+  u_char type;
+
   /* Router Priority */
   u_char priority;
 

+ 6 - 2
ospf6d/ospf6_intra.c

@@ -215,7 +215,7 @@ ospf6_router_lsa_originate (struct thread *thread)
         }
 
       /* Point-to-Point interfaces */
-      if (if_is_pointopoint (oi->interface))
+      if (oi->type == OSPF_IFTYPE_POINTOPOINT)
         {
           for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, j, on))
             {
@@ -233,7 +233,7 @@ ospf6_router_lsa_originate (struct thread *thread)
         }
 
       /* Broadcast and NBMA interfaces */
-      if (if_is_broadcast (oi->interface))
+      else if (oi->type == OSPF_IFTYPE_BROADCAST)
         {
           /* If this router is not DR,
              and If this router not fully adjacent with DR,
@@ -261,6 +261,10 @@ ospf6_router_lsa_originate (struct thread *thread)
 
           lsdesc++;
         }
+      else
+	{
+	  assert (0);		/* Unknown interface type */
+	}
 
       /* Virtual links */
         /* xxx */

+ 141 - 88
ospf6d/ospf6_message.c

@@ -1785,6 +1785,7 @@ ospf6_dbdesc_send (struct thread *thread)
   struct ospf6_dbdesc *dbdesc;
   u_char *p;
   struct ospf6_lsa *lsa;
+  struct in6_addr *dst;
 
   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
   on->thread_send_dbdesc = (struct thread *) NULL;
@@ -1848,8 +1849,14 @@ ospf6_dbdesc_send (struct thread *thread)
   oh->type = OSPF6_MESSAGE_TYPE_DBDESC;
   oh->length = htons (p - sendbuf);
 
-  ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
-              on->ospf6_if, oh);
+
+  if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
+    dst = &allspfrouters6;
+  else
+    dst = &on->linklocal_addr;
+
+  ospf6_send (on->ospf6_if->linklocal_addr, dst, on->ospf6_if, oh);
+
   return 0;
 }
 
@@ -1952,8 +1959,13 @@ ospf6_lsreq_send (struct thread *thread)
   oh->type = OSPF6_MESSAGE_TYPE_LSREQ;
   oh->length = htons (p - sendbuf);
 
-  ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
+  if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
+    ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
               on->ospf6_if, oh);
+  else
+    ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
+		on->ospf6_if, oh);
+
   return 0;
 }
 
@@ -1964,7 +1976,7 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
   struct ospf6_header *oh;
   struct ospf6_lsupdate *lsupdate;
   u_char *p;
-  int num;
+  int lsa_cnt;
   struct ospf6_lsa *lsa;
 
   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
@@ -1981,22 +1993,13 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
       return 0;
     }
 
-  /* if we have nothing to send, return */
-  if (on->lsupdate_list->count == 0 &&
-      on->retrans_list->count == 0)
-    {
-      if (IS_OSPF6_DEBUG_MESSAGE (OSPF6_MESSAGE_TYPE_LSUPDATE, SEND))
-        zlog_debug ("Quit to send (nothing to send)");
-      return 0;
-    }
-
   memset (sendbuf, 0, iobuflen);
   oh = (struct ospf6_header *) sendbuf;
   lsupdate = (struct ospf6_lsupdate *)
     ((caddr_t) oh + sizeof (struct ospf6_header));
 
   p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
-  num = 0;
+  lsa_cnt = 0;
 
   /* lsupdate_list lists those LSA which doesn't need to be
      retransmitted. remove those from the list */
@@ -2005,58 +2008,85 @@ ospf6_lsupdate_send_neighbor (struct thread *thread)
     {
       /* MTU check */
       if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
-          > ospf6_packet_max(on->ospf6_if))
-        {
-          ospf6_lsa_unlock (lsa);
-          break;
-        }
+	   > ospf6_packet_max(on->ospf6_if))
+	{
+	  ospf6_lsa_unlock (lsa);
+	  break;
+	}
 
       ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
       memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
       p += OSPF6_LSA_SIZE (lsa->header);
-      num++;
+      lsa_cnt++;
 
       assert (lsa->lock == 2);
       ospf6_lsdb_remove (lsa, on->lsupdate_list);
     }
 
+  if (lsa_cnt)
+    {
+      oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
+      oh->length = htons (p - sendbuf);
+      lsupdate->lsa_number = htonl (lsa_cnt);
+
+      if ((on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT) ||
+	  (on->ospf6_if->state == OSPF6_INTERFACE_DR) ||
+	  (on->ospf6_if->state == OSPF6_INTERFACE_BDR))
+	ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
+		    on->ospf6_if, oh);
+      else
+	ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
+		    on->ospf6_if, oh);
+    }
+
+  /* The addresses used for retransmissions are different from those sent the
+     first time and so we need to separate them here.
+  */
+  memset (sendbuf, 0, iobuflen);
+  oh = (struct ospf6_header *) sendbuf;
+  lsupdate = (struct ospf6_lsupdate *)
+    ((caddr_t) oh + sizeof (struct ospf6_header));
+  p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
+  lsa_cnt = 0;
+
   for (lsa = ospf6_lsdb_head (on->retrans_list); lsa;
        lsa = ospf6_lsdb_next (lsa))
     {
       /* MTU check */
       if ( (p - sendbuf + (unsigned int)OSPF6_LSA_SIZE (lsa->header))
-          > ospf6_packet_max(on->ospf6_if))
-        {
-          ospf6_lsa_unlock (lsa);
-          break;
-        }
+	   > ospf6_packet_max(on->ospf6_if))
+	{
+	  ospf6_lsa_unlock (lsa);
+	  break;
+	}
 
       ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
       memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
       p += OSPF6_LSA_SIZE (lsa->header);
-      num++;
+      lsa_cnt++;
     }
 
-  lsupdate->lsa_number = htonl (num);
-
-  oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
-  oh->length = htons (p - sendbuf);
-
-  ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
-              on->ospf6_if, oh);
-
-  if (on->lsupdate_list->count != 0 ||
-      on->retrans_list->count != 0)
+  if (lsa_cnt)
     {
-      if (on->lsupdate_list->count != 0)
-        on->thread_send_lsupdate =
-          thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
+      oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
+      oh->length = htons (p - sendbuf);
+      lsupdate->lsa_number = htonl (lsa_cnt);
+
+      if (on->ospf6_if->state == OSPF6_INTERFACE_POINTTOPOINT)
+	ospf6_send (on->ospf6_if->linklocal_addr, &allspfrouters6,
+		    on->ospf6_if, oh);
       else
-        on->thread_send_lsupdate =
-          thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
-                            on->ospf6_if->rxmt_interval);
+	ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
+		    on->ospf6_if, oh);
     }
 
+  if (on->lsupdate_list->count != 0)
+    on->thread_send_lsupdate =
+      thread_add_event (master, ospf6_lsupdate_send_neighbor, on, 0);
+  else if (on->retrans_list->count != 0)
+    on->thread_send_lsupdate =
+      thread_add_timer (master, ospf6_lsupdate_send_neighbor, on,
+			on->ospf6_if->rxmt_interval);
   return 0;
 }
 
@@ -2067,7 +2097,7 @@ ospf6_lsupdate_send_interface (struct thread *thread)
   struct ospf6_header *oh;
   struct ospf6_lsupdate *lsupdate;
   u_char *p;
-  int num;
+  int lsa_cnt;
   struct ospf6_lsa *lsa;
 
   oi = (struct ospf6_interface *) THREAD_ARG (thread);
@@ -2088,41 +2118,46 @@ ospf6_lsupdate_send_interface (struct thread *thread)
   memset (sendbuf, 0, iobuflen);
   oh = (struct ospf6_header *) sendbuf;
   lsupdate = (struct ospf6_lsupdate *)((caddr_t) oh +
-                                       sizeof (struct ospf6_header));
+				       sizeof (struct ospf6_header));
 
   p = (u_char *)((caddr_t) lsupdate + sizeof (struct ospf6_lsupdate));
-  num = 0;
+  lsa_cnt = 0;
 
   for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
        lsa = ospf6_lsdb_next (lsa))
     {
       /* MTU check */
       if ( (p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE (lsa->header)))
-          > ospf6_packet_max(oi))
-        {
-          ospf6_lsa_unlock (lsa);
-          break;
-        }
+	   > ospf6_packet_max(oi))
+	{
+	  ospf6_lsa_unlock (lsa);
+	  break;
+	}
 
       ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
       memcpy (p, lsa->header, OSPF6_LSA_SIZE (lsa->header));
       p += OSPF6_LSA_SIZE (lsa->header);
-      num++;
+      lsa_cnt++;
 
       assert (lsa->lock == 2);
       ospf6_lsdb_remove (lsa, oi->lsupdate_list);
     }
 
-  lsupdate->lsa_number = htonl (num);
+  if (lsa_cnt)
+    {
+      lsupdate->lsa_number = htonl (lsa_cnt);
 
-  oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
-  oh->length = htons (p - sendbuf);
+      oh->type = OSPF6_MESSAGE_TYPE_LSUPDATE;
+      oh->length = htons (p - sendbuf);
 
-  if (oi->state == OSPF6_INTERFACE_DR ||
-      oi->state == OSPF6_INTERFACE_BDR)
-    ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
-  else
-    ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
+      if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) ||
+	  (oi->state == OSPF6_INTERFACE_DR) ||
+	  (oi->state == OSPF6_INTERFACE_BDR))
+	ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
+      else
+	ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
+
+    }
 
   if (oi->lsupdate_list->count > 0)
     {
@@ -2140,6 +2175,7 @@ ospf6_lsack_send_neighbor (struct thread *thread)
   struct ospf6_header *oh;
   u_char *p;
   struct ospf6_lsa *lsa;
+  int lsa_cnt = 0;
 
   on = (struct ospf6_neighbor *) THREAD_ARG (thread);
   on->thread_send_lsack = (struct thread *) NULL;
@@ -2166,16 +2202,16 @@ ospf6_lsack_send_neighbor (struct thread *thread)
     {
       /* MTU check */
       if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(on->ospf6_if))
-        {
-          /* if we run out of packet size/space here,
-             better to try again soon. */
-          THREAD_OFF (on->thread_send_lsack);
-          on->thread_send_lsack =
-            thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
+	{
+	  /* if we run out of packet size/space here,
+	     better to try again soon. */
+	  THREAD_OFF (on->thread_send_lsack);
+	  on->thread_send_lsack =
+	    thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
 
-          ospf6_lsa_unlock (lsa);
-          break;
-        }
+	  ospf6_lsa_unlock (lsa);
+	  break;
+	}
 
       ospf6_lsa_age_update_to_send (lsa, on->ospf6_if->transdelay);
       memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
@@ -2183,13 +2219,24 @@ ospf6_lsack_send_neighbor (struct thread *thread)
 
       assert (lsa->lock == 2);
       ospf6_lsdb_remove (lsa, on->lsack_list);
+      lsa_cnt++;
     }
 
-  oh->type = OSPF6_MESSAGE_TYPE_LSACK;
-  oh->length = htons (p - sendbuf);
+  if (lsa_cnt)
+    {
+      oh->type = OSPF6_MESSAGE_TYPE_LSACK;
+      oh->length = htons (p - sendbuf);
+
+      ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
+		  on->ospf6_if, oh);
+    }
+
+  if (on->thread_send_lsack == NULL && on->lsack_list->count > 0)
+    {
+      on->thread_send_lsack =
+        thread_add_event (master, ospf6_lsack_send_neighbor, on, 0);
+    }
 
-  ospf6_send (on->ospf6_if->linklocal_addr, &on->linklocal_addr,
-              on->ospf6_if, oh);
   return 0;
 }
 
@@ -2200,6 +2247,7 @@ ospf6_lsack_send_interface (struct thread *thread)
   struct ospf6_header *oh;
   u_char *p;
   struct ospf6_lsa *lsa;
+  int lsa_cnt = 0;
 
   oi = (struct ospf6_interface *) THREAD_ARG (thread);
   oi->thread_send_lsack = (struct thread *) NULL;
@@ -2226,16 +2274,16 @@ ospf6_lsack_send_interface (struct thread *thread)
     {
       /* MTU check */
       if (p - sendbuf + sizeof (struct ospf6_lsa_header) > ospf6_packet_max(oi))
-        {
-          /* if we run out of packet size/space here,
-             better to try again soon. */
-          THREAD_OFF (oi->thread_send_lsack);
-          oi->thread_send_lsack =
-            thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
+	{
+	  /* if we run out of packet size/space here,
+	     better to try again soon. */
+	  THREAD_OFF (oi->thread_send_lsack);
+	  oi->thread_send_lsack =
+	    thread_add_event (master, ospf6_lsack_send_interface, oi, 0);
 
-          ospf6_lsa_unlock (lsa);
-          break;
-        }
+	  ospf6_lsa_unlock (lsa);
+	  break;
+	}
 
       ospf6_lsa_age_update_to_send (lsa, oi->transdelay);
       memcpy (p, lsa->header, sizeof (struct ospf6_lsa_header));
@@ -2243,16 +2291,21 @@ ospf6_lsack_send_interface (struct thread *thread)
 
       assert (lsa->lock == 2);
       ospf6_lsdb_remove (lsa, oi->lsack_list);
+      lsa_cnt++;
     }
 
-  oh->type = OSPF6_MESSAGE_TYPE_LSACK;
-  oh->length = htons (p - sendbuf);
+  if (lsa_cnt)
+    {
+      oh->type = OSPF6_MESSAGE_TYPE_LSACK;
+      oh->length = htons (p - sendbuf);
 
-  if (oi->state == OSPF6_INTERFACE_DR ||
-      oi->state == OSPF6_INTERFACE_BDR)
-    ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
-  else
-    ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
+      if ((oi->state == OSPF6_INTERFACE_POINTTOPOINT) ||
+	  (oi->state == OSPF6_INTERFACE_DR) ||
+	  (oi->state == OSPF6_INTERFACE_BDR))
+	ospf6_send (oi->linklocal_addr, &allspfrouters6, oi, oh);
+      else
+	ospf6_send (oi->linklocal_addr, &alldrouters6, oi, oh);
+    }
 
   if (oi->thread_send_lsack == NULL && oi->lsack_list->count > 0)
     {

+ 0 - 8
ospfd/ospf_interface.h

@@ -140,14 +140,6 @@ struct ospf_interface
 
   /* OSPF Network Type. */
   u_char type;
-#define OSPF_IFTYPE_NONE		0
-#define OSPF_IFTYPE_POINTOPOINT		1
-#define OSPF_IFTYPE_BROADCAST		2
-#define OSPF_IFTYPE_NBMA		3
-#define OSPF_IFTYPE_POINTOMULTIPOINT	4
-#define OSPF_IFTYPE_VIRTUALLINK		5
-#define OSPF_IFTYPE_LOOPBACK            6
-#define OSPF_IFTYPE_MAX			7
 
   /* State of Interface State Machine. */
   u_char state;