summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_route.c
diff options
context:
space:
mode:
authorAndrew J. Schorr <ajschorr@alumni.princeton.edu>2006-11-28 20:50:46 +0100
committerAndrew J. Schorr <ajschorr@alumni.princeton.edu>2006-11-28 20:50:46 +0100
commit8d45210e7c9e221b519d975825cb83aea5ebe47e (patch)
tree62629c7693b24c3b4a8e37eed7abe51e5695417d /bgpd/bgp_route.c
parent[ospfd] Fix bug in passive-interface default commands. (diff)
downloadfrr-8d45210e7c9e221b519d975825cb83aea5ebe47e.tar.xz
frr-8d45210e7c9e221b519d975825cb83aea5ebe47e.zip
[bgpd] Fix bug where a deleted route that was quickly re-added was being lost
2006-11-28 Andrew J. Schorr <ajschorr@alumni.princeton.edu> * bgp_route.c: (bgp_info_restore) New function that undoes the effects of a previous call to bgp_info_delete. This is used when a route is deleted and quickly re-added before the deletion has been processed. (bgp_static_update_rsclient, bgp_static_update_main, bgp_redistribute_add) Check whether a pre-existing route has the BGP_INFO_REMOVED set, and, if so, we need to call bgp_info_restore to resurrect it.
Diffstat (limited to '')
-rw-r--r--bgpd/bgp_route.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 3cae06e28..ce44842ee 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -192,6 +192,17 @@ bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri)
UNSET_FLAG (ri->flags, BGP_INFO_VALID);
}
+/* undo the effects of a previous call to bgp_info_delete; typically
+ called when a route is deleted and then quickly re-added before the
+ deletion has been processed */
+static void
+bgp_info_restore (struct bgp_node *rn, struct bgp_info *ri)
+{
+ bgp_info_unset_flag (rn, ri, BGP_INFO_REMOVED);
+ /* unset of previous already took care of pcount */
+ SET_FLAG (ri->flags, BGP_INFO_VALID);
+}
+
/* Adjust pcount as required */
static void
bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri)
@@ -3051,7 +3062,8 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
if (ri)
{
- if (attrhash_cmp (ri->attr, attr_new))
+ if (attrhash_cmp (ri->attr, attr_new) &&
+ !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
{
bgp_unlock_node (rn);
bgp_attr_unintern (attr_new);
@@ -3064,6 +3076,8 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
/* Rewrite BGP route information. */
+ if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
+ bgp_info_restore(rn, ri);
bgp_attr_unintern (ri->attr);
ri->attr = attr_new;
ri->uptime = time (NULL);
@@ -3158,7 +3172,8 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
if (ri)
{
- if (attrhash_cmp (ri->attr, attr_new))
+ if (attrhash_cmp (ri->attr, attr_new) &&
+ !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
{
bgp_unlock_node (rn);
bgp_attr_unintern (attr_new);
@@ -3171,7 +3186,10 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
/* Rewrite BGP route information. */
- bgp_aggregate_decrement (bgp, p, ri, afi, safi);
+ if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
+ bgp_info_restore(rn, ri);
+ else
+ bgp_aggregate_decrement (bgp, p, ri, afi, safi);
bgp_attr_unintern (ri->attr);
ri->attr = attr_new;
ri->uptime = time (NULL);
@@ -4952,7 +4970,8 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop,
if (bi)
{
- if (attrhash_cmp (bi->attr, new_attr))
+ if (attrhash_cmp (bi->attr, new_attr) &&
+ !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
{
bgp_attr_unintern (new_attr);
aspath_unintern (attr.aspath);
@@ -4965,7 +4984,10 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop,
bgp_info_set_flag (bn, bi, BGP_INFO_ATTR_CHANGED);
/* Rewrite BGP route information. */
- bgp_aggregate_decrement (bgp, p, bi, afi, SAFI_UNICAST);
+ if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
+ bgp_info_restore(bn, bi);
+ else
+ bgp_aggregate_decrement (bgp, p, bi, afi, SAFI_UNICAST);
bgp_attr_unintern (bi->attr);
bi->attr = new_attr;
bi->uptime = time (NULL);