From 9c27ef9b9c26db0af507869c2866c4a8463f4ae7 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Thu, 4 May 2006 07:32:57 +0000 Subject: [ospfd] Fix SPF of virtual-links 2006-04-24 Paul Jakma * (general) More Virtual-link fixes, again with much help in testing / debug from Juergen Kammer. Primarily in SPF. * ospf_spf.h: Add guard. ospf_interface.h will include this header. * ospf_interface.h: Modify ospf_vl_lookup definition to take struct ospf as argument, so as to allow for NULL area argument. (struct ospf_vl_data) Remove out_oi, instead add a struct vertex_nexthop, to use as initial nexthop for backbone paths through a vlink. * ospf_interface.c: (ospf_vl_lookup) Modified to allow NULL area to be passed to indicate "any" (first) area. Add extra debug. (ospf_vl_set_params) vl_oi -> nexthop. Add extra debug. (ospf_vl_up_check) Fix debug, inet_ntoa returns a static buffer.. * ospf_route.c: (ospf_intra_add_router) Vlinks dont go through backbone, don't bother checking. * ospf_spf.c: (static struct list vertex_list) Record vertices that will need to be freed. (cmp) Order network before router vertices, as required, wasn't implemented. (vertex_nexthop_free) Mild additional robustness check. (vertex_parent_free) Take void argument, as this function is passed as list deconstructor for vertex parent list. (ospf_vertex_new) More debug. Set deconstructor for parent list. Track allocated vertices on the vertex_list. (ospf_vertex_free) Get rid of the tricky recursive cleanup of vertices. Now frees only the given vertex. (ospf_vertex_add_parent) Fix assert. (ospf_nexthop_calculation) Fix calculation of nexthop for VLink vertices, lookup the vl_data and use its previously recorded nexthop information. (ospf_spf_calculate) Vertices are freed simply by deleting vertex_list nodes and letting ospf_vertex_free as deconstructor work per-node. (ospf_spf_calculate_timer) Trivial optimisation, leave backbone SPF calculation till last to reduce SPF churn on VLink updates. * ospf_vty.c: (ospf_find_vl_data) update call to ospf_vl_lookup (no_ospf_area_vlink_cmd) ditto. (show_ip_ospf_interface_sub) For Vlinks, the peer address is more interesting than the output interface. --- ospfd/ospf_interface.c | 60 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 21 deletions(-) (limited to 'ospfd/ospf_interface.c') diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 52adc420..1264cac6 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -931,16 +931,36 @@ ospf_vl_if_delete (struct ospf_vl_data *vl_data) vlink_count--; } +/* Look up vl_data for given peer, optionally qualified to be in the + * specified area. NULL area returns first found.. + */ struct ospf_vl_data * -ospf_vl_lookup (struct ospf_area *area, struct in_addr vl_peer) +ospf_vl_lookup (struct ospf *ospf, struct ospf_area *area, + struct in_addr vl_peer) { struct ospf_vl_data *vl_data; struct listnode *node; - - for (ALL_LIST_ELEMENTS_RO (area->ospf->vlinks, node, vl_data)) - if (vl_data->vl_peer.s_addr == vl_peer.s_addr && - IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id)) - return vl_data; + + if (IS_DEBUG_OSPF_EVENT) + { + zlog_debug ("%s: Looking for %s", __func__, inet_ntoa (vl_peer)); + if (area) + zlog_debug ("%s: in area %s", __func__, inet_ntoa (area->area_id)); + } + + for (ALL_LIST_ELEMENTS_RO (ospf->vlinks, node, vl_data)) + { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug ("%s: VL %s, peer %s", __func__, + vl_data->vl_oi->ifp->name, + inet_ntoa (vl_data->vl_peer)); + + if (area && !IPV4_ADDR_SAME (&vl_data->vl_area_id, &area->area_id)) + continue; + + if (IPV4_ADDR_SAME (&vl_data->vl_peer, &vl_peer)) + return vl_data; + } return NULL; } @@ -1005,14 +1025,15 @@ ospf_vl_set_params (struct ospf_vl_data *vl_data, struct vertex *v) for (ALL_LIST_ELEMENTS_RO (v->parents, node, vp)) { - vl_data->out_oi = vp->nexthop->oi; + vl_data->nexthop.oi = vp->nexthop->oi; + vl_data->nexthop.router = vp->nexthop->router; if (!IPV4_ADDR_SAME(&voi->address->u.prefix4, - &vl_data->out_oi->address->u.prefix4)) + &vl_data->nexthop.oi->address->u.prefix4)) changed = 1; - voi->address->u.prefix4 = vl_data->out_oi->address->u.prefix4; - voi->address->prefixlen = vl_data->out_oi->address->prefixlen; + voi->address->u.prefix4 = vl_data->nexthop.oi->address->u.prefix4; + voi->address->prefixlen = vl_data->nexthop.oi->address->prefixlen; break; /* We take the first interface. */ } @@ -1050,19 +1071,16 @@ ospf_vl_set_params (struct ospf_vl_data *vl_data, struct vertex *v) &rl->link[i].link_data)) changed = 1; vl_data->peer_addr = rl->link[i].link_data; - if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_vl_set_params: %s peer address is %s\n", - vl_data->vl_oi->ifp->name, - inet_ntoa(vl_data->peer_addr)); - return changed; } } } if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_vl_set_params: %s peer address is %s\n", + zlog_debug ("%s: %s peer address: %s, cost: %d,%schanged", __func__, vl_data->vl_oi->ifp->name, - inet_ntoa(vl_data->peer_addr)); + inet_ntoa(vl_data->peer_addr), + voi->output_cost, + (changed ? " " : " un")); return changed; } @@ -1088,10 +1106,10 @@ ospf_vl_up_check (struct ospf_area *area, struct in_addr rid, { if (IS_DEBUG_OSPF_EVENT) { - zlog_debug ("ospf_vl_up_check(): considering VL, name: %s", - vl_data->vl_oi->ifp->name); - zlog_debug ("ospf_vl_up_check(): VL area: %s, peer ID: %s", - inet_ntoa (vl_data->vl_area_id), + zlog_debug ("%s: considering VL, %s in area %s", __func__, + vl_data->vl_oi->ifp->name, + inet_ntoa (vl_data->vl_area_id)); + zlog_debug ("%s: peer ID: %s", __func__, inet_ntoa (vl_data->vl_peer)); } -- cgit v1.2.1