]> git.proxmox.com Git - mirror_frr.git/blobdiff - ospfd/ospf_abr.c
Merge remote-tracking branch 'origin/stable/3.0'
[mirror_frr.git] / ospfd / ospf_abr.c
index b63a803b92afff018ec01969b766bf78adb3456f..06038fed7a33082a152dd783807c694ce98e1c28 100644 (file)
@@ -8,16 +8,15 @@
  * under the terms of the GNU General Public License as published by the
  * Free Software Foundation; either version 2, or (at your option) any
  * later version.
- * 
+ *
  * GNU Zebra is distributed in the hope that it will be useful, but
  * WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING.  If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
 
@@ -50,8 +49,8 @@
 #include "ospfd/ospf_ase.h"
 #include "ospfd/ospf_zebra.h"
 #include "ospfd/ospf_dump.h"
-\f
-struct ospf_area_range *
+
+static struct ospf_area_range *
 ospf_area_range_new (struct prefix_ipv4 *p)
 {
   struct ospf_area_range *range;
@@ -64,13 +63,13 @@ ospf_area_range_new (struct prefix_ipv4 *p)
   return range;
 }
 
-void
+static void
 ospf_area_range_free (struct ospf_area_range *range)
 {
   XFREE (MTYPE_OSPF_AREA_RANGE, range);
 }
 
-void
+static void
 ospf_area_range_add (struct ospf_area *area, struct ospf_area_range *range)
 {
   struct route_node *rn;
@@ -87,24 +86,19 @@ ospf_area_range_add (struct ospf_area *area, struct ospf_area_range *range)
     rn->info = range;
 }
 
-void
-ospf_area_range_delete (struct ospf_area *area, struct ospf_area_range *range)
+static void
+ospf_area_range_delete (struct ospf_area *area, struct route_node *rn)
 {
-  struct route_node *rn;
-  struct prefix_ipv4 p;
+  struct ospf_area_range *range = rn->info;
 
-  p.family = AF_INET;
-  p.prefixlen = range->masklen;
-  p.prefix = range->addr;
+  if (range->specifics != 0)
+    ospf_delete_discard_route (area->ospf->new_table,
+                              (struct prefix_ipv4 *) &rn->p);
 
-  rn = route_node_lookup (area->ranges, (struct prefix *)&p);
-  if (rn)
-    {
-      ospf_area_range_free (rn->info);
-      rn->info = NULL;
-      route_unlock_node (rn);
-      route_unlock_node (rn);
-    }
+  ospf_area_range_free (range);
+  rn->info = NULL;
+  route_unlock_node (rn);
+  route_unlock_node (rn);
 }
 
 struct ospf_area_range *
@@ -156,7 +150,7 @@ ospf_area_range_lookup_next (struct ospf_area *area,
   return NULL;
 }
 
-struct ospf_area_range *
+static struct ospf_area_range *
 ospf_area_range_match (struct ospf_area *area, struct prefix_ipv4 *p)
 {
   struct route_node *node;
@@ -190,7 +184,7 @@ ospf_area_range_active (struct ospf_area_range *range)
   return range->specifics;
 }
 
-int
+static int
 ospf_area_actively_attached (struct ospf_area *area)
 {
   return area->act_ints;
@@ -202,9 +196,8 @@ ospf_area_range_set (struct ospf *ospf, struct in_addr area_id,
 {
   struct ospf_area *area;
   struct ospf_area_range *range;
-  int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
 
-  area = ospf_area_get (ospf, area_id, ret);
+  area = ospf_area_get (ospf, area_id);
   if (area == NULL)
     return 0;
 
@@ -238,13 +231,12 @@ ospf_area_range_cost_set (struct ospf *ospf, struct in_addr area_id,
 {
   struct ospf_area *area;
   struct ospf_area_range *range;
-  int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
 
-  area = ospf_area_get (ospf, area_id, ret);
+  area = ospf_area_get (ospf, area_id);
   if (area == NULL)
     return 0;
 
-  range = ospf_area_range_new (p);
+  range = ospf_area_range_lookup (area, p);
   if (range == NULL)
     return 0;
 
@@ -263,20 +255,20 @@ ospf_area_range_unset (struct ospf *ospf, struct in_addr area_id,
                       struct prefix_ipv4 *p)
 {
   struct ospf_area *area;
-  struct ospf_area_range *range;
+  struct route_node *rn;
 
   area = ospf_area_lookup_by_area_id (ospf, area_id);
   if (area == NULL)
     return 0;
 
-  range = ospf_area_range_lookup (area, p);
-  if (range == NULL)
+  rn = route_node_lookup (area->ranges, (struct prefix*)p);
+  if (rn == NULL)
     return 0;
 
-  if (ospf_area_range_active (range))
+  if (ospf_area_range_active (rn->info))
     ospf_schedule_abr_task (ospf);
 
-  ospf_area_range_delete (area, range);
+  ospf_area_range_delete (area, rn);
 
   return 1;
 }
@@ -287,9 +279,8 @@ ospf_area_range_substitute_set (struct ospf *ospf, struct in_addr area_id,
 {
   struct ospf_area *area;
   struct ospf_area_range *range;
-  int ret = OSPF_AREA_ID_FORMAT_ADDRESS;
 
-  area = ospf_area_get (ospf, area_id, ret);
+  area = ospf_area_get (ospf, area_id);
   range = ospf_area_range_lookup (area, p);
 
   if (range != NULL)
@@ -349,7 +340,7 @@ ospf_act_bb_connection (struct ospf *ospf)
 }
 
 /* Determine whether this router is elected translator or not for area */
-int
+static int
 ospf_abr_nssa_am_elected (struct ospf_area *area)
 {
   struct route_node *rn;
@@ -384,7 +375,7 @@ ospf_abr_nssa_am_elected (struct ospf_area *area)
       if (best == NULL)
        best = &lsa->data->id;
       else
-        if ( IPV4_ADDR_CMP (&best, &lsa->data->id) < 0)
+        if (IPV4_ADDR_CMP (&best->s_addr, &lsa->data->id.s_addr) < 0)
           best = &lsa->data->id;
     }
     
@@ -395,7 +386,7 @@ ospf_abr_nssa_am_elected (struct ospf_area *area)
     if (best == NULL)
       return 1;
     
-    if ( IPV4_ADDR_CMP (&best, &area->ospf->router_id) < 0)
+    if (IPV4_ADDR_CMP (&best->s_addr, &area->ospf->router_id.s_addr) < 0)
       return 1;
     else
       return 0;
@@ -404,72 +395,85 @@ ospf_abr_nssa_am_elected (struct ospf_area *area)
 /* Check NSSA ABR status
  * assumes there are nssa areas
  */
-void 
+static void 
 ospf_abr_nssa_check_status (struct ospf *ospf)
 {
   struct ospf_area *area;
   struct listnode *lnode, *nnode;
-    
+  
   for (ALL_LIST_ELEMENTS (ospf->areas, lnode, nnode, area))
     {
-    
+      u_char old_state = area->NSSATranslatorState;
+
       if (area->external_routing != OSPF_AREA_NSSA)
         continue;
-        
+
       if (IS_DEBUG_OSPF (nssa, NSSA))
         zlog_debug ("ospf_abr_nssa_check_status: "
                     "checking area %s",
                     inet_ntoa (area->area_id));
-      
+
       if (!IS_OSPF_ABR (area->ospf))
         {
           if (IS_DEBUG_OSPF (nssa, NSSA))
-            zlog_debug ("ospf_abr_nssa_check_status: "
-                       "not ABR");
+            zlog_debug ("ospf_abr_nssa_check_status: " 
+                        "not ABR");
           area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
-          continue;
         }
-      
-      switch (area->NSSATranslatorRole)
-        {      
-          case OSPF_NSSA_ROLE_NEVER:
-            /* We never Translate Type-7 LSA. */
-            /* TODO: check previous state and flush? */
-            if (IS_DEBUG_OSPF (nssa, NSSA))
-              zlog_debug ("ospf_abr_nssa_check_status: "
-                         "never translate");
-            area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
-            continue;
-             
-          case OSPF_NSSA_ROLE_ALWAYS:
-            /* We always translate if we are an ABR
-             * TODO: originate new LSAs if state change?
-             * or let the nssa abr task take care of it?
-             */
-            if (IS_DEBUG_OSPF (nssa, NSSA))
-              zlog_debug ("ospf_abr_nssa_check_status: "
-                         "translate always");
-            area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED;
-            continue;
-      
-          case OSPF_NSSA_ROLE_CANDIDATE:
-            /* We are a candidate for Translation */
-            if (ospf_abr_nssa_am_elected (area) > 0 )
-              {
-                area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED;
-                if (IS_DEBUG_OSPF (nssa, NSSA))
-                  zlog_debug ("ospf_abr_nssa_check_status: "
-                              "elected translator");
-               }
-            else
-               {
-                 area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
-                 if (IS_DEBUG_OSPF (nssa, NSSA))
-                   zlog_debug ("ospf_abr_nssa_check_status: "
-                              "not elected");
-               }
-            continue;
-         }
+      else
+        {
+          switch (area->NSSATranslatorRole)
+            {
+            case OSPF_NSSA_ROLE_NEVER:
+              /* We never Translate Type-7 LSA. */
+              /* TODO: check previous state and flush? */
+              if (IS_DEBUG_OSPF (nssa, NSSA))
+                zlog_debug ("ospf_abr_nssa_check_status: "
+                           "never translate");
+              area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
+              break;
+
+            case OSPF_NSSA_ROLE_ALWAYS:
+              /* We always translate if we are an ABR
+               * TODO: originate new LSAs if state change?
+               * or let the nssa abr task take care of it?
+               */
+              if (IS_DEBUG_OSPF (nssa, NSSA))
+                zlog_debug ("ospf_abr_nssa_check_status: "
+                            "translate always");
+              area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED;
+              break;
+
+            case OSPF_NSSA_ROLE_CANDIDATE:
+              /* We are a candidate for Translation */
+              if (ospf_abr_nssa_am_elected (area) > 0)
+                {
+                  area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_ENABLED;
+                  if (IS_DEBUG_OSPF (nssa, NSSA))
+                    zlog_debug ("ospf_abr_nssa_check_status: "
+                                "elected translator");
+                }
+              else
+                {
+                  area->NSSATranslatorState = OSPF_NSSA_TRANSLATE_DISABLED;
+                  if (IS_DEBUG_OSPF (nssa, NSSA))
+                    zlog_debug ("ospf_abr_nssa_check_status: " "not elected");
+                }
+              break;
+            }
+        }
+      /* RFC3101, 3.1:
+       * All NSSA border routers must set the E-bit in the Type-1 router-LSAs
+       * of their directly attached non-stub areas, even when they are not
+       * translating.
+       */
+      if (old_state != area->NSSATranslatorState)
+       {
+          if (old_state == OSPF_NSSA_TRANSLATE_DISABLED)
+           ospf_asbr_status_update (ospf, ++ospf->redistribute);
+         else if (area->NSSATranslatorState == OSPF_NSSA_TRANSLATE_DISABLED)
+           ospf_asbr_status_update (ospf, --ospf->redistribute);
+       }
     }
 }
 
@@ -548,23 +552,30 @@ ospf_check_abr_status (struct ospf *ospf)
 
   if (new_flags != ospf->flags)
     {
-      ospf_spf_calculate_schedule (ospf);
+      ospf_spf_calculate_schedule (ospf, SPF_FLAG_ABR_STATUS_CHANGE);
       if (IS_DEBUG_OSPF_EVENT)
        zlog_debug ("ospf_check_abr_status(): new router flags: %x",new_flags);
       ospf->flags = new_flags;
-      OSPF_TIMER_ON (ospf->t_router_lsa_update,
-                    ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
+      ospf_router_lsa_update (ospf);
     }
 }
 
-void
+static void
 ospf_abr_update_aggregate (struct ospf_area_range *range,
-                           struct ospf_route *or)
+                           struct ospf_route *or, struct ospf_area *area)
 {
   if (IS_DEBUG_OSPF_EVENT)
     zlog_debug ("ospf_abr_update_aggregate(): Start");
 
-  if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC)
+  if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED) &&
+      (range->cost != OSPF_STUB_MAX_METRIC_SUMMARY_COST))
+    {
+      range->cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST;
+      if (IS_DEBUG_OSPF_EVENT)
+        zlog_debug ("ospf_abr_update_aggregate(): use summary max-metric 0x%08x",
+                   range->cost);
+    }
+  else if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC)
     {
       if (IS_DEBUG_OSPF_EVENT)
         zlog_debug ("ospf_abr_update_aggregate(): use configured cost %d",
@@ -575,12 +586,18 @@ ospf_abr_update_aggregate (struct ospf_area_range *range,
   else
     {
       if (range->specifics == 0)
-        range->cost = or->cost; /* 1st time get 1st cost */
+       {
+         if (IS_DEBUG_OSPF_EVENT)
+           zlog_debug ("ospf_abr_update_aggregate(): use or->cost %d",
+                       or->cost);
+
+         range->cost = or->cost; /* 1st time get 1st cost */
+       }
 
       if (or->cost > range->cost)
         {
           if (IS_DEBUG_OSPF_EVENT)
-            zlog_debug ("ospf_abr_update_aggregate(): lowest cost, update");
+            zlog_debug ("ospf_abr_update_aggregate(): update to %d", or->cost);
 
           range->cost = or->cost;
         }
@@ -601,17 +618,8 @@ set_metric (struct ospf_lsa *lsa, u_int32_t metric)
   memcpy(header->metric, mp, 3);
 }
 
-int
-ospf_abr_check_nssa_range (struct prefix_ipv4 *p, u_int32_t cost,
-                                  struct ospf_area *area)
-{
-  /* The Type-7 is tested against the aggregated prefix and forwarded
-       for lsa installation and flooding */
-  return 0;
-}
-
 /* ospf_abr_translate_nssa */
-int
+static int
 ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa)
 {
   /* Incoming Type-7 or later aggregated Type-7 
@@ -689,7 +697,7 @@ ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa)
                zlog_debug ("ospf_abr_translate_nssa(): Could not translate "
                           "Type-7 for %s to Type-5", 
                           inet_ntoa (lsa->data->id));
-               return 1;
+              return 1;
            }
     }
 
@@ -700,7 +708,7 @@ ospf_abr_translate_nssa (struct ospf_area *area, struct ospf_lsa *lsa)
   return 0;
 }
 
-void
+static void
 ospf_abr_translate_nssa_range (struct prefix_ipv4 *p, u_int32_t cost)
 {
   /* The Type-7 is created from the aggregated prefix and forwarded
@@ -713,10 +721,16 @@ ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost,
 {
   struct ospf_lsa *lsa, *old = NULL;
   struct summary_lsa *sl = NULL;
+  u_int32_t full_cost;
 
   if (IS_DEBUG_OSPF_EVENT)
     zlog_debug ("ospf_abr_announce_network_to_area(): Start");
 
+  if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
+    full_cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST;
+  else
+    full_cost = cost;
+
   old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA, 
                                    (struct prefix_ipv4 *) p,
                                    area->ospf->router_id);
@@ -731,8 +745,9 @@ ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost,
         zlog_debug ("ospf_abr_announce_network_to_area(): "
                   "old metric: %d, new metric: %d",
                GET_METRIC (sl->metric), cost);
-               
-      if (GET_METRIC (sl->metric) == cost)
+
+      if ((GET_METRIC (sl->metric) == full_cost) &&
+         ((old->flags & OSPF_LSA_IN_MAXAGE) == 0))
         {
           /* unchanged. simply reapprove it */
           if (IS_DEBUG_OSPF_EVENT)
@@ -746,9 +761,22 @@ ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost,
           if (IS_DEBUG_OSPF_EVENT)
             zlog_debug ("ospf_abr_announce_network_to_area(): "
                        "refreshing summary");
-          set_metric (old, cost);
-          lsa = ospf_summary_lsa_refresh (area->ospf, old);
-          SET_FLAG (old->flags, OSPF_LSA_APPROVED);
+          set_metric (old, full_cost);
+          lsa = ospf_lsa_refresh (area->ospf, old);
+          
+          if (!lsa)
+            {
+             char buf[PREFIX2STR_BUFFER];
+             
+             prefix2str ((struct prefix *) p, buf, sizeof(buf));
+             zlog_warn ("%s: Could not refresh %s to %s",
+                        __func__,
+                        buf,
+                        inet_ntoa (area->area_id));
+             return;
+           }
+         
+          SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
           /* This will flood through area. */
         }
     }
@@ -757,9 +785,21 @@ ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost,
       if (IS_DEBUG_OSPF_EVENT)
         zlog_debug ("ospf_abr_announce_network_to_area(): "
                   "creating new summary");
-      lsa = ospf_summary_lsa_originate ( (struct prefix_ipv4 *)p, cost, area);
+      lsa = ospf_summary_lsa_originate ( (struct prefix_ipv4 *)p, full_cost, area);
           /* This will flood through area. */
       
+      if (!lsa)
+       {
+         char buf[PREFIX2STR_BUFFER];
+         
+         prefix2str ((struct prefix *)p, buf, sizeof(buf));
+         zlog_warn ("%s: Could not originate %s to %s",
+                    __func__,
+                    buf,
+                    inet_ntoa (area->area_id));
+         return;
+       }
+      
       SET_FLAG (lsa->flags, OSPF_LSA_APPROVED);
       if (IS_DEBUG_OSPF_EVENT)
         zlog_debug ("ospf_abr_announce_network_to_area(): "
@@ -770,26 +810,23 @@ ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost,
     zlog_debug ("ospf_abr_announce_network_to_area(): Stop");
 }
 
-int
+static int
 ospf_abr_nexthops_belong_to_area (struct ospf_route *or,
                                  struct ospf_area *area)
 {
   struct listnode *node, *nnode;
   struct ospf_path *path;
+  struct ospf_interface *oi;
 
-  for (ALL_LIST_ELEMENTS (or->paths, node, nnode, path))
-    {
-      struct ospf_interface *oi = path->oi;
-
-      if (oi != NULL)
-        if (oi->area == area)
-          return 1;
-    }
+  for (ALL_LIST_ELEMENTS_RO (or->paths, node, path))
+    for (ALL_LIST_ELEMENTS_RO (area->oiflist, nnode, oi))
+      if (oi->ifp && oi->ifp->ifindex == path->ifindex)
+       return 1;
 
   return 0;
 }
 
-int
+static int
 ospf_abr_should_accept (struct prefix_ipv4 *p, struct ospf_area *area)
 {
   if (IMPORT_NAME (area))
@@ -805,7 +842,7 @@ ospf_abr_should_accept (struct prefix_ipv4 *p, struct ospf_area *area)
  return 1;
 }
 
-int
+static int
 ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or,
                         struct prefix_ipv4 *p)
 {
@@ -821,7 +858,7 @@ ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or,
   return 1;
 }
 
-int
+static int
 ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or,
                          struct prefix_ipv4 *p)
 {
@@ -837,7 +874,7 @@ ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or,
   return 1;
 }
 
-void
+static void
 ospf_abr_announce_network (struct ospf *ospf,
                           struct prefix_ipv4 *p, struct ospf_route *or)
 {
@@ -907,16 +944,16 @@ ospf_abr_announce_network (struct ospf *ospf,
             zlog_debug ("ospf_abr_announce_network(): "
                        "this is intra-area route to %s/%d",
                        inet_ntoa (p->prefix), p->prefixlen);
-            if ((range = ospf_area_range_match (or_area, p)) 
-                 && !ospf_area_is_transit (area))
-              ospf_abr_update_aggregate (range, or);
-            else
-              ospf_abr_announce_network_to_area (p, or->cost, area);
+          if ((range = ospf_area_range_match (or_area, p)) 
+              && !ospf_area_is_transit (area))
+            ospf_abr_update_aggregate (range, or, area);
+          else
+            ospf_abr_announce_network_to_area (p, or->cost, area);
         }
     }
 }
 
-int
+static int
 ospf_abr_should_announce (struct ospf *ospf,
                          struct prefix_ipv4 *p, struct ospf_route *or)
 {
@@ -939,7 +976,7 @@ ospf_abr_should_announce (struct ospf *ospf,
   return 1;
 }
 
-void
+static void
 ospf_abr_process_nssa_translates (struct ospf *ospf)
 {
   /* Scan through all NSSA_LSDB records for all areas;
@@ -977,7 +1014,7 @@ ospf_abr_process_nssa_translates (struct ospf *ospf)
 
 }
 
-void
+static void
 ospf_abr_process_network_rt (struct ospf *ospf,
                             struct route_table *rt)
 {
@@ -1075,7 +1112,7 @@ ospf_abr_process_network_rt (struct ospf *ospf,
     zlog_debug ("ospf_abr_process_network_rt(): Stop");
 }
 
-void
+static void
 ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost,
                               struct ospf_area *area)
 {
@@ -1099,7 +1136,8 @@ ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost,
                   GET_METRIC (slsa->metric), cost);
     }
 
-  if (old && (GET_METRIC (slsa->metric) == cost))
+  if (old && (GET_METRIC (slsa->metric) == cost) &&
+      ((old->flags & OSPF_LSA_IN_MAXAGE) == 0))
     {
       if (IS_DEBUG_OSPF_EVENT)
        zlog_debug ("ospf_abr_announce_rtr_to_area(): old summary approved");
@@ -1113,14 +1151,26 @@ ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost,
       if (old) 
        { 
          set_metric (old, cost);
-         lsa = ospf_summary_asbr_lsa_refresh (area->ospf, old);
+         lsa = ospf_lsa_refresh (area->ospf, old);
        }
       else
        lsa = ospf_summary_asbr_lsa_originate (p, cost, area);
-
+      if (!lsa)
+        {
+          char buf[PREFIX2STR_BUFFER];
+          
+          prefix2str ((struct prefix *)p, buf, sizeof(buf));
+          zlog_warn ("%s: Could not refresh/originate %s to %s",
+                     __func__,
+                     buf,
+                     inet_ntoa (area->area_id));
+          return;
+        }
+      
       if (IS_DEBUG_OSPF_EVENT)
        zlog_debug ("ospf_abr_announce_rtr_to_area(): "
                   "flooding new version of summary");
+
       /*
       zlog_info ("ospf_abr_announce_rtr_to_area(): creating new summary");
       lsa = ospf_summary_asbr_lsa (p, cost, area, old); */
@@ -1134,7 +1184,7 @@ ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost,
 }
 
 
-void
+static void
 ospf_abr_announce_rtr (struct ospf *ospf,
                       struct prefix_ipv4 *p, struct ospf_route *or)
 {
@@ -1187,7 +1237,7 @@ ospf_abr_announce_rtr (struct ospf *ospf,
     zlog_debug ("ospf_abr_announce_rtr(): Stop");
 }
 
-void
+static void
 ospf_abr_process_router_rt (struct ospf *ospf, struct route_table *rt)
 {
   struct ospf_route *or;
@@ -1287,7 +1337,7 @@ ospf_abr_process_router_rt (struct ospf *ospf, struct route_table *rt)
     zlog_debug ("ospf_abr_process_router_rt(): Stop");
 }
 
-void
+static void
 ospf_abr_unapprove_translates (struct ospf *ospf) /* For NSSA Translations */
 {
   struct ospf_lsa *lsa;
@@ -1313,7 +1363,7 @@ ospf_abr_unapprove_translates (struct ospf *ospf) /* For NSSA Translations */
     zlog_debug ("ospf_abr_unapprove_translates(): Stop");
 }
 
-void
+static void
 ospf_abr_unapprove_summaries (struct ospf *ospf)
 {
   struct listnode *node;
@@ -1355,7 +1405,7 @@ ospf_abr_unapprove_summaries (struct ospf *ospf)
     zlog_debug ("ospf_abr_unapprove_summaries(): Stop");
 }
 
-void
+static void
 ospf_abr_prepare_aggregates (struct ospf *ospf)
 {
   struct listnode *node;
@@ -1380,7 +1430,7 @@ ospf_abr_prepare_aggregates (struct ospf *ospf)
     zlog_debug ("ospf_abr_prepare_aggregates(): Stop");
 }
 
-void
+static void
 ospf_abr_announce_aggregates (struct ospf *ospf)
 {
   struct ospf_area *area, *ar;
@@ -1461,7 +1511,7 @@ ospf_abr_announce_aggregates (struct ospf *ospf)
     zlog_debug ("ospf_abr_announce_aggregates(): Stop");
 }
 
-void
+static void
 ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */
 {
   struct listnode *node; /*, n; */
@@ -1530,43 +1580,7 @@ ospf_abr_send_nssa_aggregates (struct ospf *ospf) /* temporarily turned off */
     zlog_debug ("ospf_abr_send_nssa_aggregates(): Stop");
 }
 
-void
-ospf_abr_announce_nssa_defaults (struct ospf *ospf) /* By ABR-Translator */
-{
-  struct listnode *node;
-  struct ospf_area *area;
-
-  if (! IS_OSPF_ABR (ospf))
-    return;
-
-  if (IS_DEBUG_OSPF_NSSA)
-    zlog_debug ("ospf_abr_announce_stub_defaults(): Start");
-
-  for (ALL_LIST_ELEMENTS_RO (ospf->areas, node, area))
-    {
-      if (IS_DEBUG_OSPF_NSSA)
-        zlog_debug ("ospf_abr_announce_nssa_defaults(): looking at area %s",
-                   inet_ntoa (area->area_id));
-
-      if (area->external_routing != OSPF_AREA_NSSA)
-        continue;
-
-      if (OSPF_IS_AREA_BACKBONE (area))
-        continue; /* Sanity Check */
-
-      /* if (!TranslatorRole continue V 1.0 look for "always" conf */
-      if (area->NSSATranslatorState)
-        {
-          if (IS_DEBUG_OSPF_NSSA)
-            zlog_debug ("ospf_abr_announce_nssa_defaults(): "
-                       "announcing 0.0.0.0/0 to this nssa");
-          /* ospf_abr_announce_nssa_asbr_to_as (&p, area->default_cost, area); */
-          /*ospf_abr_announce_network_to_area (&p, area->default_cost, area);*/
-        }
-    }
-}
-
-void
+static void
 ospf_abr_announce_stub_defaults (struct ospf *ospf)
 {
   struct listnode *node;
@@ -1608,7 +1622,7 @@ ospf_abr_announce_stub_defaults (struct ospf *ospf)
     zlog_debug ("ospf_abr_announce_stub_defaults(): Stop");
 }
 
-int
+static int
 ospf_abr_remove_unapproved_translates_apply (struct ospf *ospf,
                                             struct ospf_lsa *lsa)
 {
@@ -1627,7 +1641,7 @@ ospf_abr_remove_unapproved_translates_apply (struct ospf *ospf,
   return 0;
 }
 
-void
+static void
 ospf_abr_remove_unapproved_translates (struct ospf *ospf)
 {
   struct route_node *rn;
@@ -1645,7 +1659,7 @@ ospf_abr_remove_unapproved_translates (struct ospf *ospf)
     zlog_debug ("ospf_abr_remove_unapproved_translates(): Stop");
 }
 
-void
+static void
 ospf_abr_remove_unapproved_summaries (struct ospf *ospf)
 {
   struct listnode *node;
@@ -1677,7 +1691,7 @@ ospf_abr_remove_unapproved_summaries (struct ospf *ospf)
     zlog_debug ("ospf_abr_remove_unapproved_summaries(): Stop");
 }
 
-void
+static void
 ospf_abr_manage_discard_routes (struct ospf *ospf)
 {
   struct listnode *node, *nnode;
@@ -1694,7 +1708,8 @@ ospf_abr_manage_discard_routes (struct ospf *ospf)
              ospf_add_discard_route (ospf->new_table, area,
                                      (struct prefix_ipv4 *) &rn->p);
            else
-             ospf_delete_discard_route ((struct prefix_ipv4 *) &rn->p);
+             ospf_delete_discard_route (ospf->new_table,
+                                        (struct prefix_ipv4 *) &rn->p);
          }
 }
 
@@ -1723,7 +1738,7 @@ ospf_abr_manage_discard_routes (struct ospf *ospf)
    For External Calculations, any NSSA areas use the Type-7 AREA-LSDB,
    any ABR-non-NSSA areas use the Type-5 GLOBAL-LSDB. */
 
-void
+static void
 ospf_abr_nssa_task (struct ospf *ospf) /* called only if any_nssa */
 {
   if (IS_DEBUG_OSPF_NSSA)
@@ -1837,8 +1852,7 @@ ospf_abr_task (struct ospf *ospf)
     zlog_debug ("ospf_abr_task(): Stop");
 }
 
-
-int
+static int
 ospf_abr_task_timer (struct thread *thread)
 {
   struct ospf *ospf = THREAD_ARG (thread);
@@ -1863,7 +1877,6 @@ ospf_schedule_abr_task (struct ospf *ospf)
   if (IS_DEBUG_OSPF_EVENT)
     zlog_debug ("Scheduling ABR task");
 
-  if (ospf->t_abr_task == NULL)
-    ospf->t_abr_task = thread_add_timer (master, ospf_abr_task_timer,
-                                        ospf, OSPF_ABR_TASK_DELAY);
+  thread_add_timer(master, ospf_abr_task_timer, ospf, OSPF_ABR_TASK_DELAY,
+                   &ospf->t_abr_task);
 }