diff options
| author | JR Rivers <jrrivers@cumulusnetworks.com> | 2012-09-24 17:26:46 +0000 | 
|---|---|---|
| committer | David Lamparter <equinox@opensourcerouting.org> | 2012-10-25 10:15:58 -0700 | 
| commit | 8fc9e007ee752a982fe47311702d7ff3b9c5b5cd (patch) | |
| tree | 8dd5ef95e303d34f1045afe538f44a07dab017d3 /ospfd/ospf_abr.c | |
| parent | d8a4e42b7d19a87eacc00c825e913907a58f39ee (diff) | |
ospfd: blackhole route removal for area range
ISSUE
When an area range is created in which there the sub-area has routes that are
smaller than the range, an ABR creates a blackhole route to cover the range.
When the range is removed, the blackhole route is not removed.
--A----B----C---
B is an ABR with A in area 1 and C in area 0.  If A advertises `10.2.0.0/30` and
`10.2.0.4/30` and B is configured with `area 0.0.0.1 range 10.2.0.0/29` a
blackhole is created on B (`blackhole 10.2.0.0/29 proto zebra`).  When the
area/range is removed via the command line, the blackhole remains in existence
even though the "range" route is removed from area 0 and the individual routes
are propagated.
PATCH
The reason for this behavior is that, prior to this patch, the range is deleted
from the area's list, so when ospf_abr_manage_discard_routes() gets called,
there is nothing to clean up.  The patch removes the discard route as part of
the processing of the command line (ospf_area_range_unset()).
Signed-off-by: JR Rivers <jrrivers@cumulusnetworks.com>
Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com>
Reviewed-by: Shrijeet Mukherjee <shm@cumulusnetworks.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'ospfd/ospf_abr.c')
| -rw-r--r-- | ospfd/ospf_abr.c | 36 | 
1 files changed, 16 insertions, 20 deletions
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index b7cc20dd87..ef1048b23b 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -88,23 +88,18 @@ ospf_area_range_add (struct ospf_area *area, struct ospf_area_range *range)  }  static void -ospf_area_range_delete (struct ospf_area *area, struct ospf_area_range *range) +ospf_area_range_delete (struct ospf_area *area, struct route_node *rn)  { -  struct route_node *rn; -  struct prefix_ipv4 p; +  struct ospf_area_range *range = rn->info; -  p.family = AF_INET; -  p.prefixlen = range->masklen; -  p.prefix = range->addr; +  if (range->specifics != 0) +    ospf_delete_discard_route (area->ospf->new_table, +			       (struct prefix_ipv4 *) &rn->p); -  rn = route_node_lookup (area->ranges, (struct prefix *)&p); -  if (rn) -    { -      ospf_area_range_free (rn->info); -      rn->info = NULL; -      route_unlock_node (rn); -      route_unlock_node (rn); -    } +  ospf_area_range_free (range); +  rn->info = NULL; +  route_unlock_node (rn); +  route_unlock_node (rn);  }  struct ospf_area_range * @@ -263,20 +258,20 @@ ospf_area_range_unset (struct ospf *ospf, struct in_addr area_id,  		       struct prefix_ipv4 *p)  {    struct ospf_area *area; -  struct ospf_area_range *range; +  struct route_node *rn;    area = ospf_area_lookup_by_area_id (ospf, area_id);    if (area == NULL)      return 0; -  range = ospf_area_range_lookup (area, p); -  if (range == NULL) +  rn = route_node_lookup (area->ranges, (struct prefix*)p); +  if (rn == NULL)      return 0; -  if (ospf_area_range_active (range)) +  if (ospf_area_range_active (rn->info))      ospf_schedule_abr_task (ospf); -  ospf_area_range_delete (area, range); +  ospf_area_range_delete (area, rn);    return 1;  } @@ -1695,7 +1690,8 @@ ospf_abr_manage_discard_routes (struct ospf *ospf)  	      ospf_add_discard_route (ospf->new_table, area,  				      (struct prefix_ipv4 *) &rn->p);  	    else -	      ospf_delete_discard_route ((struct prefix_ipv4 *) &rn->p); +	      ospf_delete_discard_route (ospf->new_table, +					 (struct prefix_ipv4 *) &rn->p);  	  }  }  | 
