[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>
This commit is contained in:
Joakim Tjernlund 2008-09-02 19:06:31 +01:00 committed by Paul Jakma
parent 5d7bdd0ed9
commit a49eb30a17
3 changed files with 117 additions and 121 deletions

View File

@ -87,7 +87,6 @@ static int
ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length) ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)
{ {
struct interface *ifp; struct interface *ifp;
struct ospf *ospf;
ifp = zebra_interface_add_read (zclient->ibuf); 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); IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp);
} }
ospf = ospf_lookup (); ospf_if_update (NULL, ifp);
if (ospf != NULL)
ospf_if_update (ospf);
#ifdef HAVE_SNMP #ifdef HAVE_SNMP
ospf_snmp_if_update (ifp); ospf_snmp_if_update (ifp);
@ -255,7 +252,6 @@ static int
ospf_interface_address_add (int command, struct zclient *zclient, ospf_interface_address_add (int command, struct zclient *zclient,
zebra_size_t length) zebra_size_t length)
{ {
struct ospf *ospf;
struct connected *c; struct connected *c;
c = zebra_interface_address_read (command, zclient->ibuf); 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); zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf);
} }
ospf = ospf_lookup (); ospf_if_update (NULL, c->ifp);
if (ospf != NULL)
ospf_if_update (ospf);
#ifdef HAVE_SNMP #ifdef HAVE_SNMP
ospf_snmp_if_update (c->ifp); ospf_snmp_if_update (c->ifp);
@ -285,7 +279,6 @@ static int
ospf_interface_address_delete (int command, struct zclient *zclient, ospf_interface_address_delete (int command, struct zclient *zclient,
zebra_size_t length) zebra_size_t length)
{ {
struct ospf *ospf;
struct connected *c; struct connected *c;
struct interface *ifp; struct interface *ifp;
struct ospf_interface *oi; struct ospf_interface *oi;
@ -327,10 +320,6 @@ ospf_interface_address_delete (int command, struct zclient *zclient,
connected_free (c); connected_free (c);
ospf = ospf_lookup ();
if (ospf != NULL)
ospf_if_update (ospf);
return 0; return 0;
} }

View File

@ -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_remove_vls_through_area (struct ospf *, struct ospf_area *);
static void ospf_network_free (struct ospf *, struct ospf_network *); static void ospf_network_free (struct ospf *, struct ospf_network *);
static void ospf_area_free (struct ospf_area *); 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 *); static void ospf_finish_final (struct ospf *);
#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1 #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 in_addr router_id, router_id_old;
struct ospf_interface *oi; struct ospf_interface *oi;
struct interface *ifp;
struct listnode *node; struct listnode *node;
if (IS_DEBUG_OSPF_EVENT) 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); ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);
/* update ospf_interface's */ /* 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); area = ospf_area_get (ospf, area_id, ret);
/* Run network config now. */ /* Run network config now. */
ospf_network_run (ospf, (struct prefix *)p, area); ospf_network_run ((struct prefix *)p, area);
/* Update connected redistribute. */ /* Update connected redistribute. */
if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT)) 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 route_node *rn;
struct ospf_network *network; struct ospf_network *network;
struct external_info *ei; struct external_info *ei;
struct listnode *node, *nnode;
struct ospf_interface *oi;
rn = route_node_lookup (ospf->networks, (struct prefix *)p); rn = route_node_lookup (ospf->networks, (struct prefix *)p);
if (rn == NULL) if (rn == NULL)
@ -783,7 +789,31 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,
rn->info = NULL; rn->info = NULL;
route_unlock_node (rn); 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. */ /* Update connected redistribute. */
if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT)) if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT))
@ -857,23 +887,14 @@ ospf_network_match_iface(struct connected *co, struct prefix *net)
} }
void 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 connected *co;
struct listnode *node;
/* Schedule Router ID Update. */
if (ospf->router_id.s_addr == 0)
ospf_router_id_update (ospf);
/* Get target interface. */
for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp))
{
struct listnode *cnode; struct listnode *cnode;
struct connected *co;
if (memcmp (ifp->name, "VLINK", 5) == 0) if (memcmp (ifp->name, "VLINK", 5) == 0)
continue; return;
/* if interface prefix is match specified prefix, /* if interface prefix is match specified prefix,
then create socket and join multicast group. */ then create socket and join multicast group. */
@ -887,12 +908,12 @@ ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
addr = CONNECTED_ID(co); addr = CONNECTED_ID(co);
if (p->family == co->address->family if (p->family == co->address->family
&& ! ospf_if_is_configured (ospf, &(addr->u.prefix4)) && ! ospf_if_is_configured (area->ospf, &(addr->u.prefix4))
&& ospf_network_match_iface(co,p)) && ospf_network_match_iface(co,p))
{ {
struct ospf_interface *oi; struct ospf_interface *oi;
oi = ospf_if_new (ospf, ifp, co->address); oi = ospf_if_new (area->ospf, ifp, co->address);
oi->connected = co; oi->connected = co;
oi->area = area; oi->area = area;
@ -904,7 +925,7 @@ ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
ospf_nbr_add_self (oi); ospf_nbr_add_self (oi);
/* Relate ospf interface to ospf instance. */ /* Relate ospf interface to ospf instance. */
oi->ospf = ospf; oi->ospf = area->ospf;
/* update network type as interface flag */ /* update network type as interface flag */
/* If network type is specified previously, /* If network type is specified previously,
@ -918,12 +939,26 @@ ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
* ospf_router_id_update() will call ospf_if_update * ospf_router_id_update() will call ospf_if_update
* whenever r-id is configured instead. * whenever r-id is configured instead.
*/ */
if ((ospf->router_id.s_addr != 0) if ((area->ospf->router_id.s_addr != 0)
&& if_is_operative (ifp)) && if_is_operative (ifp))
ospf_if_up (oi); 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 (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))
ospf_network_run_interface (p, area, ifp);
} }
void void
@ -954,54 +989,26 @@ ospf_ls_upd_queue_empty (struct ospf_interface *oi)
} }
void void
ospf_if_update (struct ospf *ospf) ospf_if_update (struct ospf *ospf, struct interface *ifp)
{ {
struct route_node *rn; struct route_node *rn;
struct listnode *node, *nnode;
struct ospf_network *network; struct ospf_network *network;
struct ospf_area *area; struct ospf_area *area;
struct ospf_interface *oi;
if (ospf != NULL) if (!ospf)
{ ospf = ospf_lookup ();
/* Router-ID must be configured. */ /* Router-ID must be configured. */
if (ospf->router_id.s_addr == 0) if (ospf->router_id.s_addr == 0)
return; return;
/* Find interfaces that not configured already. */ /* Run each netowrk for this interface. */
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)) for (rn = route_top (ospf->networks); rn; rn = route_next (rn))
if (rn->info != NULL) if (rn->info != NULL)
{ {
network = (struct ospf_network *) rn->info; network = (struct ospf_network *) rn->info;
area = ospf_area_get (ospf, network->area_id, network->format); area = ospf_area_get (ospf, network->area_id, network->format);
ospf_network_run (ospf, &rn->p, area); ospf_network_run_interface (&rn->p, area, ifp);
}
} }
} }

View File

@ -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 int ospf_nbr_nbma_poll_interval_unset (struct ospf *, struct in_addr);
extern void ospf_prefix_list_update (struct prefix_list *); extern void ospf_prefix_list_update (struct prefix_list *);
extern void ospf_init (void); 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_ls_upd_queue_empty (struct ospf_interface *);
extern void ospf_terminate (void); extern void ospf_terminate (void);
extern void ospf_nbr_nbma_if_update (struct ospf *, struct ospf_interface *); extern void ospf_nbr_nbma_if_update (struct ospf *, struct ospf_interface *);