diff options
author | Joakim Tjernlund <Joakim.Tjernlund@transmode.se> | 2008-09-02 19:06:31 +0100 |
---|---|---|
committer | Paul Jakma <paul@quagga.net> | 2008-09-02 21:38:00 +0100 |
commit | a49eb30a178547189147c8a35bf9e35f429abb66 (patch) | |
tree | 5d660dead08f4a98498240fefb86202000210932 | |
parent | 5d7bdd0ed9595f515bdfaa8af76fcfd41be7a6a6 (diff) |
[ospfd] Restructure opsf_if_update() and ospf_network_run()
Add an struct interface paramenter and adjust the affected
code accordingly.
The old code was a mess looping over all interfaces several times
when one interface was added/changed.
* ospfd/ospfd.h: Add struct interface parameter to ospf_if_update()
* ospfd/ospf_zebra.c: Add ifp arg to ospf_if_update() calls.
(ospf_interface_address_delete) delete ospf_if_update() call,
redundant as function calls ospf_if_free() itself.
* ospfd/ospfd.c: (ospf_network_unset) handle deconfiguration here,
rather than ospf_if_update.
(ospf_network_run_interface) ospf_network_run, for
any given interface.
(ospf_network_run) move guts to previous, and use it.
(ospf_if_update) Adjust to take struct interface as argument, as
all callers have a specific ifp in mind.
Iterate over ifp's connected list and call ospf_network_run_interface
instead of ospf_network_run, turning this path into O(nm) rather
than O(n^2).
Adjust all code dealing with opsf_if_update and ospf_network_run to
pass the new struct interface * arg.
(some minor modifications and bug-additions by Paul Jakma).
Signed-off-by: Paul Jakma <paul@quagga.net>
-rw-r--r-- | ospfd/ospf_zebra.c | 15 | ||||
-rw-r--r-- | ospfd/ospfd.c | 221 | ||||
-rw-r--r-- | ospfd/ospfd.h | 2 |
3 files changed, 117 insertions, 121 deletions
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index f302d28d..e27f1394 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -87,7 +87,6 @@ static int ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length) { struct interface *ifp; - struct ospf *ospf; ifp = zebra_interface_add_read (zclient->ibuf); @@ -103,9 +102,7 @@ ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length) IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp); } - ospf = ospf_lookup (); - if (ospf != NULL) - ospf_if_update (ospf); + ospf_if_update (NULL, ifp); #ifdef HAVE_SNMP ospf_snmp_if_update (ifp); @@ -255,7 +252,6 @@ static int ospf_interface_address_add (int command, struct zclient *zclient, zebra_size_t length) { - struct ospf *ospf; struct connected *c; c = zebra_interface_address_read (command, zclient->ibuf); @@ -270,9 +266,7 @@ ospf_interface_address_add (int command, struct zclient *zclient, zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf); } - ospf = ospf_lookup (); - if (ospf != NULL) - ospf_if_update (ospf); + ospf_if_update (NULL, c->ifp); #ifdef HAVE_SNMP ospf_snmp_if_update (c->ifp); @@ -285,7 +279,6 @@ static int ospf_interface_address_delete (int command, struct zclient *zclient, zebra_size_t length) { - struct ospf *ospf; struct connected *c; struct interface *ifp; struct ospf_interface *oi; @@ -327,10 +320,6 @@ ospf_interface_address_delete (int command, struct zclient *zclient, connected_free (c); - ospf = ospf_lookup (); - if (ospf != NULL) - ospf_if_update (ospf); - return 0; } diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index a4c4fac3..32580ccf 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -68,7 +68,9 @@ extern struct in_addr router_id_zebra; static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *); static void ospf_network_free (struct ospf *, struct ospf_network *); static void ospf_area_free (struct ospf_area *); -static void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *); +static void ospf_network_run (struct prefix *, struct ospf_area *); +static void ospf_network_run_interface (struct prefix *, struct ospf_area *, + struct interface *); static void ospf_finish_final (struct ospf *); #define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1 @@ -78,6 +80,7 @@ ospf_router_id_update (struct ospf *ospf) { struct in_addr router_id, router_id_old; struct ospf_interface *oi; + struct interface *ifp; struct listnode *node; if (IS_DEBUG_OSPF_EVENT) @@ -130,7 +133,8 @@ ospf_router_id_update (struct ospf *ospf) ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY); /* update ospf_interface's */ - ospf_if_update (ospf); + for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp)) + ospf_if_update (ospf, ifp); } } @@ -745,7 +749,7 @@ ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p, area = ospf_area_get (ospf, area_id, ret); /* Run network config now. */ - ospf_network_run (ospf, (struct prefix *)p, area); + ospf_network_run ((struct prefix *)p, area); /* Update connected redistribute. */ if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT)) @@ -770,6 +774,8 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p, struct route_node *rn; struct ospf_network *network; struct external_info *ei; + struct listnode *node, *nnode; + struct ospf_interface *oi; rn = route_node_lookup (ospf->networks, (struct prefix *)p); if (rn == NULL) @@ -783,7 +789,31 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p, rn->info = NULL; route_unlock_node (rn); - ospf_if_update (ospf); + /* Find interfaces that not configured already. */ + for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) + { + int found = 0; + struct connected *co = oi->connected; + + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + continue; + + for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) + { + if (rn->info == NULL) + continue; + + if (ospf_network_match_iface(co,&rn->p)) + { + found = 1; + route_unlock_node (rn); + break; + } + } + + if (found == 0) + ospf_if_free (oi); + } /* Update connected redistribute. */ if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT)) @@ -857,73 +887,78 @@ ospf_network_match_iface(struct connected *co, struct prefix *net) } void -ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area) +ospf_network_run_interface (struct prefix *p, struct ospf_area *area, + struct interface *ifp) { - struct interface *ifp; + struct listnode *cnode; struct connected *co; + + if (memcmp (ifp->name, "VLINK", 5) == 0) + return; + + /* if interface prefix is match specified prefix, + then create socket and join multicast group. */ + for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co)) + { + struct prefix *addr; + + if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY)) + continue; + + addr = CONNECTED_ID(co); + + if (p->family == co->address->family + && ! ospf_if_is_configured (area->ospf, &(addr->u.prefix4)) + && ospf_network_match_iface(co,p)) + { + struct ospf_interface *oi; + + oi = ospf_if_new (area->ospf, ifp, co->address); + oi->connected = co; + + oi->area = area; + + oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4); + oi->output_cost = ospf_if_get_output_cost (oi); + + /* Add pseudo neighbor. */ + ospf_nbr_add_self (oi); + + /* Relate ospf interface to ospf instance. */ + oi->ospf = area->ospf; + + /* update network type as interface flag */ + /* If network type is specified previously, + skip network type setting. */ + oi->type = IF_DEF_PARAMS (ifp)->type; + + ospf_area_add_if (oi->area, oi); + + /* if router_id is not configured, dont bring up + * interfaces. + * ospf_router_id_update() will call ospf_if_update + * whenever r-id is configured instead. + */ + if ((area->ospf->router_id.s_addr != 0) + && if_is_operative (ifp)) + ospf_if_up (oi); + } + } +} + +void +ospf_network_run (struct prefix *p, struct ospf_area *area) +{ + struct interface *ifp; struct listnode *node; /* Schedule Router ID Update. */ - if (ospf->router_id.s_addr == 0) - ospf_router_id_update (ospf); + if (area->ospf->router_id.s_addr == 0) + ospf_router_id_update (area->ospf); /* Get target interface. */ for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp)) - { - struct listnode *cnode; - - if (memcmp (ifp->name, "VLINK", 5) == 0) - continue; - - /* if interface prefix is match specified prefix, - then create socket and join multicast group. */ - for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co)) - { - struct prefix *addr; - - if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY)) - continue; - - addr = CONNECTED_ID(co); - - if (p->family == co->address->family - && ! ospf_if_is_configured (ospf, &(addr->u.prefix4)) - && ospf_network_match_iface(co,p)) - { - struct ospf_interface *oi; - - oi = ospf_if_new (ospf, ifp, co->address); - oi->connected = co; - - oi->area = area; - - oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4); - oi->output_cost = ospf_if_get_output_cost (oi); - - /* Add pseudo neighbor. */ - ospf_nbr_add_self (oi); - - /* Relate ospf interface to ospf instance. */ - oi->ospf = ospf; - - /* update network type as interface flag */ - /* If network type is specified previously, - skip network type setting. */ - oi->type = IF_DEF_PARAMS (ifp)->type; - - ospf_area_add_if (oi->area, oi); - - /* if router_id is not configured, dont bring up - * interfaces. - * ospf_router_id_update() will call ospf_if_update - * whenever r-id is configured instead. - */ - if ((ospf->router_id.s_addr != 0) - && if_is_operative (ifp)) - ospf_if_up (oi); - } - } - } + ospf_network_run_interface (p, area, ifp); } void @@ -954,55 +989,27 @@ ospf_ls_upd_queue_empty (struct ospf_interface *oi) } void -ospf_if_update (struct ospf *ospf) +ospf_if_update (struct ospf *ospf, struct interface *ifp) { struct route_node *rn; - struct listnode *node, *nnode; struct ospf_network *network; struct ospf_area *area; - struct ospf_interface *oi; + + if (!ospf) + ospf = ospf_lookup (); - if (ospf != NULL) - { - /* Router-ID must be configured. */ - if (ospf->router_id.s_addr == 0) - return; - - /* Find interfaces that not configured already. */ - for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) - { - int found = 0; - struct connected *co = oi->connected; - - if (oi->type == OSPF_IFTYPE_VIRTUALLINK) - continue; - - for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) - { - if (rn->info == NULL) - continue; - - if (ospf_network_match_iface(co,&rn->p)) - { - found = 1; - route_unlock_node (rn); - break; - } - } - - if (found == 0) - ospf_if_free (oi); - } - - /* Run each interface. */ - for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) - if (rn->info != NULL) - { - network = (struct ospf_network *) rn->info; - area = ospf_area_get (ospf, network->area_id, network->format); - ospf_network_run (ospf, &rn->p, area); - } - } + /* Router-ID must be configured. */ + if (ospf->router_id.s_addr == 0) + return; + + /* Run each netowrk for this interface. */ + for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) + if (rn->info != NULL) + { + network = (struct ospf_network *) rn->info; + area = ospf_area_get (ospf, network->area_id, network->format); + ospf_network_run_interface (&rn->p, area, ifp); + } } void diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index b6187111..6a60e86f 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -588,7 +588,7 @@ extern int ospf_nbr_nbma_poll_interval_set (struct ospf *, struct in_addr, extern int ospf_nbr_nbma_poll_interval_unset (struct ospf *, struct in_addr); extern void ospf_prefix_list_update (struct prefix_list *); extern void ospf_init (void); -extern void ospf_if_update (struct ospf *); +extern void ospf_if_update (struct ospf *, struct interface *); extern void ospf_ls_upd_queue_empty (struct ospf_interface *); extern void ospf_terminate (void); extern void ospf_nbr_nbma_if_update (struct ospf *, struct ospf_interface *); |