* 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
*/
#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;
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;
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 *
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;
return range->specifics;
}
-int
+static int
ospf_area_actively_attached (struct ospf_area *area)
{
return area->act_ints;
{
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;
{
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;
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;
}
{
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)
}
/* 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;
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;
}
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;
/* 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);
+ }
}
}
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",
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;
}
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
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;
}
}
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
{
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);
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)
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. */
}
}
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(): "
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))
return 1;
}
-int
+static int
ospf_abr_plist_in_check (struct ospf_area *area, struct ospf_route *or,
struct prefix_ipv4 *p)
{
return 1;
}
-int
+static int
ospf_abr_plist_out_check (struct ospf_area *area, struct ospf_route *or,
struct prefix_ipv4 *p)
{
return 1;
}
-void
+static void
ospf_abr_announce_network (struct ospf *ospf,
struct prefix_ipv4 *p, struct ospf_route *or)
{
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)
{
return 1;
}
-void
+static void
ospf_abr_process_nssa_translates (struct ospf *ospf)
{
/* Scan through all NSSA_LSDB records for all areas;
}
-void
+static void
ospf_abr_process_network_rt (struct ospf *ospf,
struct route_table *rt)
{
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)
{
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");
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); */
}
-void
+static void
ospf_abr_announce_rtr (struct ospf *ospf,
struct prefix_ipv4 *p, struct ospf_route *or)
{
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;
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;
zlog_debug ("ospf_abr_unapprove_translates(): Stop");
}
-void
+static void
ospf_abr_unapprove_summaries (struct ospf *ospf)
{
struct listnode *node;
zlog_debug ("ospf_abr_unapprove_summaries(): Stop");
}
-void
+static void
ospf_abr_prepare_aggregates (struct ospf *ospf)
{
struct listnode *node;
zlog_debug ("ospf_abr_prepare_aggregates(): Stop");
}
-void
+static void
ospf_abr_announce_aggregates (struct ospf *ospf)
{
struct ospf_area *area, *ar;
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; */
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;
zlog_debug ("ospf_abr_announce_stub_defaults(): Stop");
}
-int
+static int
ospf_abr_remove_unapproved_translates_apply (struct ospf *ospf,
struct ospf_lsa *lsa)
{
return 0;
}
-void
+static void
ospf_abr_remove_unapproved_translates (struct ospf *ospf)
{
struct route_node *rn;
zlog_debug ("ospf_abr_remove_unapproved_translates(): Stop");
}
-void
+static void
ospf_abr_remove_unapproved_summaries (struct ospf *ospf)
{
struct listnode *node;
zlog_debug ("ospf_abr_remove_unapproved_summaries(): Stop");
}
-void
+static void
ospf_abr_manage_discard_routes (struct ospf *ospf)
{
struct listnode *node, *nnode;
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);
}
}
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)
zlog_debug ("ospf_abr_task(): Stop");
}
-
-int
+static int
ospf_abr_task_timer (struct thread *thread)
{
struct ospf *ospf = THREAD_ARG (thread);
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);
}