diff options
Diffstat (limited to 'ospfd/ospf_ase.c')
-rw-r--r-- | ospfd/ospf_ase.c | 104 |
1 files changed, 59 insertions, 45 deletions
diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index 5d0cae42..c06f0178 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -31,6 +31,7 @@ #include "table.h" #include "vty.h" #include "log.h" +#include "workqueue.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_interface.h" @@ -130,18 +131,6 @@ ospf_find_asbr_route_through_area (struct route_table *rtrs, return NULL; } -static void -ospf_ase_complete_direct_routes (struct ospf_route *ro, struct in_addr nexthop) -{ - struct listnode *node; - struct ospf_path *op; - struct interface *ifp; - - for (ALL_LIST_ELEMENTS_RO (ro->paths, node, op)) - if (op->nexthop.s_addr == 0) - op->nexthop.s_addr = nexthop.s_addr; -} - static int ospf_ase_forward_address_check (struct ospf *ospf, struct in_addr fwd_addr) { @@ -284,8 +273,8 @@ ospf_ase_calculate_new_route (struct ospf_lsa *lsa, #define OSPF_ASE_CALC_INTERVAL 1 -int -ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa * lsa) +static int +ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa *lsa) { u_int32_t metric; struct as_external_lsa *al; @@ -451,8 +440,8 @@ ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa * lsa) /* if there is a Intra/Inter area route to the N do not install external route */ - if (rn = route_node_lookup (ospf->new_table, - (struct prefix *) &p)) + if ((rn = route_node_lookup (ospf->new_table, + (struct prefix *) &p))) { route_unlock_node(rn); if (rn->info == NULL) @@ -463,8 +452,8 @@ ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa * lsa) } /* Find a route to the same dest */ /* If there is no route, create new one. */ - if (rn = route_node_lookup (ospf->new_external_route, - (struct prefix *) &p)) + if ((rn = route_node_lookup (ospf->new_external_route, + (struct prefix *) &p))) route_unlock_node(rn); if (!rn || (or = rn->info) == NULL) @@ -475,8 +464,6 @@ ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa * lsa) ospf_route_add (ospf->new_external_route, &p, new, asbr_route); - if (al->e[0].fwd_addr.s_addr) - ospf_ase_complete_direct_routes (new, al->e[0].fwd_addr); return 0; } else @@ -513,8 +500,7 @@ ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa * lsa) if (IS_DEBUG_OSPF (lsa, LSA)) zlog_debug ("Route[External]: New route is better"); ospf_route_subst (rn, new, asbr_route); - if (al->e[0].fwd_addr.s_addr) - ospf_ase_complete_direct_routes (new, al->e[0].fwd_addr); + or = new; new = NULL; } @@ -531,8 +517,6 @@ ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa * lsa) if (IS_DEBUG_OSPF (lsa, LSA)) zlog_debug ("Route[External]: Routes are equal"); ospf_route_copy_nexthops (or, asbr_route->paths); - if (al->e[0].fwd_addr.s_addr) - ospf_ase_complete_direct_routes (or, al->e[0].fwd_addr); } } /* Make sure setting newly calculated ASBR route.*/ @@ -629,6 +613,50 @@ ospf_ase_compare_tables (struct route_table *new_external_route, return 0; } +static int ospf_ase_calculate_timer (struct thread *); + +static void ospf_ase_calc_completion (struct work_queue *wq) +{ + struct ospf *ospf = wq->spec.data; + + /* Compare old and new external routing table and install the + difference info zebra/kernel */ + ospf_ase_compare_tables (ospf->new_external_route, + ospf->old_external_route); + + /* Delete old external routing table */ + ospf_route_table_free (ospf->old_external_route); + ospf->old_external_route = ospf->new_external_route; + ospf->new_external_route = route_table_init (); + + /* another timer fired since, so another run might be needed */ + if (ospf->ase_calc && !ospf->t_ase_calc) + ospf->t_ase_calc = thread_add_timer (master, ospf_ase_calculate_timer, + ospf, 0); +} + +static wq_item_status +ospf_ase_calc_process (struct work_queue *wq, void *data) +{ + struct ospf_lsa *lsa = data; + ospf_ase_calculate_route (wq->spec.data, lsa); + ospf_lsa_unlock (&lsa); + return WQ_SUCCESS; +} + +static void +ospf_ase_calc_queue_init (struct ospf *ospf) +{ + ospf->ase_calc_queue = work_queue_new (master, "ase_calc_queue"); + + ospf->ase_calc_queue->spec.workfunc = &ospf_ase_calc_process; + ospf->ase_calc_queue->spec.completion_func = &ospf_ase_calc_completion; + + ospf->ase_calc_queue->spec.data = ospf; + ospf->ase_calc_queue->spec.max_retries = 0; + ospf->ase_calc_queue->spec.hold = 0; +} + static int ospf_ase_calculate_timer (struct thread *t) { @@ -645,9 +673,12 @@ ospf_ase_calculate_timer (struct thread *t) { ospf->ase_calc = 0; + if (!ospf->ase_calc_queue) + ospf_ase_calc_queue_init (ospf); + /* Calculate external route for each AS-external-LSA */ LSDB_LOOP (EXTERNAL_LSDB (ospf), rn, lsa) - ospf_ase_calculate_route (ospf, lsa); + work_queue_add (ospf->ase_calc_queue, ospf_lsa_lock (lsa)); /* This version simple adds to the table all NSSA areas */ if (ospf->anyNSSA) @@ -659,39 +690,22 @@ ospf_ase_calculate_timer (struct thread *t) if (area->external_routing == OSPF_AREA_NSSA) LSDB_LOOP (NSSA_LSDB (area), rn, lsa) - ospf_ase_calculate_route (ospf, lsa); + work_queue_add (ospf->ase_calc_queue, ospf_lsa_lock (lsa)); } /* kevinm: And add the NSSA routes in ospf_top */ LSDB_LOOP (NSSA_LSDB (ospf),rn,lsa) - ospf_ase_calculate_route(ospf,lsa); - - /* Compare old and new external routing table and install the - difference info zebra/kernel */ - ospf_ase_compare_tables (ospf->new_external_route, - ospf->old_external_route); - - /* Delete old external routing table */ - ospf_route_table_free (ospf->old_external_route); - ospf->old_external_route = ospf->new_external_route; - ospf->new_external_route = route_table_init (); + work_queue_add (ospf->ase_calc_queue, ospf_lsa_lock (lsa)); } return 0; } void -ospf_ase_calculate_schedule (struct ospf *ospf) +ospf_ase_calculate_timer_add (struct ospf *ospf) { if (ospf == NULL) return; ospf->ase_calc = 1; -} - -void -ospf_ase_calculate_timer_add (struct ospf *ospf) -{ - if (ospf == NULL) - return; if (! ospf->t_ase_calc) ospf->t_ase_calc = thread_add_timer (master, ospf_ase_calculate_timer, |