2002-12-13 21:15:29 +01:00
|
|
|
|
/* OSPF SPF calculation.
|
|
|
|
|
Copyright (C) 1999, 2000 Kunihiro Ishiguro, Toshiaki Takada
|
|
|
|
|
|
|
|
|
|
This file is part of GNU Zebra.
|
|
|
|
|
|
|
|
|
|
GNU Zebra is free software; you can redistribute it and/or modify it
|
|
|
|
|
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. */
|
|
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
|
|
#include "thread.h"
|
|
|
|
|
#include "memory.h"
|
|
|
|
|
#include "hash.h"
|
|
|
|
|
#include "linklist.h"
|
|
|
|
|
#include "prefix.h"
|
|
|
|
|
#include "if.h"
|
|
|
|
|
#include "table.h"
|
|
|
|
|
#include "log.h"
|
|
|
|
|
#include "sockunion.h" /* for inet_ntop () */
|
2005-02-23 12:29:02 +01:00
|
|
|
|
#include "pqueue.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
#include "ospfd/ospfd.h"
|
|
|
|
|
#include "ospfd/ospf_interface.h"
|
|
|
|
|
#include "ospfd/ospf_ism.h"
|
|
|
|
|
#include "ospfd/ospf_asbr.h"
|
|
|
|
|
#include "ospfd/ospf_lsa.h"
|
|
|
|
|
#include "ospfd/ospf_lsdb.h"
|
|
|
|
|
#include "ospfd/ospf_neighbor.h"
|
|
|
|
|
#include "ospfd/ospf_nsm.h"
|
|
|
|
|
#include "ospfd/ospf_spf.h"
|
|
|
|
|
#include "ospfd/ospf_route.h"
|
|
|
|
|
#include "ospfd/ospf_ia.h"
|
|
|
|
|
#include "ospfd/ospf_ase.h"
|
|
|
|
|
#include "ospfd/ospf_abr.h"
|
|
|
|
|
#include "ospfd/ospf_dump.h"
|
|
|
|
|
|
2005-02-23 12:29:02 +01:00
|
|
|
|
/* Heap related functions, for the managment of the candidates, to
|
|
|
|
|
* be used with pqueue. */
|
|
|
|
|
static int
|
|
|
|
|
cmp (void * node1 , void * node2)
|
|
|
|
|
{
|
|
|
|
|
struct vertex * v1 = (struct vertex *) node1;
|
|
|
|
|
struct vertex * v2 = (struct vertex *) node2;
|
|
|
|
|
if (v1 != NULL && v2 != NULL )
|
|
|
|
|
return (v1->distance - v2->distance);
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
update_stat (void *node , int position)
|
2005-02-23 12:29:02 +01:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
struct vertex *v = node;
|
|
|
|
|
|
2005-02-23 12:29:02 +01:00
|
|
|
|
/* Set the status of the vertex, when its position changes. */
|
|
|
|
|
*(v->stat) = position;
|
|
|
|
|
}
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static struct vertex_nexthop *
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
vertex_nexthop_new (void)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
return XCALLOC (MTYPE_OSPF_NEXTHOP, sizeof (struct vertex_nexthop));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
|
vertex_nexthop_free (struct vertex_nexthop *nh)
|
|
|
|
|
{
|
|
|
|
|
XFREE (MTYPE_OSPF_NEXTHOP, nh);
|
|
|
|
|
}
|
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
/* Free the canonical nexthop objects for an area, ie the nexthop objects
|
|
|
|
|
* attached to the first-hop router vertices.
|
|
|
|
|
*/
|
|
|
|
|
static void
|
|
|
|
|
ospf_canonical_nexthops_free (struct vertex *root)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
struct listnode *node, *nnode;
|
|
|
|
|
struct vertex *child;
|
|
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS (root->children, node, nnode, child))
|
|
|
|
|
{
|
|
|
|
|
struct listnode *n2, *nn2;
|
|
|
|
|
struct vertex_parent *vp;
|
|
|
|
|
|
|
|
|
|
if (child->type == OSPF_VERTEX_NETWORK)
|
|
|
|
|
ospf_canonical_nexthops_free (child);
|
|
|
|
|
|
|
|
|
|
for (ALL_LIST_ELEMENTS (child->parents, n2, nn2, vp))
|
|
|
|
|
vertex_nexthop_free (vp->nexthop);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct vertex_parent *
|
|
|
|
|
vertex_parent_new (struct vertex *v, int backlink, struct vertex_nexthop *hop)
|
|
|
|
|
{
|
|
|
|
|
struct vertex_parent *new;
|
|
|
|
|
|
|
|
|
|
new = XMALLOC (MTYPE_OSPF_VERTEX_PARENT, sizeof (struct vertex_parent));
|
|
|
|
|
|
|
|
|
|
if (new == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
new->parent = v;
|
|
|
|
|
new->backlink = backlink;
|
|
|
|
|
new->nexthop = hop;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
return new;
|
|
|
|
|
}
|
2003-06-07 01:27:04 +02:00
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
static void
|
|
|
|
|
vertex_parent_free (struct vertex_parent *p)
|
|
|
|
|
{
|
|
|
|
|
XFREE (MTYPE_OSPF_VERTEX_PARENT, p);
|
|
|
|
|
}
|
|
|
|
|
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static struct vertex *
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ospf_vertex_new (struct ospf_lsa *lsa)
|
|
|
|
|
{
|
|
|
|
|
struct vertex *new;
|
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
new = XCALLOC (MTYPE_OSPF_VERTEX, sizeof (struct vertex));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
new->flags = 0;
|
2005-02-23 12:29:02 +01:00
|
|
|
|
new->stat = &(lsa->stat);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
new->type = lsa->data->type;
|
|
|
|
|
new->id = lsa->data->id;
|
|
|
|
|
new->lsa = lsa->data;
|
|
|
|
|
new->distance = 0;
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
new->children = list_new ();
|
|
|
|
|
new->parents = list_new ();
|
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
return new;
|
|
|
|
|
}
|
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
/* Recursively free the given vertex and all its children
|
|
|
|
|
* and associated parent and nexthop information
|
|
|
|
|
* Parent should indicate which parent is trying to free this child,
|
|
|
|
|
* NULL parent is only valid for the root vertex.
|
|
|
|
|
*/
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static void
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
ospf_vertex_free (struct vertex *v, const struct ospf_area *area)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
struct listnode *node, *nnode;
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
struct vertex *vc;
|
|
|
|
|
|
|
|
|
|
assert (*(v->stat) == LSA_SPF_IN_SPFTREE);
|
|
|
|
|
|
|
|
|
|
/* recurse down the tree, freeing furthest children first */
|
|
|
|
|
if (v->children)
|
|
|
|
|
{
|
|
|
|
|
for (ALL_LIST_ELEMENTS (v->children, node, nnode, vc))
|
|
|
|
|
ospf_vertex_free (vc, area);
|
|
|
|
|
|
|
|
|
|
list_delete (v->children);
|
|
|
|
|
v->children = NULL;
|
|
|
|
|
}
|
2005-06-13 15:57:16 +02:00
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
/* The vertex itself can only be freed when the last remaining parent
|
|
|
|
|
* with a reference to this vertex frees this vertex. Until then, we
|
|
|
|
|
* just cleanup /one/ parent association (doesnt matter which) -
|
|
|
|
|
* essentially using the parents list as a refcount.
|
|
|
|
|
*/
|
|
|
|
|
if (listcount (v->parents) > 0)
|
|
|
|
|
{
|
|
|
|
|
vertex_parent_free (listgetdata (listhead (v->parents)));
|
|
|
|
|
list_delete_node (v->parents, listhead (v->parents));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
if (listcount (v->parents) > 0)
|
|
|
|
|
return; /* there are still parent references left */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
list_delete (v->parents);
|
|
|
|
|
v->parents = NULL;
|
|
|
|
|
|
|
|
|
|
v->lsa = NULL;
|
2005-06-13 15:57:16 +02:00
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
XFREE (MTYPE_OSPF_VERTEX, v);
|
|
|
|
|
}
|
|
|
|
|
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static void
|
2004-10-08 10:17:22 +02:00
|
|
|
|
ospf_vertex_dump(const char *msg, struct vertex *v,
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
int print_parents, int print_children)
|
2004-08-31 19:28:41 +02:00
|
|
|
|
{
|
|
|
|
|
if ( ! IS_DEBUG_OSPF_EVENT)
|
|
|
|
|
return;
|
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
zlog_debug("%s %s vertex %s distance %u flags %u",
|
2004-08-31 19:28:41 +02:00
|
|
|
|
msg,
|
|
|
|
|
v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network",
|
|
|
|
|
inet_ntoa(v->lsa->id),
|
|
|
|
|
v->distance,
|
|
|
|
|
(unsigned int)v->flags);
|
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
if (print_parents)
|
2004-08-31 19:28:41 +02:00
|
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
struct listnode *node;
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
struct vertex_parent *vp;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp))
|
2004-08-31 19:28:41 +02:00
|
|
|
|
{
|
|
|
|
|
char buf1[BUFSIZ];
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
|
|
|
|
|
if (vp)
|
2004-08-31 19:28:41 +02:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
zlog_debug ("parent %s backlink %d nexthop %s interface %s",
|
|
|
|
|
inet_ntoa(vp->parent->lsa->id), vp->backlink,
|
|
|
|
|
inet_ntop(AF_INET, &vp->nexthop->router, buf1, BUFSIZ),
|
|
|
|
|
vp->nexthop->oi ? IF_NAME(vp->nexthop->oi) : "NULL");
|
2004-08-31 19:28:41 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (print_children)
|
|
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
|
struct listnode *cnode;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
struct vertex *cv;
|
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
for (ALL_LIST_ELEMENTS_RO (v->children, cnode, cv))
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
ospf_vertex_dump(" child:", cv, 0, 0);
|
2004-08-31 19:28:41 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Add a vertex to the list of children in each of its parents. */
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ospf_vertex_add_parent (struct vertex *v)
|
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
struct vertex_parent *vp;
|
2004-09-23 21:18:23 +02:00
|
|
|
|
struct listnode *node;
|
2005-06-13 15:57:16 +02:00
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
assert (v && v->children);
|
2005-06-13 15:57:16 +02:00
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp))
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
assert (vp->parent && vp->parent->children);
|
2005-06-13 15:57:16 +02:00
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
/* No need to add two links from the same parent. */
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
if (listnode_lookup (vp->parent->children, v) == NULL)
|
|
|
|
|
listnode_add (vp->parent->children, v);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ospf_spf_init (struct ospf_area *area)
|
|
|
|
|
{
|
|
|
|
|
struct vertex *v;
|
|
|
|
|
|
|
|
|
|
/* Create root node. */
|
|
|
|
|
v = ospf_vertex_new (area->router_lsa_self);
|
|
|
|
|
|
|
|
|
|
area->spf = v;
|
|
|
|
|
|
|
|
|
|
/* Reset ABR and ASBR router counts. */
|
|
|
|
|
area->abr_count = 0;
|
|
|
|
|
area->asbr_count = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2004-04-08 09:43:45 +02:00
|
|
|
|
/* return index of link back to V from W, or -1 if no link found */
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static int
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ospf_lsa_has_link (struct lsa_header *w, struct lsa_header *v)
|
|
|
|
|
{
|
2004-10-08 10:17:22 +02:00
|
|
|
|
unsigned int i, length;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
struct router_lsa *rl;
|
|
|
|
|
struct network_lsa *nl;
|
|
|
|
|
|
|
|
|
|
/* In case of W is Network LSA. */
|
|
|
|
|
if (w->type == OSPF_NETWORK_LSA)
|
|
|
|
|
{
|
|
|
|
|
if (v->type == OSPF_NETWORK_LSA)
|
2004-04-08 09:43:45 +02:00
|
|
|
|
return -1;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
nl = (struct network_lsa *) w;
|
|
|
|
|
length = (ntohs (w->length) - OSPF_LSA_HEADER_SIZE - 4) / 4;
|
2003-06-07 01:27:04 +02:00
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
for (i = 0; i < length; i++)
|
|
|
|
|
if (IPV4_ADDR_SAME (&nl->routers[i], &v->id))
|
2004-04-08 09:43:45 +02:00
|
|
|
|
return i;
|
|
|
|
|
return -1;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* In case of W is Router LSA. */
|
|
|
|
|
if (w->type == OSPF_ROUTER_LSA)
|
|
|
|
|
{
|
|
|
|
|
rl = (struct router_lsa *) w;
|
|
|
|
|
|
|
|
|
|
length = ntohs (w->length);
|
|
|
|
|
|
|
|
|
|
for (i = 0;
|
2003-06-07 01:27:04 +02:00
|
|
|
|
i < ntohs (rl->links) && length >= sizeof (struct router_lsa);
|
|
|
|
|
i++, length -= 12)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
|
|
|
|
switch (rl->link[i].type)
|
|
|
|
|
{
|
|
|
|
|
case LSA_LINK_TYPE_POINTOPOINT:
|
|
|
|
|
case LSA_LINK_TYPE_VIRTUALLINK:
|
|
|
|
|
/* Router LSA ID. */
|
|
|
|
|
if (v->type == OSPF_ROUTER_LSA &&
|
|
|
|
|
IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id))
|
|
|
|
|
{
|
2004-04-08 09:43:45 +02:00
|
|
|
|
return i;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case LSA_LINK_TYPE_TRANSIT:
|
|
|
|
|
/* Network LSA ID. */
|
|
|
|
|
if (v->type == OSPF_NETWORK_LSA &&
|
|
|
|
|
IPV4_ADDR_SAME (&rl->link[i].link_id, &v->id))
|
|
|
|
|
{
|
2004-04-08 09:43:45 +02:00
|
|
|
|
return i;
|
2003-06-07 01:27:04 +02:00
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
break;
|
|
|
|
|
case LSA_LINK_TYPE_STUB:
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
/* Stub can't lead anywhere, carry on */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
continue;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-04-08 09:43:45 +02:00
|
|
|
|
return -1;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define ROUTER_LSA_MIN_SIZE 12
|
|
|
|
|
#define ROUTER_LSA_TOS_SIZE 4
|
|
|
|
|
|
2004-08-31 19:28:41 +02:00
|
|
|
|
/* Find the next link after prev_link from v to w. If prev_link is
|
|
|
|
|
* NULL, return the first link from v to w. Ignore stub and virtual links;
|
|
|
|
|
* these link types will never be returned.
|
|
|
|
|
*/
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static struct router_lsa_link *
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ospf_get_next_link (struct vertex *v, struct vertex *w,
|
2003-06-07 01:27:04 +02:00
|
|
|
|
struct router_lsa_link *prev_link)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
|
|
|
|
u_char *p;
|
|
|
|
|
u_char *lim;
|
|
|
|
|
struct router_lsa_link *l;
|
|
|
|
|
|
|
|
|
|
if (prev_link == NULL)
|
2004-08-31 19:28:41 +02:00
|
|
|
|
p = ((u_char *) v->lsa) + OSPF_LSA_HEADER_SIZE + 4;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
2003-06-07 01:27:04 +02:00
|
|
|
|
p = (u_char *) prev_link;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
p += (ROUTER_LSA_MIN_SIZE +
|
|
|
|
|
(prev_link->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
|
|
|
|
|
}
|
2003-06-07 01:27:04 +02:00
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
lim = ((u_char *) v->lsa) + ntohs (v->lsa->length);
|
|
|
|
|
|
|
|
|
|
while (p < lim)
|
|
|
|
|
{
|
|
|
|
|
l = (struct router_lsa_link *) p;
|
|
|
|
|
|
2003-06-07 01:27:04 +02:00
|
|
|
|
p += (ROUTER_LSA_MIN_SIZE + (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
if (l->m[0].type == LSA_LINK_TYPE_STUB)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* Defer NH calculation via VLs until summaries from
|
|
|
|
|
transit areas area confidered */
|
|
|
|
|
|
|
|
|
|
if (l->m[0].type == LSA_LINK_TYPE_VIRTUALLINK)
|
2003-06-07 01:27:04 +02:00
|
|
|
|
continue;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
if (IPV4_ADDR_SAME (&l->link_id, &w->id))
|
2003-06-07 01:27:04 +02:00
|
|
|
|
return l;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-05 11:10:31 +02:00
|
|
|
|
/*
|
|
|
|
|
* Consider supplied next-hop for inclusion to the supplied list of
|
|
|
|
|
* equal-cost next-hops, adjust list as neccessary.
|
|
|
|
|
*
|
|
|
|
|
* (Discussed on GNU Zebra list 27 May 2003, [zebra 19184])
|
|
|
|
|
*
|
|
|
|
|
* Note that below is a bit of a hack, and limits ECMP to paths that go to
|
|
|
|
|
* same nexthop. Where as paths via inequal output_cost interfaces could
|
|
|
|
|
* still quite easily be ECMP due to remote cost differences.
|
|
|
|
|
*
|
|
|
|
|
* TODO: It really should be done by way of recording currently valid
|
|
|
|
|
* backlinks and determining the appropriate nexthops from the list of
|
|
|
|
|
* backlinks, or even simpler, just flushing nexthop list if we find a lower
|
|
|
|
|
* cost path to a candidate vertex in SPF, maybe.
|
2003-06-07 01:23:36 +02:00
|
|
|
|
*/
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static void
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
ospf_spf_add_parent (struct vertex *v, struct vertex *w,
|
|
|
|
|
struct vertex_nexthop *newhop)
|
2003-06-07 01:23:36 +02:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
struct vertex_parent *vp;
|
|
|
|
|
|
|
|
|
|
/* we must have a newhop.. */
|
|
|
|
|
assert (v && w && newhop);
|
|
|
|
|
|
|
|
|
|
/* new parent is <= existing parents, add it */
|
|
|
|
|
vp = vertex_parent_new (v, ospf_lsa_has_link (w->lsa, v->lsa), newhop);
|
|
|
|
|
listnode_add (w->parents, vp);
|
2003-06-07 01:27:04 +02:00
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
ospf_spf_flush_parents (struct vertex *w)
|
|
|
|
|
{
|
|
|
|
|
struct vertex_parent *vp;
|
|
|
|
|
struct listnode *ln, *nn;
|
|
|
|
|
|
|
|
|
|
/* delete the existing nexthops */
|
|
|
|
|
for (ALL_LIST_ELEMENTS (w->parents, ln, nn, vp))
|
2004-08-05 11:10:31 +02:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
list_delete_node (w->parents, ln);
|
|
|
|
|
vertex_parent_free (vp);
|
2004-08-05 11:10:31 +02:00
|
|
|
|
}
|
2003-06-07 01:23:36 +02:00
|
|
|
|
}
|
|
|
|
|
|
2004-08-31 19:28:41 +02:00
|
|
|
|
/* 16.1.1. Calculate nexthop from root through V (parent) to
|
|
|
|
|
* vertex W (destination).
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
*
|
|
|
|
|
* The link must be supplied if V is the root vertex. In all other cases
|
|
|
|
|
* it may be NULL.
|
2004-08-31 19:28:41 +02:00
|
|
|
|
*/
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static void
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
ospf_nexthop_calculation (struct ospf_area *area, struct vertex *v,
|
|
|
|
|
struct vertex *w, struct router_lsa_link *l)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
struct listnode *node, *nnode;
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
struct vertex_nexthop *nh;
|
|
|
|
|
struct vertex_parent *vp;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
struct ospf_interface *oi = NULL;
|
2003-06-07 01:27:04 +02:00
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-08-31 19:28:41 +02:00
|
|
|
|
{
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("ospf_nexthop_calculation(): Start");
|
2004-08-31 19:28:41 +02:00
|
|
|
|
ospf_vertex_dump("V (parent):", v, 1, 1);
|
|
|
|
|
ospf_vertex_dump("W (dest) :", w, 1, 1);
|
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
if (v == area->spf)
|
|
|
|
|
{
|
2004-08-31 19:28:41 +02:00
|
|
|
|
/* 16.1.1 para 4. In the first case, the parent vertex (V) is the
|
|
|
|
|
root (the calculating router itself). This means that the
|
|
|
|
|
destination is either a directly connected network or directly
|
|
|
|
|
connected router. The outgoing interface in this case is simply
|
|
|
|
|
the OSPF interface connecting to the destination network/router.
|
|
|
|
|
*/
|
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
if (w->type == OSPF_VERTEX_ROUTER)
|
2003-06-07 01:27:04 +02:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
/* l is a link from v to w
|
|
|
|
|
* l2 will be link from w to v
|
|
|
|
|
*/
|
|
|
|
|
struct router_lsa_link *l2 = NULL;
|
|
|
|
|
|
|
|
|
|
/* we *must* be supplied with the link data */
|
|
|
|
|
assert (l != NULL);
|
|
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2003-06-07 01:27:04 +02:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
char buf1[BUFSIZ];
|
|
|
|
|
char buf2[BUFSIZ];
|
|
|
|
|
|
|
|
|
|
zlog_debug("ospf_nexthop_calculation(): considering link "
|
|
|
|
|
"type %d link_id %s link_data %s",
|
|
|
|
|
l->m[0].type,
|
|
|
|
|
inet_ntop (AF_INET, &l->link_id, buf1, BUFSIZ),
|
|
|
|
|
inet_ntop (AF_INET, &l->link_data, buf2, BUFSIZ));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (l->m[0].type == LSA_LINK_TYPE_POINTOPOINT)
|
|
|
|
|
{
|
|
|
|
|
/* If the destination is a router which connects to
|
|
|
|
|
the calculating router via a Point-to-MultiPoint
|
|
|
|
|
network, the destination's next hop IP address(es)
|
|
|
|
|
can be determined by examining the destination's
|
|
|
|
|
router-LSA: each link pointing back to the
|
|
|
|
|
calculating router and having a Link Data field
|
|
|
|
|
belonging to the Point-to-MultiPoint network
|
|
|
|
|
provides an IP address of the next hop router.
|
|
|
|
|
|
|
|
|
|
At this point l is a link from V to W, and V is the
|
|
|
|
|
root ("us"). Find the local interface associated
|
|
|
|
|
with l (its address is in l->link_data). If it
|
|
|
|
|
is a point-to-multipoint interface, then look through
|
|
|
|
|
the links in the opposite direction (W to V). If
|
|
|
|
|
any of them have an address that lands within the
|
|
|
|
|
subnet declared by the PtMP link, then that link
|
|
|
|
|
is a constituent of the PtMP link, and its address is
|
|
|
|
|
a nexthop address for V.
|
|
|
|
|
*/
|
|
|
|
|
oi = ospf_if_is_configured (area->ospf, &l->link_data);
|
|
|
|
|
if (oi && oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)
|
2003-06-07 01:27:04 +02:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
struct prefix_ipv4 la;
|
|
|
|
|
|
|
|
|
|
la.family = AF_INET;
|
|
|
|
|
la.prefixlen = oi->address->prefixlen;
|
|
|
|
|
|
|
|
|
|
/* V links to W on PtMP interface
|
|
|
|
|
- find the interface address on W */
|
|
|
|
|
while ((l2 = ospf_get_next_link (w, v, l2)))
|
2003-06-07 01:27:04 +02:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
la.prefix = l2->link_data;
|
2003-06-07 01:27:04 +02:00
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
if (prefix_cmp ((struct prefix *) &la,
|
|
|
|
|
oi->address) == 0)
|
|
|
|
|
/* link_data is on our PtMP network */
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} /* end l is on point-to-multipoint link */
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* l is a regular point-to-point link.
|
|
|
|
|
Look for a link from W to V.
|
|
|
|
|
*/
|
|
|
|
|
while ((l2 = ospf_get_next_link (w, v, l2)))
|
2003-06-07 01:27:04 +02:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
oi = ospf_if_is_configured (area->ospf,
|
|
|
|
|
&(l2->link_data));
|
|
|
|
|
|
|
|
|
|
if (oi == NULL)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (!IPV4_ADDR_SAME (&oi->address->u.prefix4,
|
|
|
|
|
&l->link_data))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
break;
|
2003-06-07 01:27:04 +02:00
|
|
|
|
}
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (oi && l2)
|
|
|
|
|
{
|
|
|
|
|
/* found all necessary info to build nexthop */
|
|
|
|
|
nh = vertex_nexthop_new ();
|
|
|
|
|
nh->oi = oi;
|
|
|
|
|
nh->router = l2->link_data;
|
|
|
|
|
ospf_spf_add_parent (v, w, nh);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
zlog_info("ospf_nexthop_calculation(): "
|
|
|
|
|
"could not determine nexthop for link");
|
|
|
|
|
}
|
|
|
|
|
} /* end point-to-point link from V to W */
|
2004-08-31 19:28:41 +02:00
|
|
|
|
} /* end W is a Router vertex */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
else
|
2003-06-07 01:27:04 +02:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
assert(w->type == OSPF_VERTEX_NETWORK);
|
|
|
|
|
oi = ospf_if_is_configured (area->ospf, &(l->link_data));
|
|
|
|
|
if (oi)
|
2003-06-07 01:27:04 +02:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
nh = vertex_nexthop_new ();
|
|
|
|
|
nh->oi = oi;
|
|
|
|
|
nh->router.s_addr = 0;
|
|
|
|
|
ospf_spf_add_parent (v, w, nh);
|
2003-06-07 01:27:04 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
return;
|
2004-08-31 19:28:41 +02:00
|
|
|
|
} /* end V is the root */
|
|
|
|
|
/* Check if W's parent is a network connected to root. */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
else if (v->type == OSPF_VERTEX_NETWORK)
|
|
|
|
|
{
|
2004-08-31 19:28:41 +02:00
|
|
|
|
/* See if any of V's parents are the root. */
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
for (ALL_LIST_ELEMENTS (v->parents, node, nnode, vp))
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
if (vp->parent == area->spf) /* connects to root? */
|
2004-08-31 19:28:41 +02:00
|
|
|
|
{
|
|
|
|
|
/* 16.1.1 para 5. ...the parent vertex is a network that
|
|
|
|
|
* directly connects the calculating router to the destination
|
|
|
|
|
* router. The list of next hops is then determined by
|
|
|
|
|
* examining the destination's router-LSA...
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
assert(w->type == OSPF_VERTEX_ROUTER);
|
2003-06-07 01:27:04 +02:00
|
|
|
|
while ((l = ospf_get_next_link (w, v, l)))
|
|
|
|
|
{
|
2004-08-31 19:28:41 +02:00
|
|
|
|
/* ...For each link in the router-LSA that points back to the
|
|
|
|
|
* parent network, the link's Link Data field provides the IP
|
|
|
|
|
* address of a next hop router. The outgoing interface to
|
|
|
|
|
* use can then be derived from the next hop IP address (or
|
|
|
|
|
* it can be inherited from the parent network).
|
|
|
|
|
*/
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
nh = vertex_nexthop_new ();
|
|
|
|
|
nh->oi = vp->nexthop->oi;
|
|
|
|
|
nh->router = l->link_data;
|
|
|
|
|
ospf_spf_add_parent (v, w, nh);
|
2003-06-07 01:27:04 +02:00
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-31 19:28:41 +02:00
|
|
|
|
/* 16.1.1 para 4. If there is at least one intervening router in the
|
|
|
|
|
* current shortest path between the destination and the root, the
|
|
|
|
|
* destination simply inherits the set of next hops from the
|
|
|
|
|
* parent.
|
|
|
|
|
*/
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
for (ALL_LIST_ELEMENTS (v->parents, node, nnode, vp))
|
|
|
|
|
ospf_spf_add_parent (v, w, vp->nexthop);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
2004-08-31 19:28:41 +02:00
|
|
|
|
/* RFC2328 Section 16.1 (2).
|
|
|
|
|
* v is on the SPF tree. Examine the links in v's LSA. Update the list
|
|
|
|
|
* of candidates with any vertices not already on the list. If a lower-cost
|
|
|
|
|
* path is found to a vertex already on the candidate list, store the new cost.
|
|
|
|
|
*/
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ospf_spf_next (struct vertex *v, struct ospf_area *area,
|
2005-02-23 12:29:02 +01:00
|
|
|
|
struct pqueue * candidate)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
|
|
|
|
struct ospf_lsa *w_lsa = NULL;
|
|
|
|
|
u_char *p;
|
|
|
|
|
u_char *lim;
|
|
|
|
|
struct router_lsa_link *l = NULL;
|
|
|
|
|
struct in_addr *r;
|
|
|
|
|
int type = 0;
|
|
|
|
|
|
|
|
|
|
/* If this is a router-LSA, and bit V of the router-LSA (see Section
|
|
|
|
|
A.4.2:RFC2328) is set, set Area A's TransitCapability to TRUE. */
|
|
|
|
|
if (v->type == OSPF_VERTEX_ROUTER)
|
|
|
|
|
{
|
|
|
|
|
if (IS_ROUTER_LSA_VIRTUAL ((struct router_lsa *) v->lsa))
|
|
|
|
|
area->transit = OSPF_TRANSIT_TRUE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p = ((u_char *) v->lsa) + OSPF_LSA_HEADER_SIZE + 4;
|
2003-06-07 01:27:04 +02:00
|
|
|
|
lim = ((u_char *) v->lsa) + ntohs (v->lsa->length);
|
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
while (p < lim)
|
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
struct vertex *w;
|
|
|
|
|
unsigned int distance;
|
2004-04-08 09:43:45 +02:00
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
/* In case of V is Router-LSA. */
|
|
|
|
|
if (v->lsa->type == OSPF_ROUTER_LSA)
|
|
|
|
|
{
|
|
|
|
|
l = (struct router_lsa_link *) p;
|
|
|
|
|
|
2003-06-07 01:27:04 +02:00
|
|
|
|
p += (ROUTER_LSA_MIN_SIZE +
|
2002-12-13 21:15:29 +01:00
|
|
|
|
(l->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
|
|
|
|
|
|
|
|
|
|
/* (a) If this is a link to a stub network, examine the next
|
|
|
|
|
link in V's LSA. Links to stub networks will be
|
|
|
|
|
considered in the second stage of the shortest path
|
|
|
|
|
calculation. */
|
|
|
|
|
if ((type = l->m[0].type) == LSA_LINK_TYPE_STUB)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
/* (b) Otherwise, W is a transit vertex (router or transit
|
|
|
|
|
network). Look up the vertex W's LSA (router-LSA or
|
|
|
|
|
network-LSA) in Area A's link state database. */
|
|
|
|
|
switch (type)
|
|
|
|
|
{
|
|
|
|
|
case LSA_LINK_TYPE_POINTOPOINT:
|
|
|
|
|
case LSA_LINK_TYPE_VIRTUALLINK:
|
|
|
|
|
if (type == LSA_LINK_TYPE_VIRTUALLINK)
|
2003-06-07 01:27:04 +02:00
|
|
|
|
{
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("looking up LSA through VL: %s",
|
2003-06-07 01:27:04 +02:00
|
|
|
|
inet_ntoa (l->link_id));
|
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
w_lsa = ospf_lsa_lookup (area, OSPF_ROUTER_LSA, l->link_id,
|
|
|
|
|
l->link_id);
|
|
|
|
|
if (w_lsa)
|
2003-06-07 01:27:04 +02:00
|
|
|
|
{
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("found Router LSA %s", inet_ntoa (l->link_id));
|
2003-06-07 01:27:04 +02:00
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
break;
|
|
|
|
|
case LSA_LINK_TYPE_TRANSIT:
|
2003-06-07 01:27:04 +02:00
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("Looking up Network LSA, ID: %s",
|
2003-06-07 01:27:04 +02:00
|
|
|
|
inet_ntoa (l->link_id));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
w_lsa = ospf_lsa_lookup_by_id (area, OSPF_NETWORK_LSA,
|
2003-06-07 01:27:04 +02:00
|
|
|
|
l->link_id);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
if (w_lsa)
|
2003-06-07 01:27:04 +02:00
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("found the LSA");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
break;
|
|
|
|
|
default:
|
2003-06-07 01:27:04 +02:00
|
|
|
|
zlog_warn ("Invalid LSA link type %d", type);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
/* In case of V is Network-LSA. */
|
2003-06-07 01:27:04 +02:00
|
|
|
|
r = (struct in_addr *) p;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
p += sizeof (struct in_addr);
|
|
|
|
|
|
|
|
|
|
/* Lookup the vertex W's LSA. */
|
|
|
|
|
w_lsa = ospf_lsa_lookup_by_id (area, OSPF_ROUTER_LSA, *r);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* (b cont.) If the LSA does not exist, or its LS age is equal
|
|
|
|
|
to MaxAge, or it does not have a link back to vertex V,
|
|
|
|
|
examine the next link in V's LSA.[23] */
|
|
|
|
|
if (w_lsa == NULL)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
if (IS_LSA_MAXAGE (w_lsa))
|
|
|
|
|
continue;
|
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
if (ospf_lsa_has_link (w_lsa->data, v->lsa) < 0 )
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
2003-06-07 01:27:04 +02:00
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("The LSA doesn't have a link back");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* (c) If vertex W is already on the shortest-path tree, examine
|
|
|
|
|
the next link in the LSA. */
|
2005-02-23 12:29:02 +01:00
|
|
|
|
if (w_lsa->stat == LSA_SPF_IN_SPFTREE)
|
|
|
|
|
{
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
|
zlog_debug ("The LSA is already in SPF");
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
/* (d) Calculate the link state cost D of the resulting path
|
|
|
|
|
from the root to vertex W. D is equal to the sum of the link
|
|
|
|
|
state cost of the (already calculated) shortest path to
|
|
|
|
|
vertex V and the advertised cost of the link between vertices
|
|
|
|
|
V and W. If D is: */
|
|
|
|
|
|
|
|
|
|
/* calculate link cost D. */
|
|
|
|
|
if (v->lsa->type == OSPF_ROUTER_LSA)
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
distance = v->distance + ntohs (l->m[0].metric);
|
2004-08-31 19:28:41 +02:00
|
|
|
|
else /* v is not a Router-LSA */
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
distance = v->distance;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
/* Is there already vertex W in candidate list? */
|
2005-02-23 12:29:02 +01:00
|
|
|
|
if (w_lsa->stat == LSA_SPF_NOT_EXPLORED)
|
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
/* prepare vertex W. */
|
|
|
|
|
w = ospf_vertex_new (w_lsa);
|
|
|
|
|
|
2005-02-23 12:29:02 +01:00
|
|
|
|
/* Calculate nexthop to W. */
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
w->distance = distance;
|
|
|
|
|
ospf_nexthop_calculation (area, v, w, l);
|
2005-02-23 12:29:02 +01:00
|
|
|
|
pqueue_enqueue (w, candidate);
|
|
|
|
|
}
|
|
|
|
|
else if (w_lsa->stat >= 0)
|
|
|
|
|
{
|
|
|
|
|
/* Get the vertex from candidates. */
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
w = candidate->array[w_lsa->stat];
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
2005-02-23 12:29:02 +01:00
|
|
|
|
/* if D is greater than. */
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
if (w->distance < distance)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2005-02-23 12:29:02 +01:00
|
|
|
|
/* equal to. */
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
else if (w->distance == distance)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
/* Found an equal-cost path to W.
|
|
|
|
|
* Calculate nexthop of to W from V. */
|
|
|
|
|
ospf_nexthop_calculation (area, v, w, l);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
2005-02-23 12:29:02 +01:00
|
|
|
|
/* less than. */
|
|
|
|
|
else
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
/* Found a lower-cost path to W. */
|
|
|
|
|
w->distance = distance;
|
|
|
|
|
|
|
|
|
|
/* Flush existing parent list from W */
|
|
|
|
|
ospf_spf_flush_parents (w);
|
|
|
|
|
|
|
|
|
|
/* Calculate new nexthop(s) to W. */
|
|
|
|
|
ospf_nexthop_calculation (area, v, w, l);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
2005-02-23 12:29:02 +01:00
|
|
|
|
/* Decrease the key of the node in the heap, re-sort the heap. */
|
|
|
|
|
trickle_down (w_lsa->stat, candidate);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
2004-08-31 19:28:41 +02:00
|
|
|
|
} /* end W is already on the candidate list */
|
|
|
|
|
} /* end loop over the links in V's LSA */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ospf_spf_dump (struct vertex *v, int i)
|
|
|
|
|
{
|
2004-09-23 21:18:23 +02:00
|
|
|
|
struct listnode *cnode;
|
|
|
|
|
struct listnode *nnode;
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
struct vertex_parent *parent;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
if (v->type == OSPF_VERTEX_ROUTER)
|
|
|
|
|
{
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("SPF Result: %d [R] %s", i, inet_ntoa (v->lsa->id));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
struct network_lsa *lsa = (struct network_lsa *) v->lsa;
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("SPF Result: %d [N] %s/%d", i, inet_ntoa (v->lsa->id),
|
2003-06-07 01:27:04 +02:00
|
|
|
|
ip_masklen (lsa->mask));
|
2004-08-31 19:28:41 +02:00
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
for (ALL_LIST_ELEMENTS_RO (v->parents, nnode, parent))
|
|
|
|
|
{
|
|
|
|
|
zlog_debug (" nexthop %p %s %s",
|
|
|
|
|
parent->nexthop,
|
|
|
|
|
inet_ntoa (parent->nexthop->router),
|
|
|
|
|
parent->nexthop->oi ? IF_NAME(parent->nexthop->oi)
|
|
|
|
|
: "NULL");
|
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
for (ALL_LIST_ELEMENTS_RO (v->children, cnode, v))
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
ospf_spf_dump (v, i);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Second stage of SPF calculation. */
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static void
|
2003-06-07 01:27:04 +02:00
|
|
|
|
ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v,
|
2002-12-13 21:15:29 +01:00
|
|
|
|
struct route_table *rt)
|
|
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
struct listnode *cnode, *cnnode;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
struct vertex *child;
|
|
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("ospf_process_stub():processing stubs for area %s",
|
2003-06-07 01:27:04 +02:00
|
|
|
|
inet_ntoa (area->area_id));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
if (v->type == OSPF_VERTEX_ROUTER)
|
|
|
|
|
{
|
|
|
|
|
u_char *p;
|
|
|
|
|
u_char *lim;
|
|
|
|
|
struct router_lsa_link *l;
|
|
|
|
|
struct router_lsa *rlsa;
|
|
|
|
|
|
2003-06-07 01:27:04 +02:00
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("ospf_process_stubs():processing router LSA, id: %s",
|
2003-06-07 01:27:04 +02:00
|
|
|
|
inet_ntoa (v->lsa->id));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
rlsa = (struct router_lsa *) v->lsa;
|
|
|
|
|
|
|
|
|
|
|
2003-06-07 01:27:04 +02:00
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("ospf_process_stubs(): we have %d links to process",
|
2003-06-07 01:27:04 +02:00
|
|
|
|
ntohs (rlsa->links));
|
2004-08-31 19:28:41 +02:00
|
|
|
|
p = ((u_char *) v->lsa) + OSPF_LSA_HEADER_SIZE + 4;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
lim = ((u_char *) v->lsa) + ntohs (v->lsa->length);
|
|
|
|
|
|
|
|
|
|
while (p < lim)
|
|
|
|
|
{
|
|
|
|
|
l = (struct router_lsa_link *) p;
|
|
|
|
|
|
|
|
|
|
p += (ROUTER_LSA_MIN_SIZE +
|
|
|
|
|
(l->m[0].tos_count * ROUTER_LSA_TOS_SIZE));
|
|
|
|
|
|
|
|
|
|
if (l->m[0].type == LSA_LINK_TYPE_STUB)
|
|
|
|
|
ospf_intra_add_stub (rt, l, v, area);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-08-31 19:28:41 +02:00
|
|
|
|
ospf_vertex_dump("ospf_process_stubs(): after examining links: ", v, 1, 1);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
for (ALL_LIST_ELEMENTS (v->children, cnode, cnnode, child))
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
|
|
|
|
if (CHECK_FLAG (child->flags, OSPF_VERTEX_PROCESSED))
|
2003-06-07 01:27:04 +02:00
|
|
|
|
continue;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
ospf_spf_process_stubs (area, child, rt);
|
|
|
|
|
|
|
|
|
|
SET_FLAG (child->flags, OSPF_VERTEX_PROCESSED);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ospf_rtrs_free (struct route_table *rtrs)
|
|
|
|
|
{
|
|
|
|
|
struct route_node *rn;
|
2004-09-23 21:18:23 +02:00
|
|
|
|
struct list *or_list;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
struct ospf_route *or;
|
|
|
|
|
struct listnode *node, *nnode;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("Route: Router Routing Table free");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
for (rn = route_top (rtrs); rn; rn = route_next (rn))
|
|
|
|
|
if ((or_list = rn->info) != NULL)
|
|
|
|
|
{
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
for (ALL_LIST_ELEMENTS (or_list, node, nnode, or))
|
|
|
|
|
ospf_route_free (or);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
2003-06-07 01:27:04 +02:00
|
|
|
|
list_delete (or_list);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
2003-06-07 01:27:04 +02:00
|
|
|
|
/* Unlock the node. */
|
|
|
|
|
rn->info = NULL;
|
|
|
|
|
route_unlock_node (rn);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
route_table_finish (rtrs);
|
|
|
|
|
}
|
|
|
|
|
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static void
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ospf_rtrs_print (struct route_table *rtrs)
|
|
|
|
|
{
|
|
|
|
|
struct route_node *rn;
|
2004-09-23 21:18:23 +02:00
|
|
|
|
struct list *or_list;
|
|
|
|
|
struct listnode *ln;
|
|
|
|
|
struct listnode *pnode;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
struct ospf_route *or;
|
|
|
|
|
struct ospf_path *path;
|
|
|
|
|
char buf1[BUFSIZ];
|
|
|
|
|
char buf2[BUFSIZ];
|
|
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("ospf_rtrs_print() start");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
for (rn = route_top (rtrs); rn; rn = route_next (rn))
|
|
|
|
|
if ((or_list = rn->info) != NULL)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
for (ALL_LIST_ELEMENTS_RO (or_list, ln, or))
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
|
|
|
|
switch (or->path_type)
|
|
|
|
|
{
|
|
|
|
|
case OSPF_PATH_INTRA_AREA:
|
2003-06-07 01:27:04 +02:00
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("%s [%d] area: %s",
|
2003-06-07 01:27:04 +02:00
|
|
|
|
inet_ntop (AF_INET, &or->id, buf1, BUFSIZ),
|
|
|
|
|
or->cost, inet_ntop (AF_INET, &or->u.std.area_id,
|
|
|
|
|
buf2, BUFSIZ));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
break;
|
|
|
|
|
case OSPF_PATH_INTER_AREA:
|
2003-06-07 01:27:04 +02:00
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("%s IA [%d] area: %s",
|
2003-06-07 01:27:04 +02:00
|
|
|
|
inet_ntop (AF_INET, &or->id, buf1, BUFSIZ),
|
|
|
|
|
or->cost, inet_ntop (AF_INET, &or->u.std.area_id,
|
|
|
|
|
buf2, BUFSIZ));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
for (ALL_LIST_ELEMENTS_RO (or->paths, pnode, path))
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
|
|
|
|
if (path->nexthop.s_addr == 0)
|
2003-06-07 01:27:04 +02:00
|
|
|
|
{
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug (" directly attached to %s\r\n",
|
2003-06-07 01:27:04 +02:00
|
|
|
|
IF_NAME (path->oi));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug (" via %s, %s\r\n",
|
2003-06-07 01:27:04 +02:00
|
|
|
|
inet_ntoa (path->nexthop), IF_NAME (path->oi));
|
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("ospf_rtrs_print() end");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Calculating the shortest-path tree for an area. */
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static void
|
2003-06-07 01:27:04 +02:00
|
|
|
|
ospf_spf_calculate (struct ospf_area *area, struct route_table *new_table,
|
2002-12-13 21:15:29 +01:00
|
|
|
|
struct route_table *new_rtrs)
|
|
|
|
|
{
|
2005-02-23 12:29:02 +01:00
|
|
|
|
struct pqueue *candidate;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
struct vertex *v;
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
|
{
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("ospf_spf_calculate: Start");
|
|
|
|
|
zlog_debug ("ospf_spf_calculate: running Dijkstra for area %s",
|
2003-06-07 01:27:04 +02:00
|
|
|
|
inet_ntoa (area->area_id));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Check router-lsa-self. If self-router-lsa is not yet allocated,
|
|
|
|
|
return this area's calculation. */
|
2003-06-07 01:27:04 +02:00
|
|
|
|
if (!area->router_lsa_self)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("ospf_spf_calculate: "
|
2003-06-07 01:27:04 +02:00
|
|
|
|
"Skip area %s's calculation due to empty router_lsa_self",
|
|
|
|
|
inet_ntoa (area->area_id));
|
2002-12-13 21:15:29 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* RFC2328 16.1. (1). */
|
2003-06-07 01:27:04 +02:00
|
|
|
|
/* Initialize the algorithm's data structures. */
|
2005-02-23 12:29:02 +01:00
|
|
|
|
|
|
|
|
|
/* This function scans all the LSA database and set the stat field to
|
|
|
|
|
* LSA_SPF_NOT_EXPLORED. */
|
|
|
|
|
ospf_lsdb_clean_stat (area->lsdb);
|
|
|
|
|
/* Create a new heap for the candidates. */
|
|
|
|
|
candidate = pqueue_create();
|
|
|
|
|
candidate->cmp = cmp;
|
|
|
|
|
candidate->update = update_stat;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
/* Initialize the shortest-path tree to only the root (which is the
|
|
|
|
|
router doing the calculation). */
|
|
|
|
|
ospf_spf_init (area);
|
|
|
|
|
v = area->spf;
|
2005-02-23 12:29:02 +01:00
|
|
|
|
/* Set LSA position to LSA_SPF_IN_SPFTREE. This vertex is the root of the
|
|
|
|
|
* spanning tree. */
|
|
|
|
|
*(v->stat) = LSA_SPF_IN_SPFTREE;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
/* Set Area A's TransitCapability to FALSE. */
|
|
|
|
|
area->transit = OSPF_TRANSIT_FALSE;
|
|
|
|
|
area->shortcut_capability = 1;
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
for (;;)
|
|
|
|
|
{
|
|
|
|
|
/* RFC2328 16.1. (2). */
|
2005-02-23 12:29:02 +01:00
|
|
|
|
ospf_spf_next (v, area, candidate);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
/* RFC2328 16.1. (3). */
|
|
|
|
|
/* If at this step the candidate list is empty, the shortest-
|
|
|
|
|
path tree (of transit vertices) has been completely built and
|
|
|
|
|
this stage of the procedure terminates. */
|
2005-02-23 12:29:02 +01:00
|
|
|
|
if (candidate->size == 0)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
/* Otherwise, choose the vertex belonging to the candidate list
|
|
|
|
|
that is closest to the root, and add it to the shortest-path
|
|
|
|
|
tree (removing it from the candidate list in the
|
2003-06-07 01:27:04 +02:00
|
|
|
|
process). */
|
2005-02-23 12:29:02 +01:00
|
|
|
|
/* Extract from the candidates the node with the lower key. */
|
|
|
|
|
v = (struct vertex *) pqueue_dequeue (candidate);
|
|
|
|
|
/* Update stat field in vertex. */
|
|
|
|
|
*(v->stat) = LSA_SPF_IN_SPFTREE;
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ospf_vertex_add_parent (v);
|
|
|
|
|
|
|
|
|
|
/* Note that when there is a choice of vertices closest to the
|
|
|
|
|
root, network vertices must be chosen before router vertices
|
|
|
|
|
in order to necessarily find all equal-cost paths. */
|
|
|
|
|
/* We don't do this at this moment, we should add the treatment
|
|
|
|
|
above codes. -- kunihiro. */
|
|
|
|
|
|
|
|
|
|
/* RFC2328 16.1. (4). */
|
|
|
|
|
if (v->type == OSPF_VERTEX_ROUTER)
|
|
|
|
|
ospf_intra_add_router (new_rtrs, v, area);
|
2003-06-07 01:27:04 +02:00
|
|
|
|
else
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ospf_intra_add_transit (new_table, v, area);
|
|
|
|
|
|
|
|
|
|
/* RFC2328 16.1. (5). */
|
|
|
|
|
/* Iterate the algorithm by returning to Step 2. */
|
2004-08-31 19:28:41 +02:00
|
|
|
|
|
|
|
|
|
} /* end loop until no more candidate vertices */
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
|
|
|
|
{
|
|
|
|
|
ospf_spf_dump (area->spf, 0);
|
|
|
|
|
ospf_route_table_dump (new_table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Second stage of SPF calculation procedure's */
|
|
|
|
|
ospf_spf_process_stubs (area, area->spf, new_table);
|
|
|
|
|
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
/* Free candidate queue. */
|
2005-02-23 12:29:02 +01:00
|
|
|
|
pqueue_delete (candidate);
|
2005-10-18 Paul Jakma <paul.jakma@sun.com>
* (general) SPF memory management cleanup and fix for rare
double-free bug.
* ospf_spf.h: (struct vertex_parent) New struct to hold parent
specific data, eg the backlink and the parent vertex pointer,
and point to the appropriate general struct vertex_nexthop.
(struct vertex_nexthop) remove parent vertex pointer, so
this struct can be shared across vertices.
(struct vertex) rename list child to list children. Remove
list of nexthops, replace with list of vertex_parents.
* ospf_spf.c: (update_stat) trivial, remove cast from void *.
(vertex_nexthop_new) remove init of parent - field is gone
from struct vertex_nexthop.
(ospf_canonical_nexthops_free) Remove the canonical
vertex_nexthop memory objects. These are the vertex_nexthops
attached to the first level of router vertices from the root.
(vertex_parent_new) new function, create a vertex_parent.
(vertex_parent_free) ditto, but free it.
(ospf_vertex_new) Update to match changes to struct vertex.
(ospf_vertex_free) Recursively free a struct vertex and its
children. The parent list is used as a reference count.
vertex_nexthops must be free seperately, if required.
(ospf_vertex_dump) update to match struct vertex changes.
Print out backlink of parents too.
(ospf_vertex_add_parent) ditto.
(ospf_lsa_has_link) update comment.
(ospf_nexthop_add_unique) removed, not needed anymore.
(ospf_nexthop_merge) ditto.
(ospf_spf_consider_nexthop) renamed to ospf_spf_add_parent.
Simplified to just create vertex_parent and add it.
(ospf_spf_flush_parents) new function, flush out the parent
list.
(ospf_nexthop_calculation) Take the relevant route_lsa_link
as an argument, which simplifies things and removes the need
for the hack in ospf_nexthop_add_unique - ospf_spf_next
already knew exactly which link the cost calculated was for.
Update to match struct vertex changes too.
(ospf_spf_next) Don't create a vertex for W unnecessarily, if
it's there's a vertex already created for W, use it, and
hence there's no need to free it either.
Update some manipulation/comparisons of distance to match.
Flush the parent list if a lower cost path is found.
(ospf_spf_route_free) unused, removed.
(ospf_spf_dump) match the struct vertex changes, and dump the
ifname if possible.
(ospf_spf_calculate) At end of SPF, free the canonical nexthops
and call ospf_vertex_free on the root vertex to free the
entire tree.
* ospf_interface.c: (ospf_vl_set_params) match struct vertex
changes.
* ospf_route.c: (ospf_intra_route_add) ditto
(ospf_route_copy_nexthops_from_vertex) ditto
* memtypes.c: (memory_list_ospf) Add MTYPE_OSPF_VERTEX_PARENT.
2005-10-18 06:20:33 +02:00
|
|
|
|
|
|
|
|
|
ospf_vertex_dump (__func__, area->spf, 0, 1);
|
|
|
|
|
/* Free nexthop information, canonical versions of which are attached
|
|
|
|
|
* the first level of router vertices attached to the root vertex, see
|
|
|
|
|
* ospf_nexthop_calculation.
|
|
|
|
|
*/
|
|
|
|
|
ospf_canonical_nexthops_free (area->spf);
|
|
|
|
|
|
|
|
|
|
/* Free SPF vertices */
|
|
|
|
|
ospf_vertex_free (area->spf, area);
|
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
/* Increment SPF Calculation Counter. */
|
|
|
|
|
area->spf_calculation++;
|
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
|
area->ospf->ts_spf = time (NULL);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("ospf_spf_calculate: Stop");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Timer for SPF calculation. */
|
2005-05-06 23:37:42 +02:00
|
|
|
|
static int
|
2003-03-25 06:07:42 +01:00
|
|
|
|
ospf_spf_calculate_timer (struct thread *thread)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
2003-03-25 06:07:42 +01:00
|
|
|
|
struct ospf *ospf = THREAD_ARG (thread);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
struct route_table *new_table, *new_rtrs;
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
struct ospf_area *area;
|
|
|
|
|
struct listnode *node, *nnode;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("SPF: Timer (SPF calculation expire)");
|
2003-06-07 01:27:04 +02:00
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
|
ospf->t_spf_calc = NULL;
|
|
|
|
|
|
|
|
|
|
/* Allocate new table tree. */
|
|
|
|
|
new_table = route_table_init ();
|
2003-06-07 01:27:04 +02:00
|
|
|
|
new_rtrs = route_table_init ();
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
|
ospf_vl_unapprove (ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
/* Calculate SPF for each area. */
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
|
for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))
|
|
|
|
|
ospf_spf_calculate (area, new_table, new_rtrs);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
|
ospf_vl_shut_unapproved (ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
|
ospf_ia_routing (ospf, new_table, new_rtrs);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
ospf_prune_unreachable_networks (new_table);
|
|
|
|
|
ospf_prune_unreachable_routers (new_rtrs);
|
|
|
|
|
|
|
|
|
|
/* AS-external-LSA calculation should not be performed here. */
|
|
|
|
|
|
|
|
|
|
/* If new Router Route is installed,
|
|
|
|
|
then schedule re-calculate External routes. */
|
|
|
|
|
if (1)
|
2003-03-25 06:07:42 +01:00
|
|
|
|
ospf_ase_calculate_schedule (ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
|
ospf_ase_calculate_timer_add (ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
/* Update routing table. */
|
2003-03-25 06:07:42 +01:00
|
|
|
|
ospf_route_install (ospf, new_table);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
/* Update ABR/ASBR routing table */
|
2003-03-25 06:07:42 +01:00
|
|
|
|
if (ospf->old_rtrs)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
|
|
|
|
/* old_rtrs's node holds linked list of ospf_route. --kunihiro. */
|
2003-03-25 06:07:42 +01:00
|
|
|
|
/* ospf_route_delete (ospf->old_rtrs); */
|
|
|
|
|
ospf_rtrs_free (ospf->old_rtrs);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
|
ospf->old_rtrs = ospf->new_rtrs;
|
|
|
|
|
ospf->new_rtrs = new_rtrs;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
2003-06-07 01:27:04 +02:00
|
|
|
|
if (IS_OSPF_ABR (ospf))
|
2003-03-25 06:07:42 +01:00
|
|
|
|
ospf_abr_task (ospf);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("SPF: calculation complete");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Add schedule for SPF calculation. To avoid frequenst SPF calc, we
|
|
|
|
|
set timer for SPF calc. */
|
|
|
|
|
void
|
2003-03-25 06:07:42 +01:00
|
|
|
|
ospf_spf_calculate_schedule (struct ospf *ospf)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
|
|
|
|
time_t ht, delay;
|
|
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("SPF: calculation timer scheduled");
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
/* OSPF instance does not exist. */
|
2003-03-25 06:07:42 +01:00
|
|
|
|
if (ospf == NULL)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
/* SPF calculation timer is already scheduled. */
|
2003-03-25 06:07:42 +01:00
|
|
|
|
if (ospf->t_spf_calc)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("SPF: calculation timer is already scheduled: %p",
|
2003-06-07 01:27:04 +02:00
|
|
|
|
ospf->t_spf_calc);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2003-03-25 06:07:42 +01:00
|
|
|
|
ht = time (NULL) - ospf->ts_spf;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
/* Get SPF calculation delay time. */
|
2003-03-25 06:07:42 +01:00
|
|
|
|
if (ht < ospf->spf_holdtime)
|
2002-12-13 21:15:29 +01:00
|
|
|
|
{
|
2003-03-25 06:07:42 +01:00
|
|
|
|
if (ospf->spf_holdtime - ht < ospf->spf_delay)
|
2003-06-07 01:27:04 +02:00
|
|
|
|
delay = ospf->spf_delay;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
else
|
2003-06-07 01:27:04 +02:00
|
|
|
|
delay = ospf->spf_holdtime - ht;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
2003-03-25 06:07:42 +01:00
|
|
|
|
delay = ospf->spf_delay;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
|
|
if (IS_DEBUG_OSPF_EVENT)
|
2004-12-08 19:43:03 +01:00
|
|
|
|
zlog_debug ("SPF: calculation timer delay = %ld", (long)delay);
|
2003-03-25 06:07:42 +01:00
|
|
|
|
ospf->t_spf_calc =
|
|
|
|
|
thread_add_timer (master, ospf_spf_calculate_timer, ospf, delay);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
}
|