From: Donald Sharp Date: Wed, 20 May 2015 01:29:19 +0000 (-0700) Subject: If the default route is removed from the BGP table we must re-evaluate "neighbor... X-Git-Tag: frr-2.0-rc1~1359 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=4125bb6716363637606aeeeacc63d42cdd97b8d1;hp=840fced957c89904faaf61b9c642ff900f4f42e7;p=mirror_frr.git If the default route is removed from the BGP table we must re-evaluate "neighbor x.x.x.x default-originate" --- diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index a0fc60f95..7ffb35c1b 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -64,7 +64,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA extern const char *bgp_origin_str[]; extern const char *bgp_origin_long_str[]; -static struct bgp_node * +struct bgp_node * bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct prefix *p, struct prefix_rd *prd) { @@ -1220,6 +1220,18 @@ subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp, return 0; } + /* Do not send the default route in the BGP table if the neighbor is + * configured for default-originate */ + if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_DEFAULT_ORIGINATE)) + { + if (p->family == AF_INET && p->u.prefix4.s_addr == INADDR_ANY) + return 0; +#ifdef HAVE_IPV6 + else if (p->family == AF_INET6 && p->prefixlen == 0) + return 0; +#endif /* HAVE_IPV6 */ + } + /* Transparency check. */ if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT) && CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)) @@ -1902,7 +1914,7 @@ subgroup_process_announce_selected (struct update_subgroup *subgrp, if (selected && subgroup_announce_check(selected, subgrp, p, &attr)) bgp_adj_out_set_subgroup(rn, subgrp, &attr, selected); else - bgp_adj_out_unset_subgroup(rn, subgrp); + bgp_adj_out_unset_subgroup(rn, subgrp, 1); break; case BGP_TABLE_RSCLIENT: @@ -1912,7 +1924,7 @@ subgroup_process_announce_selected (struct update_subgroup *subgrp, subgroup_announce_check_rsclient (selected, subgrp, p, &attr)) bgp_adj_out_set_subgroup (rn, subgrp, &attr, selected); else - bgp_adj_out_unset_subgroup(rn, subgrp); + bgp_adj_out_unset_subgroup(rn, subgrp, 1); break; } diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index c15b82406..b6c5a2511 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -230,6 +230,9 @@ extern void bgp_clear_route_all (struct peer *); extern void bgp_clear_adj_in (struct peer *, afi_t, safi_t); extern void bgp_clear_stale_route (struct peer *, afi_t, safi_t); +extern struct bgp_node *bgp_afi_node_get (struct bgp_table *table, afi_t afi, + safi_t safi, struct prefix *p, + struct prefix_rd *prd); extern struct bgp_info *bgp_info_lock (struct bgp_info *); extern struct bgp_info *bgp_info_unlock (struct bgp_info *); extern void bgp_info_add (struct bgp_node *rn, struct bgp_info *ri); diff --git a/bgpd/bgp_updgrp.h b/bgpd/bgp_updgrp.h index 6d4112822..7a980f061 100644 --- a/bgpd/bgp_updgrp.h +++ b/bgpd/bgp_updgrp.h @@ -459,7 +459,8 @@ bgp_adj_out_set_subgroup (struct bgp_node *rn, struct attr *attr, struct bgp_info *binfo); extern void bgp_adj_out_unset_subgroup (struct bgp_node *rn, - struct update_subgroup *subgrp); + struct update_subgroup *subgrp, + char withdraw); void subgroup_announce_table (struct update_subgroup *subgrp, struct bgp_table *table, int rsclient); diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c index 712e9eb06..4eeca365f 100644 --- a/bgpd/bgp_updgrp_adv.c +++ b/bgpd/bgp_updgrp_adv.c @@ -382,12 +382,18 @@ bgp_adj_out_set_subgroup (struct bgp_node *rn, subgrp->version = max (subgrp->version, rn->version); } +/* The only time 'withdraw' will be false is if we are sending + * the "neighbor x.x.x.x default-originate" default and need to clear + * bgp_adj_out for the 0.0.0.0/0 route in the BGP table. + */ void bgp_adj_out_unset_subgroup (struct bgp_node *rn, - struct update_subgroup *subgrp) + struct update_subgroup *subgrp, + char withdraw) { struct bgp_adj_out *adj; struct bgp_advertise *adv; + char trigger_write; if (DISABLE_BGP_ANNOUNCE) return; @@ -398,11 +404,11 @@ bgp_adj_out_unset_subgroup (struct bgp_node *rn, if (!adj) goto done; - /* Clearn up previous advertisement. */ + /* Clean up previous advertisement. */ if (adj->adv) bgp_advertise_clean_subgroup (subgrp, adj); - if (adj->attr) + if (adj->attr && withdraw) { /* We need advertisement structure. */ adj->adv = bgp_advertise_new (); @@ -410,12 +416,18 @@ bgp_adj_out_unset_subgroup (struct bgp_node *rn, adv->rn = rn; adv->adj = adj; - /* Schedule packet write, if FIFO is getting its first entry. */ + /* Note if we need to trigger a packet write */ if (BGP_ADV_FIFO_EMPTY (&subgrp->sync->withdraw)) - subgroup_trigger_write(subgrp); + trigger_write = 1; + else + trigger_write = 0; /* Add to synchronization entry for withdraw announcement. */ BGP_ADV_FIFO_ADD (&subgrp->sync->withdraw, &adv->fifo); + + /* Schedule packet write, if FIFO is getting its first entry. */ + if (trigger_write) + subgroup_trigger_write(subgrp); } else { @@ -510,7 +522,7 @@ subgroup_announce_table (struct update_subgroup *subgrp, && subgroup_announce_check (ri, subgrp, &rn->p, &attr)) bgp_adj_out_set_subgroup (rn, subgrp, &attr, ri); else - bgp_adj_out_unset_subgroup (rn, subgrp); + bgp_adj_out_unset_subgroup (rn, subgrp, 1); } /* @@ -680,6 +692,20 @@ subgroup_default_originate (struct update_subgroup *subgrp, int withdraw) { SET_FLAG (subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE); subgroup_default_update_packet (subgrp, &attr, from); + + /* The 'neighbor x.x.x.x default-originate' default will act as an + * implicit withdraw for any previous UPDATEs sent for 0.0.0.0/0 so + * clear adj_out for the 0.0.0.0/0 prefix in the BGP table. + */ + if (afi == AFI_IP) + str2prefix ("0.0.0.0/0", &p); +#ifdef HAVE_IPV6 + else + str2prefix ("::/0", &p); +#endif /* HAVE_IPV6 */ + + rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, &p, NULL); + bgp_adj_out_unset_subgroup (rn, subgrp, 0); } }