summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 03:29:19 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 03:29:19 +0200
commit4125bb6716363637606aeeeacc63d42cdd97b8d1 (patch)
treeda4e4b20f5b221dac8a2a61361b8e5db3e992cef
parentBGP 'show ip bgp nei x.x.x.x advertised-route' does not display 'Originating ... (diff)
downloadfrr-4125bb6716363637606aeeeacc63d42cdd97b8d1.tar.xz
frr-4125bb6716363637606aeeeacc63d42cdd97b8d1.zip
If the default route is removed from the BGP table we must re-evaluate "neighbor x.x.x.x default-originate"
-rw-r--r--bgpd/bgp_route.c18
-rw-r--r--bgpd/bgp_route.h3
-rw-r--r--bgpd/bgp_updgrp.h3
-rw-r--r--bgpd/bgp_updgrp_adv.c38
4 files changed, 52 insertions, 10 deletions
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);
}
}