summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_route.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_route.c')
-rw-r--r--bgpd/bgp_route.c17922
1 files changed, 9058 insertions, 8864 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 9b85ad3d9..f8db12df5 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -77,119 +77,109 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
extern const char *bgp_origin_str[];
extern const char *bgp_origin_long_str[];
-struct bgp_node *
-bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct prefix *p,
- struct prefix_rd *prd)
-{
- struct bgp_node *rn;
- struct bgp_node *prn = NULL;
-
- assert (table);
- if (!table)
- return NULL;
-
- if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) ||
- (safi == SAFI_EVPN))
- {
- prn = bgp_node_get (table, (struct prefix *) prd);
-
- if (prn->info == NULL)
- prn->info = bgp_table_init (afi, safi);
- else
- bgp_unlock_node (prn);
- table = prn->info;
- }
+struct bgp_node *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
+ safi_t safi, struct prefix *p,
+ struct prefix_rd *prd)
+{
+ struct bgp_node *rn;
+ struct bgp_node *prn = NULL;
+
+ assert(table);
+ if (!table)
+ return NULL;
+
+ if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
+ || (safi == SAFI_EVPN)) {
+ prn = bgp_node_get(table, (struct prefix *)prd);
+
+ if (prn->info == NULL)
+ prn->info = bgp_table_init(afi, safi);
+ else
+ bgp_unlock_node(prn);
+ table = prn->info;
+ }
- rn = bgp_node_get (table, p);
+ rn = bgp_node_get(table, p);
- if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) ||
- (safi == SAFI_EVPN))
- rn->prn = prn;
+ if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
+ || (safi == SAFI_EVPN))
+ rn->prn = prn;
- return rn;
+ return rn;
}
/* Allocate bgp_info_extra */
-static struct bgp_info_extra *
-bgp_info_extra_new (void)
+static struct bgp_info_extra *bgp_info_extra_new(void)
{
- struct bgp_info_extra *new;
- new = XCALLOC (MTYPE_BGP_ROUTE_EXTRA, sizeof (struct bgp_info_extra));
- return new;
+ struct bgp_info_extra *new;
+ new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA, sizeof(struct bgp_info_extra));
+ return new;
}
-static void
-bgp_info_extra_free (struct bgp_info_extra **extra)
+static void bgp_info_extra_free(struct bgp_info_extra **extra)
{
- if (extra && *extra)
- {
- if ((*extra)->damp_info)
- bgp_damp_info_free ((*extra)->damp_info, 0);
-
- (*extra)->damp_info = NULL;
-
- XFREE (MTYPE_BGP_ROUTE_EXTRA, *extra);
-
- *extra = NULL;
- }
+ if (extra && *extra) {
+ if ((*extra)->damp_info)
+ bgp_damp_info_free((*extra)->damp_info, 0);
+
+ (*extra)->damp_info = NULL;
+
+ XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
+
+ *extra = NULL;
+ }
}
/* Get bgp_info extra information for the given bgp_info, lazy allocated
* if required.
*/
-struct bgp_info_extra *
-bgp_info_extra_get (struct bgp_info *ri)
+struct bgp_info_extra *bgp_info_extra_get(struct bgp_info *ri)
{
- if (!ri->extra)
- ri->extra = bgp_info_extra_new();
- return ri->extra;
+ if (!ri->extra)
+ ri->extra = bgp_info_extra_new();
+ return ri->extra;
}
/* Allocate new bgp info structure. */
-struct bgp_info *
-bgp_info_new (void)
+struct bgp_info *bgp_info_new(void)
{
- return XCALLOC (MTYPE_BGP_ROUTE, sizeof (struct bgp_info));
+ return XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_info));
}
/* Free bgp route information. */
-static void
-bgp_info_free (struct bgp_info *binfo)
+static void bgp_info_free(struct bgp_info *binfo)
{
- if (binfo->attr)
- bgp_attr_unintern (&binfo->attr);
+ if (binfo->attr)
+ bgp_attr_unintern(&binfo->attr);
- bgp_unlink_nexthop(binfo);
- bgp_info_extra_free (&binfo->extra);
- bgp_info_mpath_free (&binfo->mpath);
+ bgp_unlink_nexthop(binfo);
+ bgp_info_extra_free(&binfo->extra);
+ bgp_info_mpath_free(&binfo->mpath);
- peer_unlock (binfo->peer); /* bgp_info peer reference */
+ peer_unlock(binfo->peer); /* bgp_info peer reference */
- XFREE (MTYPE_BGP_ROUTE, binfo);
+ XFREE(MTYPE_BGP_ROUTE, binfo);
}
-struct bgp_info *
-bgp_info_lock (struct bgp_info *binfo)
+struct bgp_info *bgp_info_lock(struct bgp_info *binfo)
{
- binfo->lock++;
- return binfo;
+ binfo->lock++;
+ return binfo;
}
-struct bgp_info *
-bgp_info_unlock (struct bgp_info *binfo)
+struct bgp_info *bgp_info_unlock(struct bgp_info *binfo)
{
- assert (binfo && binfo->lock > 0);
- binfo->lock--;
-
- if (binfo->lock == 0)
- {
+ assert(binfo && binfo->lock > 0);
+ binfo->lock--;
+
+ if (binfo->lock == 0) {
#if 0
zlog_debug ("%s: unlocked and freeing", __func__);
zlog_backtrace (LOG_DEBUG);
#endif
- bgp_info_free (binfo);
- return NULL;
- }
+ bgp_info_free(binfo);
+ return NULL;
+ }
#if 0
if (binfo->lock == 1)
@@ -198,1642 +188,1664 @@ bgp_info_unlock (struct bgp_info *binfo)
zlog_backtrace (LOG_DEBUG);
}
#endif
-
- return binfo;
+
+ return binfo;
}
-void
-bgp_info_add (struct bgp_node *rn, struct bgp_info *ri)
+void bgp_info_add(struct bgp_node *rn, struct bgp_info *ri)
{
- struct bgp_info *top;
+ struct bgp_info *top;
- top = rn->info;
-
- ri->next = rn->info;
- ri->prev = NULL;
- if (top)
- top->prev = ri;
- rn->info = ri;
-
- bgp_info_lock (ri);
- bgp_lock_node (rn);
- peer_lock (ri->peer); /* bgp_info peer reference */
+ top = rn->info;
+
+ ri->next = rn->info;
+ ri->prev = NULL;
+ if (top)
+ top->prev = ri;
+ rn->info = ri;
+
+ bgp_info_lock(ri);
+ bgp_lock_node(rn);
+ peer_lock(ri->peer); /* bgp_info peer reference */
}
-/* Do the actual removal of info from RIB, for use by bgp_process
+/* Do the actual removal of info from RIB, for use by bgp_process
completion callback *only* */
-static void
-bgp_info_reap (struct bgp_node *rn, struct bgp_info *ri)
+static void bgp_info_reap(struct bgp_node *rn, struct bgp_info *ri)
{
- if (ri->next)
- ri->next->prev = ri->prev;
- if (ri->prev)
- ri->prev->next = ri->next;
- else
- rn->info = ri->next;
-
- bgp_info_mpath_dequeue (ri);
- bgp_info_unlock (ri);
- bgp_unlock_node (rn);
+ if (ri->next)
+ ri->next->prev = ri->prev;
+ if (ri->prev)
+ ri->prev->next = ri->next;
+ else
+ rn->info = ri->next;
+
+ bgp_info_mpath_dequeue(ri);
+ bgp_info_unlock(ri);
+ bgp_unlock_node(rn);
}
-void
-bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri)
+void bgp_info_delete(struct bgp_node *rn, struct bgp_info *ri)
{
- bgp_info_set_flag (rn, ri, BGP_INFO_REMOVED);
- /* set of previous already took care of pcount */
- UNSET_FLAG (ri->flags, BGP_INFO_VALID);
+ bgp_info_set_flag(rn, ri, BGP_INFO_REMOVED);
+ /* set of previous already took care of pcount */
+ 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 */
-void
-bgp_info_restore (struct bgp_node *rn, struct bgp_info *ri)
+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);
+ 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)
+/* Adjust pcount as required */
+static void bgp_pcount_adjust(struct bgp_node *rn, struct bgp_info *ri)
{
- struct bgp_table *table;
+ struct bgp_table *table;
- assert (rn && bgp_node_table (rn));
- assert (ri && ri->peer && ri->peer->bgp);
+ assert(rn && bgp_node_table(rn));
+ assert(ri && ri->peer && ri->peer->bgp);
- table = bgp_node_table (rn);
+ table = bgp_node_table(rn);
- if (ri->peer == ri->peer->bgp->peer_self)
- return;
-
- if (!BGP_INFO_COUNTABLE (ri)
- && CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
- {
-
- UNSET_FLAG (ri->flags, BGP_INFO_COUNTED);
-
- /* slight hack, but more robust against errors. */
- if (ri->peer->pcount[table->afi][table->safi])
- ri->peer->pcount[table->afi][table->safi]--;
- else
- {
- zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s",
- __func__, ri->peer->host);
- zlog_backtrace (LOG_WARNING);
- zlog_warn ("%s: Please report to Quagga bugzilla", __func__);
- }
- }
- else if (BGP_INFO_COUNTABLE (ri)
- && !CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
- {
- SET_FLAG (ri->flags, BGP_INFO_COUNTED);
- ri->peer->pcount[table->afi][table->safi]++;
- }
+ if (ri->peer == ri->peer->bgp->peer_self)
+ return;
+
+ if (!BGP_INFO_COUNTABLE(ri)
+ && CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
+
+ UNSET_FLAG(ri->flags, BGP_INFO_COUNTED);
+
+ /* slight hack, but more robust against errors. */
+ if (ri->peer->pcount[table->afi][table->safi])
+ ri->peer->pcount[table->afi][table->safi]--;
+ else {
+ zlog_warn(
+ "%s: Asked to decrement 0 prefix count for peer %s",
+ __func__, ri->peer->host);
+ zlog_backtrace(LOG_WARNING);
+ zlog_warn("%s: Please report to Quagga bugzilla",
+ __func__);
+ }
+ } else if (BGP_INFO_COUNTABLE(ri)
+ && !CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
+ SET_FLAG(ri->flags, BGP_INFO_COUNTED);
+ ri->peer->pcount[table->afi][table->safi]++;
+ }
}
/* Set/unset bgp_info flags, adjusting any other state as needed.
* This is here primarily to keep prefix-count in check.
*/
-void
-bgp_info_set_flag (struct bgp_node *rn, struct bgp_info *ri, u_int32_t flag)
+void bgp_info_set_flag(struct bgp_node *rn, struct bgp_info *ri, u_int32_t flag)
{
- SET_FLAG (ri->flags, flag);
-
- /* early bath if we know it's not a flag that changes countability state */
- if (!CHECK_FLAG (flag, BGP_INFO_VALID|BGP_INFO_HISTORY|BGP_INFO_REMOVED))
- return;
-
- bgp_pcount_adjust (rn, ri);
+ SET_FLAG(ri->flags, flag);
+
+ /* early bath if we know it's not a flag that changes countability state
+ */
+ if (!CHECK_FLAG(flag,
+ BGP_INFO_VALID | BGP_INFO_HISTORY | BGP_INFO_REMOVED))
+ return;
+
+ bgp_pcount_adjust(rn, ri);
}
-void
-bgp_info_unset_flag (struct bgp_node *rn, struct bgp_info *ri, u_int32_t flag)
+void bgp_info_unset_flag(struct bgp_node *rn, struct bgp_info *ri,
+ u_int32_t flag)
{
- UNSET_FLAG (ri->flags, flag);
-
- /* early bath if we know it's not a flag that changes countability state */
- if (!CHECK_FLAG (flag, BGP_INFO_VALID|BGP_INFO_HISTORY|BGP_INFO_REMOVED))
- return;
-
- bgp_pcount_adjust (rn, ri);
+ UNSET_FLAG(ri->flags, flag);
+
+ /* early bath if we know it's not a flag that changes countability state
+ */
+ if (!CHECK_FLAG(flag,
+ BGP_INFO_VALID | BGP_INFO_HISTORY | BGP_INFO_REMOVED))
+ return;
+
+ bgp_pcount_adjust(rn, ri);
}
/* Get MED value. If MED value is missing and "bgp bestpath
missing-as-worst" is specified, treat it as the worst value. */
-static u_int32_t
-bgp_med_value (struct attr *attr, struct bgp *bgp)
-{
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
- return attr->med;
- else
- {
- if (bgp_flag_check (bgp, BGP_FLAG_MED_MISSING_AS_WORST))
- return BGP_MED_MAX;
- else
- return 0;
- }
+static u_int32_t bgp_med_value(struct attr *attr, struct bgp *bgp)
+{
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
+ return attr->med;
+ else {
+ if (bgp_flag_check(bgp, BGP_FLAG_MED_MISSING_AS_WORST))
+ return BGP_MED_MAX;
+ else
+ return 0;
+ }
}
-void
-bgp_info_path_with_addpath_rx_str (struct bgp_info *ri, char *buf)
+void bgp_info_path_with_addpath_rx_str(struct bgp_info *ri, char *buf)
{
- if (ri->addpath_rx_id)
- sprintf(buf, "path %s (addpath rxid %d)", ri->peer->host, ri->addpath_rx_id);
- else
- sprintf(buf, "path %s", ri->peer->host);
-}
-
-/* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1. */
-static int
-bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
- int *paths_eq, struct bgp_maxpaths_cfg *mpath_cfg, int debug,
- const char *pfx_buf)
-{
- struct attr *newattr, *existattr;
- struct attr_extra *newattre, *existattre;
- bgp_peer_sort_t new_sort;
- bgp_peer_sort_t exist_sort;
- u_int32_t new_pref;
- u_int32_t exist_pref;
- u_int32_t new_med;
- u_int32_t exist_med;
- u_int32_t new_weight;
- u_int32_t exist_weight;
- uint32_t newm, existm;
- struct in_addr new_id;
- struct in_addr exist_id;
- int new_cluster;
- int exist_cluster;
- int internal_as_route;
- int confed_as_route;
- int ret;
- char new_buf[PATH_ADDPATH_STR_BUFFER];
- char exist_buf[PATH_ADDPATH_STR_BUFFER];
-
- *paths_eq = 0;
-
- /* 0. Null check. */
- if (new == NULL)
- {
- if (debug)
- zlog_debug("%s: new is NULL", pfx_buf);
- return 0;
- }
-
- if (debug)
- bgp_info_path_with_addpath_rx_str (new, new_buf);
-
- if (exist == NULL)
- {
- if (debug)
- zlog_debug("%s: %s is the initial bestpath", pfx_buf, new_buf);
- return 1;
- }
+ if (ri->addpath_rx_id)
+ sprintf(buf, "path %s (addpath rxid %d)", ri->peer->host,
+ ri->addpath_rx_id);
+ else
+ sprintf(buf, "path %s", ri->peer->host);
+}
- if (debug)
- {
- bgp_info_path_with_addpath_rx_str (exist, exist_buf);
- zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
- pfx_buf, new_buf, new->flags, exist_buf, exist->flags);
- }
+/* Compare two bgp route entity. If 'new' is preferable over 'exist' return 1.
+ */
+static int bgp_info_cmp(struct bgp *bgp, struct bgp_info *new,
+ struct bgp_info *exist, int *paths_eq,
+ struct bgp_maxpaths_cfg *mpath_cfg, int debug,
+ const char *pfx_buf)
+{
+ struct attr *newattr, *existattr;
+ struct attr_extra *newattre, *existattre;
+ bgp_peer_sort_t new_sort;
+ bgp_peer_sort_t exist_sort;
+ u_int32_t new_pref;
+ u_int32_t exist_pref;
+ u_int32_t new_med;
+ u_int32_t exist_med;
+ u_int32_t new_weight;
+ u_int32_t exist_weight;
+ uint32_t newm, existm;
+ struct in_addr new_id;
+ struct in_addr exist_id;
+ int new_cluster;
+ int exist_cluster;
+ int internal_as_route;
+ int confed_as_route;
+ int ret;
+ char new_buf[PATH_ADDPATH_STR_BUFFER];
+ char exist_buf[PATH_ADDPATH_STR_BUFFER];
+
+ *paths_eq = 0;
+
+ /* 0. Null check. */
+ if (new == NULL) {
+ if (debug)
+ zlog_debug("%s: new is NULL", pfx_buf);
+ return 0;
+ }
- newattr = new->attr;
- existattr = exist->attr;
- newattre = newattr->extra;
- existattre = existattr->extra;
+ if (debug)
+ bgp_info_path_with_addpath_rx_str(new, new_buf);
- /* 1. Weight check. */
- new_weight = exist_weight = 0;
+ if (exist == NULL) {
+ if (debug)
+ zlog_debug("%s: %s is the initial bestpath", pfx_buf,
+ new_buf);
+ return 1;
+ }
- if (newattre)
- new_weight = newattre->weight;
- if (existattre)
- exist_weight = existattre->weight;
+ if (debug) {
+ bgp_info_path_with_addpath_rx_str(exist, exist_buf);
+ zlog_debug("%s: Comparing %s flags 0x%x with %s flags 0x%x",
+ pfx_buf, new_buf, new->flags, exist_buf,
+ exist->flags);
+ }
- if (new_weight > exist_weight)
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to weight %d > %d",
- pfx_buf, new_buf, exist_buf, new_weight, exist_weight);
- return 1;
- }
+ newattr = new->attr;
+ existattr = exist->attr;
+ newattre = newattr->extra;
+ existattre = existattr->extra;
+
+ /* 1. Weight check. */
+ new_weight = exist_weight = 0;
+
+ if (newattre)
+ new_weight = newattre->weight;
+ if (existattre)
+ exist_weight = existattre->weight;
+
+ if (new_weight > exist_weight) {
+ if (debug)
+ zlog_debug("%s: %s wins over %s due to weight %d > %d",
+ pfx_buf, new_buf, exist_buf, new_weight,
+ exist_weight);
+ return 1;
+ }
- if (new_weight < exist_weight)
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to weight %d < %d",
- pfx_buf, new_buf, exist_buf, new_weight, exist_weight);
- return 0;
- }
+ if (new_weight < exist_weight) {
+ if (debug)
+ zlog_debug("%s: %s loses to %s due to weight %d < %d",
+ pfx_buf, new_buf, exist_buf, new_weight,
+ exist_weight);
+ return 0;
+ }
- /* 2. Local preference check. */
- new_pref = exist_pref = bgp->default_local_pref;
+ /* 2. Local preference check. */
+ new_pref = exist_pref = bgp->default_local_pref;
+
+ if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
+ new_pref = newattr->local_pref;
+ if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
+ exist_pref = existattr->local_pref;
+
+ if (new_pref > exist_pref) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to localpref %d > %d",
+ pfx_buf, new_buf, exist_buf, new_pref,
+ exist_pref);
+ return 1;
+ }
- if (newattr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
- new_pref = newattr->local_pref;
- if (existattr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
- exist_pref = existattr->local_pref;
+ if (new_pref < exist_pref) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to localpref %d < %d",
+ pfx_buf, new_buf, exist_buf, new_pref,
+ exist_pref);
+ return 0;
+ }
- if (new_pref > exist_pref)
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to localpref %d > %d",
- pfx_buf, new_buf, exist_buf, new_pref, exist_pref);
- return 1;
- }
+ /* 3. Local route check. We prefer:
+ * - BGP_ROUTE_STATIC
+ * - BGP_ROUTE_AGGREGATE
+ * - BGP_ROUTE_REDISTRIBUTE
+ */
+ if (!(new->sub_type == BGP_ROUTE_NORMAL)) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to preferred BGP_ROUTE type",
+ pfx_buf, new_buf, exist_buf);
+ return 1;
+ }
- if (new_pref < exist_pref)
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to localpref %d < %d",
- pfx_buf, new_buf, exist_buf, new_pref, exist_pref);
- return 0;
- }
+ if (!(exist->sub_type == BGP_ROUTE_NORMAL)) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to preferred BGP_ROUTE type",
+ pfx_buf, new_buf, exist_buf);
+ return 0;
+ }
- /* 3. Local route check. We prefer:
- * - BGP_ROUTE_STATIC
- * - BGP_ROUTE_AGGREGATE
- * - BGP_ROUTE_REDISTRIBUTE
- */
- if (! (new->sub_type == BGP_ROUTE_NORMAL))
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to preferred BGP_ROUTE type",
- pfx_buf, new_buf, exist_buf);
- return 1;
- }
+ /* 4. AS path length check. */
+ if (!bgp_flag_check(bgp, BGP_FLAG_ASPATH_IGNORE)) {
+ int exist_hops = aspath_count_hops(existattr->aspath);
+ int exist_confeds = aspath_count_confeds(existattr->aspath);
+
+ if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_CONFED)) {
+ int aspath_hops;
+
+ aspath_hops = aspath_count_hops(newattr->aspath);
+ aspath_hops += aspath_count_confeds(newattr->aspath);
+
+ if (aspath_hops < (exist_hops + exist_confeds)) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
+ pfx_buf, new_buf, exist_buf,
+ aspath_hops,
+ (exist_hops + exist_confeds));
+ return 1;
+ }
+
+ if (aspath_hops > (exist_hops + exist_confeds)) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
+ pfx_buf, new_buf, exist_buf,
+ aspath_hops,
+ (exist_hops + exist_confeds));
+ return 0;
+ }
+ } else {
+ int newhops = aspath_count_hops(newattr->aspath);
+
+ if (newhops < exist_hops) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to aspath hopcount %d < %d",
+ pfx_buf, new_buf, exist_buf,
+ newhops, exist_hops);
+ return 1;
+ }
+
+ if (newhops > exist_hops) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to aspath hopcount %d > %d",
+ pfx_buf, new_buf, exist_buf,
+ newhops, exist_hops);
+ return 0;
+ }
+ }
+ }
- if (! (exist->sub_type == BGP_ROUTE_NORMAL))
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to preferred BGP_ROUTE type",
- pfx_buf, new_buf, exist_buf);
- return 0;
- }
+ /* 5. Origin check. */
+ if (newattr->origin < existattr->origin) {
+ if (debug)
+ zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
+ pfx_buf, new_buf, exist_buf,
+ bgp_origin_long_str[newattr->origin],
+ bgp_origin_long_str[existattr->origin]);
+ return 1;
+ }
- /* 4. AS path length check. */
- if (! bgp_flag_check (bgp, BGP_FLAG_ASPATH_IGNORE))
- {
- int exist_hops = aspath_count_hops (existattr->aspath);
- int exist_confeds = aspath_count_confeds (existattr->aspath);
-
- if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
- {
- int aspath_hops;
-
- aspath_hops = aspath_count_hops (newattr->aspath);
- aspath_hops += aspath_count_confeds (newattr->aspath);
-
- if ( aspath_hops < (exist_hops + exist_confeds))
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to aspath (with confeds) hopcount %d < %d",
- pfx_buf, new_buf, exist_buf,
- aspath_hops, (exist_hops + exist_confeds));
- return 1;
- }
-
- if ( aspath_hops > (exist_hops + exist_confeds))
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to aspath (with confeds) hopcount %d > %d",
- pfx_buf, new_buf, exist_buf,
- aspath_hops, (exist_hops + exist_confeds));
- return 0;
- }
- }
- else
- {
- int newhops = aspath_count_hops (newattr->aspath);
-
- if (newhops < exist_hops)
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to aspath hopcount %d < %d",
- pfx_buf, new_buf, exist_buf, newhops, exist_hops);
- return 1;
- }
-
- if (newhops > exist_hops)
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to aspath hopcount %d > %d",
- pfx_buf, new_buf, exist_buf, newhops, exist_hops);
- return 0;
- }
+ if (newattr->origin > existattr->origin) {
+ if (debug)
+ zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
+ pfx_buf, new_buf, exist_buf,
+ bgp_origin_long_str[newattr->origin],
+ bgp_origin_long_str[existattr->origin]);
+ return 0;
}
- }
- /* 5. Origin check. */
- if (newattr->origin < existattr->origin)
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to ORIGIN %s < %s",
- pfx_buf, new_buf, exist_buf,
- bgp_origin_long_str[newattr->origin],
- bgp_origin_long_str[existattr->origin]);
- return 1;
- }
+ /* 6. MED check. */
+ internal_as_route = (aspath_count_hops(newattr->aspath) == 0
+ && aspath_count_hops(existattr->aspath) == 0);
+ confed_as_route = (aspath_count_confeds(newattr->aspath) > 0
+ && aspath_count_confeds(existattr->aspath) > 0
+ && aspath_count_hops(newattr->aspath) == 0
+ && aspath_count_hops(existattr->aspath) == 0);
+
+ if (bgp_flag_check(bgp, BGP_FLAG_ALWAYS_COMPARE_MED)
+ || (bgp_flag_check(bgp, BGP_FLAG_MED_CONFED) && confed_as_route)
+ || aspath_cmp_left(newattr->aspath, existattr->aspath)
+ || aspath_cmp_left_confed(newattr->aspath, existattr->aspath)
+ || internal_as_route) {
+ new_med = bgp_med_value(new->attr, bgp);
+ exist_med = bgp_med_value(exist->attr, bgp);
+
+ if (new_med < exist_med) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to MED %d < %d",
+ pfx_buf, new_buf, exist_buf, new_med,
+ exist_med);
+ return 1;
+ }
- if (newattr->origin > existattr->origin)
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to ORIGIN %s > %s",
- pfx_buf, new_buf, exist_buf,
- bgp_origin_long_str[newattr->origin],
- bgp_origin_long_str[existattr->origin]);
- return 0;
- }
+ if (new_med > exist_med) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to MED %d > %d",
+ pfx_buf, new_buf, exist_buf, new_med,
+ exist_med);
+ return 0;
+ }
+ }
- /* 6. MED check. */
- internal_as_route = (aspath_count_hops (newattr->aspath) == 0
- && aspath_count_hops (existattr->aspath) == 0);
- confed_as_route = (aspath_count_confeds (newattr->aspath) > 0
- && aspath_count_confeds (existattr->aspath) > 0
- && aspath_count_hops (newattr->aspath) == 0
- && aspath_count_hops (existattr->aspath) == 0);
-
- if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED)
- || (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
- && confed_as_route)
- || aspath_cmp_left (newattr->aspath, existattr->aspath)
- || aspath_cmp_left_confed (newattr->aspath, existattr->aspath)
- || internal_as_route)
- {
- new_med = bgp_med_value (new->attr, bgp);
- exist_med = bgp_med_value (exist->attr, bgp);
-
- if (new_med < exist_med)
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to MED %d < %d",
- pfx_buf, new_buf, exist_buf, new_med, exist_med);
- return 1;
- }
-
- if (new_med > exist_med)
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to MED %d > %d",
- pfx_buf, new_buf, exist_buf, new_med, exist_med);
- return 0;
- }
- }
+ /* 7. Peer type check. */
+ new_sort = new->peer->sort;
+ exist_sort = exist->peer->sort;
+
+ if (new_sort == BGP_PEER_EBGP
+ && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED)) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to eBGP peer > iBGP peer",
+ pfx_buf, new_buf, exist_buf);
+ return 1;
+ }
- /* 7. Peer type check. */
- new_sort = new->peer->sort;
- exist_sort = exist->peer->sort;
+ if (exist_sort == BGP_PEER_EBGP
+ && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED)) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to iBGP peer < eBGP peer",
+ pfx_buf, new_buf, exist_buf);
+ return 0;
+ }
- if (new_sort == BGP_PEER_EBGP
- && (exist_sort == BGP_PEER_IBGP || exist_sort == BGP_PEER_CONFED))
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to eBGP peer > iBGP peer",
- pfx_buf, new_buf, exist_buf);
- return 1;
- }
+ /* 8. IGP metric check. */
+ newm = existm = 0;
- if (exist_sort == BGP_PEER_EBGP
- && (new_sort == BGP_PEER_IBGP || new_sort == BGP_PEER_CONFED))
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to iBGP peer < eBGP peer",
- pfx_buf, new_buf, exist_buf);
- return 0;
- }
+ if (new->extra)
+ newm = new->extra->igpmetric;
+ if (exist->extra)
+ existm = exist->extra->igpmetric;
- /* 8. IGP metric check. */
- newm = existm = 0;
+ if (newm < existm) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to IGP metric %d < %d",
+ pfx_buf, new_buf, exist_buf, newm, existm);
+ ret = 1;
+ }
- if (new->extra)
- newm = new->extra->igpmetric;
- if (exist->extra)
- existm = exist->extra->igpmetric;
+ if (newm > existm) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to IGP metric %d > %d",
+ pfx_buf, new_buf, exist_buf, newm, existm);
+ ret = 0;
+ }
- if (newm < existm)
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to IGP metric %d < %d",
- pfx_buf, new_buf, exist_buf, newm, existm);
- ret = 1;
- }
+ /* 9. Same IGP metric. Compare the cluster list length as
+ representative of IGP hops metric. Rewrite the metric value
+ pair (newm, existm) with the cluster list length. Prefer the
+ path with smaller cluster list length. */
+ if (newm == existm) {
+ if (peer_sort(new->peer) == BGP_PEER_IBGP
+ && peer_sort(exist->peer) == BGP_PEER_IBGP
+ && (mpath_cfg == NULL
+ || CHECK_FLAG(
+ mpath_cfg->ibgp_flags,
+ BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN))) {
+ newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
+ existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
+
+ if (newm < existm) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
+ pfx_buf, new_buf, exist_buf,
+ newm, existm);
+ ret = 1;
+ }
+
+ if (newm > existm) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
+ pfx_buf, new_buf, exist_buf,
+ newm, existm);
+ ret = 0;
+ }
+ }
+ }
- if (newm > existm)
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to IGP metric %d > %d",
- pfx_buf, new_buf, exist_buf, newm, existm);
- ret = 0;
- }
+ /* 10. confed-external vs. confed-internal */
+ if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
+ if (new_sort == BGP_PEER_CONFED
+ && exist_sort == BGP_PEER_IBGP) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to confed-external peer > confed-internal peer",
+ pfx_buf, new_buf, exist_buf);
+ return 1;
+ }
- /* 9. Same IGP metric. Compare the cluster list length as
- representative of IGP hops metric. Rewrite the metric value
- pair (newm, existm) with the cluster list length. Prefer the
- path with smaller cluster list length. */
- if (newm == existm)
- {
- if (peer_sort (new->peer) == BGP_PEER_IBGP
- && peer_sort (exist->peer) == BGP_PEER_IBGP
- && (mpath_cfg == NULL ||
- CHECK_FLAG (mpath_cfg->ibgp_flags,
- BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN)))
- {
- newm = BGP_CLUSTER_LIST_LENGTH(new->attr);
- existm = BGP_CLUSTER_LIST_LENGTH(exist->attr);
-
- if (newm < existm)
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
- pfx_buf, new_buf, exist_buf, newm, existm);
- ret = 1;
- }
-
- if (newm > existm)
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
- pfx_buf, new_buf, exist_buf, newm, existm);
- ret = 0;
- }
+ if (exist_sort == BGP_PEER_CONFED
+ && new_sort == BGP_PEER_IBGP) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to confed-internal peer < confed-external peer",
+ pfx_buf, new_buf, exist_buf);
+ return 0;
+ }
}
- }
- /* 10. confed-external vs. confed-internal */
- if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
- {
- if (new_sort == BGP_PEER_CONFED && exist_sort == BGP_PEER_IBGP)
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to confed-external peer > confed-internal peer",
- pfx_buf, new_buf, exist_buf);
- return 1;
- }
-
- if (exist_sort == BGP_PEER_CONFED && new_sort == BGP_PEER_IBGP)
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to confed-internal peer < confed-external peer",
- pfx_buf, new_buf, exist_buf);
- return 0;
- }
- }
-
- /* 11. Maximum path check. */
- if (newm == existm)
- {
- if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX))
- {
-
- /*
- * For the two paths, all comparison steps till IGP metric
- * have succeeded - including AS_PATH hop count. Since 'bgp
- * bestpath as-path multipath-relax' knob is on, we don't need
- * an exact match of AS_PATH. Thus, mark the paths are equal.
- * That will trigger both these paths to get into the multipath
- * array.
- */
- *paths_eq = 1;
-
- if (debug)
- zlog_debug("%s: %s and %s are equal via multipath-relax",
- pfx_buf, new_buf, exist_buf);
- }
- else if (new->peer->sort == BGP_PEER_IBGP)
- {
- if (aspath_cmp (new->attr->aspath, exist->attr->aspath))
- {
- *paths_eq = 1;
-
- if (debug)
- zlog_debug("%s: %s and %s are equal via matching aspaths",
- pfx_buf, new_buf, exist_buf);
- }
- }
- else if (new->peer->as == exist->peer->as)
- {
- *paths_eq = 1;
-
- if (debug)
- zlog_debug("%s: %s and %s are equal via same remote-as",
- pfx_buf, new_buf, exist_buf);
- }
- }
- else
- {
- /*
- * TODO: If unequal cost ibgp multipath is enabled we can
- * mark the paths as equal here instead of returning
- */
- if (debug)
- {
- if (ret == 1)
- zlog_debug("%s: %s wins over %s after IGP metric comparison",
- pfx_buf, new_buf, exist_buf);
- else
- zlog_debug("%s: %s loses to %s after IGP metric comparison",
- pfx_buf, new_buf, exist_buf);
- }
- return ret;
- }
+ /* 11. Maximum path check. */
+ if (newm == existm) {
+ if (bgp_flag_check(bgp, BGP_FLAG_ASPATH_MULTIPATH_RELAX)) {
+
+ /*
+ * For the two paths, all comparison steps till IGP
+ * metric
+ * have succeeded - including AS_PATH hop count. Since
+ * 'bgp
+ * bestpath as-path multipath-relax' knob is on, we
+ * don't need
+ * an exact match of AS_PATH. Thus, mark the paths are
+ * equal.
+ * That will trigger both these paths to get into the
+ * multipath
+ * array.
+ */
+ *paths_eq = 1;
+
+ if (debug)
+ zlog_debug(
+ "%s: %s and %s are equal via multipath-relax",
+ pfx_buf, new_buf, exist_buf);
+ } else if (new->peer->sort == BGP_PEER_IBGP) {
+ if (aspath_cmp(new->attr->aspath,
+ exist->attr->aspath)) {
+ *paths_eq = 1;
+
+ if (debug)
+ zlog_debug(
+ "%s: %s and %s are equal via matching aspaths",
+ pfx_buf, new_buf, exist_buf);
+ }
+ } else if (new->peer->as == exist->peer->as) {
+ *paths_eq = 1;
+
+ if (debug)
+ zlog_debug(
+ "%s: %s and %s are equal via same remote-as",
+ pfx_buf, new_buf, exist_buf);
+ }
+ } else {
+ /*
+ * TODO: If unequal cost ibgp multipath is enabled we can
+ * mark the paths as equal here instead of returning
+ */
+ if (debug) {
+ if (ret == 1)
+ zlog_debug(
+ "%s: %s wins over %s after IGP metric comparison",
+ pfx_buf, new_buf, exist_buf);
+ else
+ zlog_debug(
+ "%s: %s loses to %s after IGP metric comparison",
+ pfx_buf, new_buf, exist_buf);
+ }
+ return ret;
+ }
- /* 12. If both paths are external, prefer the path that was received
- first (the oldest one). This step minimizes route-flap, since a
- newer path won't displace an older one, even if it was the
- preferred route based on the additional decision criteria below. */
- if (! bgp_flag_check (bgp, BGP_FLAG_COMPARE_ROUTER_ID)
- && new_sort == BGP_PEER_EBGP
- && exist_sort == BGP_PEER_EBGP)
- {
- if (CHECK_FLAG (new->flags, BGP_INFO_SELECTED))
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to oldest external",
- pfx_buf, new_buf, exist_buf);
- return 1;
- }
-
- if (CHECK_FLAG (exist->flags, BGP_INFO_SELECTED))
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to oldest external",
- pfx_buf, new_buf, exist_buf);
- return 0;
- }
- }
+ /* 12. If both paths are external, prefer the path that was received
+ first (the oldest one). This step minimizes route-flap, since a
+ newer path won't displace an older one, even if it was the
+ preferred route based on the additional decision criteria below. */
+ if (!bgp_flag_check(bgp, BGP_FLAG_COMPARE_ROUTER_ID)
+ && new_sort == BGP_PEER_EBGP && exist_sort == BGP_PEER_EBGP) {
+ if (CHECK_FLAG(new->flags, BGP_INFO_SELECTED)) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to oldest external",
+ pfx_buf, new_buf, exist_buf);
+ return 1;
+ }
- /* 13. Router-ID comparision. */
- /* If one of the paths is "stale", the corresponding peer router-id will
- * be 0 and would always win over the other path. If originator id is
- * used for the comparision, it will decide which path is better.
- */
- if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
- new_id.s_addr = newattre->originator_id.s_addr;
- else
- new_id.s_addr = new->peer->remote_id.s_addr;
- if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
- exist_id.s_addr = existattre->originator_id.s_addr;
- else
- exist_id.s_addr = exist->peer->remote_id.s_addr;
+ if (CHECK_FLAG(exist->flags, BGP_INFO_SELECTED)) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to oldest external",
+ pfx_buf, new_buf, exist_buf);
+ return 0;
+ }
+ }
- if (ntohl (new_id.s_addr) < ntohl (exist_id.s_addr))
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to Router-ID comparison",
- pfx_buf, new_buf, exist_buf);
- return 1;
- }
+ /* 13. Router-ID comparision. */
+ /* If one of the paths is "stale", the corresponding peer router-id will
+ * be 0 and would always win over the other path. If originator id is
+ * used for the comparision, it will decide which path is better.
+ */
+ if (newattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
+ new_id.s_addr = newattre->originator_id.s_addr;
+ else
+ new_id.s_addr = new->peer->remote_id.s_addr;
+ if (existattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
+ exist_id.s_addr = existattre->originator_id.s_addr;
+ else
+ exist_id.s_addr = exist->peer->remote_id.s_addr;
+
+ if (ntohl(new_id.s_addr) < ntohl(exist_id.s_addr)) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to Router-ID comparison",
+ pfx_buf, new_buf, exist_buf);
+ return 1;
+ }
- if (ntohl (new_id.s_addr) > ntohl (exist_id.s_addr))
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to Router-ID comparison",
- pfx_buf, new_buf, exist_buf);
- return 0;
- }
+ if (ntohl(new_id.s_addr) > ntohl(exist_id.s_addr)) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to Router-ID comparison",
+ pfx_buf, new_buf, exist_buf);
+ return 0;
+ }
- /* 14. Cluster length comparision. */
- new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
- exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
+ /* 14. Cluster length comparision. */
+ new_cluster = BGP_CLUSTER_LIST_LENGTH(new->attr);
+ exist_cluster = BGP_CLUSTER_LIST_LENGTH(exist->attr);
+
+ if (new_cluster < exist_cluster) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
+ pfx_buf, new_buf, exist_buf, new_cluster,
+ exist_cluster);
+ return 1;
+ }
- if (new_cluster < exist_cluster)
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to CLUSTER_LIST length %d < %d",
- pfx_buf, new_buf, exist_buf, new_cluster, exist_cluster);
- return 1;
- }
+ if (new_cluster > exist_cluster) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
+ pfx_buf, new_buf, exist_buf, new_cluster,
+ exist_cluster);
+ return 0;
+ }
- if (new_cluster > exist_cluster)
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to CLUSTER_LIST length %d > %d",
- pfx_buf, new_buf, exist_buf, new_cluster, exist_cluster);
- return 0;
- }
+ /* 15. Neighbor address comparision. */
+ /* Do this only if neither path is "stale" as stale paths do not have
+ * valid peer information (as the connection may or may not be up).
+ */
+ if (CHECK_FLAG(exist->flags, BGP_INFO_STALE)) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to latter path being STALE",
+ pfx_buf, new_buf, exist_buf);
+ return 1;
+ }
- /* 15. Neighbor address comparision. */
- /* Do this only if neither path is "stale" as stale paths do not have
- * valid peer information (as the connection may or may not be up).
- */
- if (CHECK_FLAG (exist->flags, BGP_INFO_STALE))
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to latter path being STALE",
- pfx_buf, new_buf, exist_buf);
- return 1;
- }
+ if (CHECK_FLAG(new->flags, BGP_INFO_STALE)) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to former path being STALE",
+ pfx_buf, new_buf, exist_buf);
+ return 0;
+ }
- if (CHECK_FLAG (new->flags, BGP_INFO_STALE))
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to former path being STALE",
- pfx_buf, new_buf, exist_buf);
- return 0;
- }
+ /* locally configured routes to advertise do not have su_remote */
+ if (new->peer->su_remote == NULL)
+ return 0;
+ if (exist->peer->su_remote == NULL)
+ return 1;
- /* locally configured routes to advertise do not have su_remote */
- if (new->peer->su_remote == NULL)
- return 0;
- if (exist->peer->su_remote == NULL)
- return 1;
-
- ret = sockunion_cmp (new->peer->su_remote, exist->peer->su_remote);
+ ret = sockunion_cmp(new->peer->su_remote, exist->peer->su_remote);
- if (ret == 1)
- {
- if (debug)
- zlog_debug("%s: %s loses to %s due to Neighor IP comparison",
- pfx_buf, new_buf, exist_buf);
- return 0;
- }
+ if (ret == 1) {
+ if (debug)
+ zlog_debug(
+ "%s: %s loses to %s due to Neighor IP comparison",
+ pfx_buf, new_buf, exist_buf);
+ return 0;
+ }
- if (ret == -1)
- {
- if (debug)
- zlog_debug("%s: %s wins over %s due to Neighor IP comparison",
- pfx_buf, new_buf, exist_buf);
- return 1;
- }
+ if (ret == -1) {
+ if (debug)
+ zlog_debug(
+ "%s: %s wins over %s due to Neighor IP comparison",
+ pfx_buf, new_buf, exist_buf);
+ return 1;
+ }
- if (debug)
- zlog_debug("%s: %s wins over %s due to nothing left to compare",
- pfx_buf, new_buf, exist_buf);
+ if (debug)
+ zlog_debug("%s: %s wins over %s due to nothing left to compare",
+ pfx_buf, new_buf, exist_buf);
- return 1;
+ return 1;
}
/* Compare two bgp route entity. Return -1 if new is preferred, 1 if exist
* is preferred, or 0 if they are the same (usually will only occur if
- * multipath is enabled
+ * multipath is enabled
* This version is compatible with */
-int
-bgp_info_cmp_compatible (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist,
- afi_t afi, safi_t safi)
-{
- int paths_eq;
- int ret;
- ret = bgp_info_cmp (bgp, new, exist, &paths_eq, NULL, 0, __func__);
-
- if (paths_eq)
- ret = 0;
- else
- {
- if (ret == 1)
- ret = -1;
- else
- ret = 1;
- }
- return ret;
+int bgp_info_cmp_compatible(struct bgp *bgp, struct bgp_info *new,
+ struct bgp_info *exist, afi_t afi, safi_t safi)
+{
+ int paths_eq;
+ int ret;
+ ret = bgp_info_cmp(bgp, new, exist, &paths_eq, NULL, 0, __func__);
+
+ if (paths_eq)
+ ret = 0;
+ else {
+ if (ret == 1)
+ ret = -1;
+ else
+ ret = 1;
+ }
+ return ret;
}
-static enum filter_type
-bgp_input_filter (struct peer *peer, struct prefix *p, struct attr *attr,
- afi_t afi, safi_t safi)
+static enum filter_type bgp_input_filter(struct peer *peer, struct prefix *p,
+ struct attr *attr, afi_t afi,
+ safi_t safi)
{
- struct bgp_filter *filter;
+ struct bgp_filter *filter;
- filter = &peer->filter[afi][safi];
+ filter = &peer->filter[afi][safi];
-#define FILTER_EXIST_WARN(F,f,filter) \
- if (BGP_DEBUG (update, UPDATE_IN) \
- && !(F ## _IN (filter))) \
- zlog_warn ("%s: Could not find configured input %s-list %s!", \
- peer->host, #f, F ## _IN_NAME(filter));
-
- if (DISTRIBUTE_IN_NAME (filter)) {
- FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
-
- if (access_list_apply (DISTRIBUTE_IN (filter), p) == FILTER_DENY)
- return FILTER_DENY;
- }
-
- if (PREFIX_LIST_IN_NAME (filter)) {
- FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
-
- if (prefix_list_apply (PREFIX_LIST_IN (filter), p) == PREFIX_DENY)
- return FILTER_DENY;
- }
-
- if (FILTER_LIST_IN_NAME (filter)) {
- FILTER_EXIST_WARN(FILTER_LIST, as, filter);
-
- if (as_list_apply (FILTER_LIST_IN (filter), attr->aspath)== AS_FILTER_DENY)
- return FILTER_DENY;
- }
-
- return FILTER_PERMIT;
+#define FILTER_EXIST_WARN(F, f, filter) \
+ if (BGP_DEBUG(update, UPDATE_IN) && !(F##_IN(filter))) \
+ zlog_warn("%s: Could not find configured input %s-list %s!", \
+ peer->host, #f, F##_IN_NAME(filter));
+
+ if (DISTRIBUTE_IN_NAME(filter)) {
+ FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
+
+ if (access_list_apply(DISTRIBUTE_IN(filter), p) == FILTER_DENY)
+ return FILTER_DENY;
+ }
+
+ if (PREFIX_LIST_IN_NAME(filter)) {
+ FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
+
+ if (prefix_list_apply(PREFIX_LIST_IN(filter), p) == PREFIX_DENY)
+ return FILTER_DENY;
+ }
+
+ if (FILTER_LIST_IN_NAME(filter)) {
+ FILTER_EXIST_WARN(FILTER_LIST, as, filter);
+
+ if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
+ == AS_FILTER_DENY)
+ return FILTER_DENY;
+ }
+
+ return FILTER_PERMIT;
#undef FILTER_EXIST_WARN
}
-static enum filter_type
-bgp_output_filter (struct peer *peer, struct prefix *p, struct attr *attr,
- afi_t afi, safi_t safi)
+static enum filter_type bgp_output_filter(struct peer *peer, struct prefix *p,
+ struct attr *attr, afi_t afi,
+ safi_t safi)
{
- struct bgp_filter *filter;
+ struct bgp_filter *filter;
- filter = &peer->filter[afi][safi];
+ filter = &peer->filter[afi][safi];
-#define FILTER_EXIST_WARN(F,f,filter) \
- if (BGP_DEBUG (update, UPDATE_OUT) \
- && !(F ## _OUT (filter))) \
- zlog_warn ("%s: Could not find configured output %s-list %s!", \
- peer->host, #f, F ## _OUT_NAME(filter));
+#define FILTER_EXIST_WARN(F, f, filter) \
+ if (BGP_DEBUG(update, UPDATE_OUT) && !(F##_OUT(filter))) \
+ zlog_warn("%s: Could not find configured output %s-list %s!", \
+ peer->host, #f, F##_OUT_NAME(filter));
- if (DISTRIBUTE_OUT_NAME (filter)) {
- FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
-
- if (access_list_apply (DISTRIBUTE_OUT (filter), p) == FILTER_DENY)
- return FILTER_DENY;
- }
+ if (DISTRIBUTE_OUT_NAME(filter)) {
+ FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
- if (PREFIX_LIST_OUT_NAME (filter)) {
- FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
-
- if (prefix_list_apply (PREFIX_LIST_OUT (filter), p) == PREFIX_DENY)
- return FILTER_DENY;
- }
+ if (access_list_apply(DISTRIBUTE_OUT(filter), p) == FILTER_DENY)
+ return FILTER_DENY;
+ }
+
+ if (PREFIX_LIST_OUT_NAME(filter)) {
+ FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
- if (FILTER_LIST_OUT_NAME (filter)) {
- FILTER_EXIST_WARN(FILTER_LIST, as, filter);
-
- if (as_list_apply (FILTER_LIST_OUT (filter), attr->aspath) == AS_FILTER_DENY)
- return FILTER_DENY;
- }
+ if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
+ == PREFIX_DENY)
+ return FILTER_DENY;
+ }
- return FILTER_PERMIT;
+ if (FILTER_LIST_OUT_NAME(filter)) {
+ FILTER_EXIST_WARN(FILTER_LIST, as, filter);
+
+ if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
+ == AS_FILTER_DENY)
+ return FILTER_DENY;
+ }
+
+ return FILTER_PERMIT;
#undef FILTER_EXIST_WARN
}
/* If community attribute includes no_export then return 1. */
-static int
-bgp_community_filter (struct peer *peer, struct attr *attr)
-{
- if (attr->community)
- {
- /* NO_ADVERTISE check. */
- if (community_include (attr->community, COMMUNITY_NO_ADVERTISE))
- return 1;
-
- /* NO_EXPORT check. */
- if (peer->sort == BGP_PEER_EBGP &&
- community_include (attr->community, COMMUNITY_NO_EXPORT))
- return 1;
-
- /* NO_EXPORT_SUBCONFED check. */
- if (peer->sort == BGP_PEER_EBGP
- || peer->sort == BGP_PEER_CONFED)
- if (community_include (attr->community, COMMUNITY_NO_EXPORT_SUBCONFED))
- return 1;
- }
- return 0;
+static int bgp_community_filter(struct peer *peer, struct attr *attr)
+{
+ if (attr->community) {
+ /* NO_ADVERTISE check. */
+ if (community_include(attr->community, COMMUNITY_NO_ADVERTISE))
+ return 1;
+
+ /* NO_EXPORT check. */
+ if (peer->sort == BGP_PEER_EBGP
+ && community_include(attr->community, COMMUNITY_NO_EXPORT))
+ return 1;
+
+ /* NO_EXPORT_SUBCONFED check. */
+ if (peer->sort == BGP_PEER_EBGP
+ || peer->sort == BGP_PEER_CONFED)
+ if (community_include(attr->community,
+ COMMUNITY_NO_EXPORT_SUBCONFED))
+ return 1;
+ }
+ return 0;
}
/* Route reflection loop check. */
-static int
-bgp_cluster_filter (struct peer *peer, struct attr *attr)
+static int bgp_cluster_filter(struct peer *peer, struct attr *attr)
{
- struct in_addr cluster_id;
+ struct in_addr cluster_id;
- if (attr->extra && attr->extra->cluster)
- {
- if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
- cluster_id = peer->bgp->cluster_id;
- else
- cluster_id = peer->bgp->router_id;
-
- if (cluster_loop_check (attr->extra->cluster, cluster_id))
- return 1;
- }
- return 0;
+ if (attr->extra && attr->extra->cluster) {
+ if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
+ cluster_id = peer->bgp->cluster_id;
+ else
+ cluster_id = peer->bgp->router_id;
+
+ if (cluster_loop_check(attr->extra->cluster, cluster_id))
+ return 1;
+ }
+ return 0;
}
-static int
-bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
- afi_t afi, safi_t safi, const char *rmap_name)
+static int bgp_input_modifier(struct peer *peer, struct prefix *p,
+ struct attr *attr, afi_t afi, safi_t safi,
+ const char *rmap_name)
{
- struct bgp_filter *filter;
- struct bgp_info info;
- route_map_result_t ret;
- struct route_map *rmap = NULL;
+ struct bgp_filter *filter;
+ struct bgp_info info;
+ route_map_result_t ret;
+ struct route_map *rmap = NULL;
- filter = &peer->filter[afi][safi];
+ filter = &peer->filter[afi][safi];
- /* Apply default weight value. */
- if (peer->weight[afi][safi])
- (bgp_attr_extra_get (attr))->weight = peer->weight[afi][safi];
+ /* Apply default weight value. */
+ if (peer->weight[afi][safi])
+ (bgp_attr_extra_get(attr))->weight = peer->weight[afi][safi];
- if (rmap_name)
- {
- rmap = route_map_lookup_by_name(rmap_name);
+ if (rmap_name) {
+ rmap = route_map_lookup_by_name(rmap_name);
- if (rmap == NULL)
- return RMAP_DENY;
- }
- else
- {
- if (ROUTE_MAP_IN_NAME(filter))
- {
- rmap = ROUTE_MAP_IN (filter);
+ if (rmap == NULL)
+ return RMAP_DENY;
+ } else {
+ if (ROUTE_MAP_IN_NAME(filter)) {
+ rmap = ROUTE_MAP_IN(filter);
- if (rmap == NULL)
- return RMAP_DENY;
- }
- }
+ if (rmap == NULL)
+ return RMAP_DENY;
+ }
+ }
- /* Route map apply. */
- if (rmap)
- {
- /* Duplicate current value to new strucutre for modification. */
- info.peer = peer;
- info.attr = attr;
+ /* Route map apply. */
+ if (rmap) {
+ /* Duplicate current value to new strucutre for modification. */
+ info.peer = peer;
+ info.attr = attr;
- SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN);
+ SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
- /* Apply BGP route map to the attribute. */
- ret = route_map_apply (rmap, p, RMAP_BGP, &info);
+ /* Apply BGP route map to the attribute. */
+ ret = route_map_apply(rmap, p, RMAP_BGP, &info);
- peer->rmap_type = 0;
+ peer->rmap_type = 0;
- if (ret == RMAP_DENYMATCH)
- {
- /* Free newly generated AS path and community by route-map. */
- bgp_attr_flush (attr);
- return RMAP_DENY;
+ if (ret == RMAP_DENYMATCH) {
+ /* Free newly generated AS path and community by
+ * route-map. */
+ bgp_attr_flush(attr);
+ return RMAP_DENY;
+ }
}
- }
- return RMAP_PERMIT;
+ return RMAP_PERMIT;
}
-static int
-bgp_output_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
- afi_t afi, safi_t safi, const char *rmap_name)
+static int bgp_output_modifier(struct peer *peer, struct prefix *p,
+ struct attr *attr, afi_t afi, safi_t safi,
+ const char *rmap_name)
{
- struct bgp_filter *filter;
- struct bgp_info info;
- route_map_result_t ret;
- struct route_map *rmap = NULL;
+ struct bgp_filter *filter;
+ struct bgp_info info;
+ route_map_result_t ret;
+ struct route_map *rmap = NULL;
- filter = &peer->filter[afi][safi];
+ filter = &peer->filter[afi][safi];
- /* Apply default weight value. */
- if (peer->weight[afi][safi])
- (bgp_attr_extra_get (attr))->weight = peer->weight[afi][safi];
+ /* Apply default weight value. */
+ if (peer->weight[afi][safi])
+ (bgp_attr_extra_get(attr))->weight = peer->weight[afi][safi];
- if (rmap_name)
- {
- rmap = route_map_lookup_by_name(rmap_name);
+ if (rmap_name) {
+ rmap = route_map_lookup_by_name(rmap_name);
- if (rmap == NULL)
- return RMAP_DENY;
- }
- else
- {
- if (ROUTE_MAP_OUT_NAME(filter))
- {
- rmap = ROUTE_MAP_OUT (filter);
+ if (rmap == NULL)
+ return RMAP_DENY;
+ } else {
+ if (ROUTE_MAP_OUT_NAME(filter)) {
+ rmap = ROUTE_MAP_OUT(filter);
- if (rmap == NULL)
- return RMAP_DENY;
- }
- }
+ if (rmap == NULL)
+ return RMAP_DENY;
+ }
+ }
- /* Route map apply. */
- if (rmap)
- {
- /* Duplicate current value to new strucutre for modification. */
- info.peer = peer;
- info.attr = attr;
+ /* Route map apply. */
+ if (rmap) {
+ /* Duplicate current value to new strucutre for modification. */
+ info.peer = peer;
+ info.attr = attr;
- SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT);
+ SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
- /* Apply BGP route map to the attribute. */
- ret = route_map_apply (rmap, p, RMAP_BGP, &info);
+ /* Apply BGP route map to the attribute. */
+ ret = route_map_apply(rmap, p, RMAP_BGP, &info);
- peer->rmap_type = 0;
+ peer->rmap_type = 0;
- if (ret == RMAP_DENYMATCH)
- /* caller has multiple error paths with bgp_attr_flush() */
- return RMAP_DENY;
- }
- return RMAP_PERMIT;
+ if (ret == RMAP_DENYMATCH)
+ /* caller has multiple error paths with bgp_attr_flush()
+ */
+ return RMAP_DENY;
+ }
+ return RMAP_PERMIT;
}
/* If this is an EBGP peer with remove-private-AS */
-static void
-bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
- struct peer *peer, struct attr *attr)
-{
- if (peer->sort == BGP_PEER_EBGP &&
- (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE) ||
- peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE) ||
- peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL) ||
- peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)))
- {
- // Take action on the entire aspath
- if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE) ||
- peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL))
- {
- if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
- attr->aspath = aspath_replace_private_asns (attr->aspath, bgp->as);
-
- // The entire aspath consists of private ASNs so create an empty aspath
- else if (aspath_private_as_check (attr->aspath))
- attr->aspath = aspath_empty_get ();
-
- // There are some public and some private ASNs, remove the private ASNs
- else
- attr->aspath = aspath_remove_private_asns (attr->aspath);
- }
-
- // 'all' was not specified so the entire aspath must be private ASNs
- // for us to do anything
- else if (aspath_private_as_check (attr->aspath))
- {
- if (peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
- attr->aspath = aspath_replace_private_asns (attr->aspath, bgp->as);
- else
- attr->aspath = aspath_empty_get ();
- }
- }
+static void bgp_peer_remove_private_as(struct bgp *bgp, afi_t afi, safi_t safi,
+ struct peer *peer, struct attr *attr)
+{
+ if (peer->sort == BGP_PEER_EBGP
+ && (peer_af_flag_check(peer, afi, safi,
+ PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
+ || peer_af_flag_check(peer, afi, safi,
+ PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE)
+ || peer_af_flag_check(peer, afi, safi,
+ PEER_FLAG_REMOVE_PRIVATE_AS_ALL)
+ || peer_af_flag_check(peer, afi, safi,
+ PEER_FLAG_REMOVE_PRIVATE_AS))) {
+ // Take action on the entire aspath
+ if (peer_af_flag_check(peer, afi, safi,
+ PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE)
+ || peer_af_flag_check(peer, afi, safi,
+ PEER_FLAG_REMOVE_PRIVATE_AS_ALL)) {
+ if (peer_af_flag_check(
+ peer, afi, safi,
+ PEER_FLAG_REMOVE_PRIVATE_AS_ALL_REPLACE))
+ attr->aspath = aspath_replace_private_asns(
+ attr->aspath, bgp->as);
+
+ // The entire aspath consists of private ASNs so create
+ // an empty aspath
+ else if (aspath_private_as_check(attr->aspath))
+ attr->aspath = aspath_empty_get();
+
+ // There are some public and some private ASNs, remove
+ // the private ASNs
+ else
+ attr->aspath = aspath_remove_private_asns(
+ attr->aspath);
+ }
+
+ // 'all' was not specified so the entire aspath must be private
+ // ASNs
+ // for us to do anything
+ else if (aspath_private_as_check(attr->aspath)) {
+ if (peer_af_flag_check(
+ peer, afi, safi,
+ PEER_FLAG_REMOVE_PRIVATE_AS_REPLACE))
+ attr->aspath = aspath_replace_private_asns(
+ attr->aspath, bgp->as);
+ else
+ attr->aspath = aspath_empty_get();
+ }
+ }
}
/* If this is an EBGP peer with as-override */
-static void
-bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
- struct peer *peer, struct attr *attr)
+static void bgp_peer_as_override(struct bgp *bgp, afi_t afi, safi_t safi,
+ struct peer *peer, struct attr *attr)
+{
+ if (peer->sort == BGP_PEER_EBGP
+ && peer_af_flag_check(peer, afi, safi, PEER_FLAG_AS_OVERRIDE)) {
+ if (aspath_single_asn_check(attr->aspath, peer->as))
+ attr->aspath = aspath_replace_specific_asn(
+ attr->aspath, peer->as, bgp->as);
+ }
+}
+
+static void subgroup_announce_reset_nhop(u_char family, struct attr *attr)
{
- if (peer->sort == BGP_PEER_EBGP &&
- peer_af_flag_check (peer, afi, safi, PEER_FLAG_AS_OVERRIDE))
- {
- if (aspath_single_asn_check (attr->aspath, peer->as))
- attr->aspath = aspath_replace_specific_asn (attr->aspath, peer->as, bgp->as);
- }
+ if (family == AF_INET)
+ attr->nexthop.s_addr = 0;
+ if (family == AF_INET6)
+ memset(&attr->extra->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
}
-static void
-subgroup_announce_reset_nhop (u_char family, struct attr *attr)
-{
- if (family == AF_INET)
- attr->nexthop.s_addr = 0;
- if (family == AF_INET6)
- memset (&attr->extra->mp_nexthop_global, 0, IPV6_MAX_BYTELEN);
-}
-
-int
-subgroup_announce_check (struct bgp_info *ri, struct update_subgroup *subgrp,
- struct prefix *p, struct attr *attr)
-{
- struct bgp_filter *filter;
- struct peer *from;
- struct peer *peer;
- struct peer *onlypeer;
- struct bgp *bgp;
- struct attr *riattr;
- struct peer_af *paf;
- char buf[PREFIX_STRLEN];
- int ret;
- int transparent;
- int reflect;
- afi_t afi;
- safi_t safi;
- int samepeer_safe = 0; /* for synthetic mplsvpns routes */
-
- if (DISABLE_BGP_ANNOUNCE)
- return 0;
-
- afi = SUBGRP_AFI(subgrp);
- safi = SUBGRP_SAFI(subgrp);
- peer = SUBGRP_PEER(subgrp);
- onlypeer = NULL;
- if (CHECK_FLAG (peer->flags, PEER_FLAG_LONESOUL))
- onlypeer = SUBGRP_PFIRST(subgrp)->peer;
-
- from = ri->peer;
- filter = &peer->filter[afi][safi];
- bgp = SUBGRP_INST(subgrp);
- riattr = bgp_info_mpath_count (ri) ? bgp_info_mpath_attr (ri) : ri->attr;
+int subgroup_announce_check(struct bgp_info *ri, struct update_subgroup *subgrp,
+ struct prefix *p, struct attr *attr)
+{
+ struct bgp_filter *filter;
+ struct peer *from;
+ struct peer *peer;
+ struct peer *onlypeer;
+ struct bgp *bgp;
+ struct attr *riattr;
+ struct peer_af *paf;
+ char buf[PREFIX_STRLEN];
+ int ret;
+ int transparent;
+ int reflect;
+ afi_t afi;
+ safi_t safi;
+ int samepeer_safe = 0; /* for synthetic mplsvpns routes */
+
+ if (DISABLE_BGP_ANNOUNCE)
+ return 0;
+
+ afi = SUBGRP_AFI(subgrp);
+ safi = SUBGRP_SAFI(subgrp);
+ peer = SUBGRP_PEER(subgrp);
+ onlypeer = NULL;
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_LONESOUL))
+ onlypeer = SUBGRP_PFIRST(subgrp)->peer;
+
+ from = ri->peer;
+ filter = &peer->filter[afi][safi];
+ bgp = SUBGRP_INST(subgrp);
+ riattr = bgp_info_mpath_count(ri) ? bgp_info_mpath_attr(ri) : ri->attr;
#if ENABLE_BGP_VNC
- if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN) &&
- ((ri->type == ZEBRA_ROUTE_BGP_DIRECT) ||
- (ri->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
-
- /*
- * direct and direct_ext type routes originate internally even
- * though they can have peer pointers that reference other systems
- */
- prefix2str(p, buf, PREFIX_STRLEN);
- zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe", __func__, buf);
- samepeer_safe = 1;
- }
+ if (((afi == AFI_IP) || (afi == AFI_IP6)) && (safi == SAFI_MPLS_VPN)
+ && ((ri->type == ZEBRA_ROUTE_BGP_DIRECT)
+ || (ri->type == ZEBRA_ROUTE_BGP_DIRECT_EXT))) {
+
+ /*
+ * direct and direct_ext type routes originate internally even
+ * though they can have peer pointers that reference other
+ * systems
+ */
+ prefix2str(p, buf, PREFIX_STRLEN);
+ zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
+ __func__, buf);
+ samepeer_safe = 1;
+ }
#endif
- /* With addpath we may be asked to TX all kinds of paths so make sure
- * ri is valid */
- if (!CHECK_FLAG (ri->flags, BGP_INFO_VALID) ||
- CHECK_FLAG (ri->flags, BGP_INFO_HISTORY) ||
- CHECK_FLAG (ri->flags, BGP_INFO_REMOVED))
- {
- return 0;
- }
+ /* With addpath we may be asked to TX all kinds of paths so make sure
+ * ri is valid */
+ if (!CHECK_FLAG(ri->flags, BGP_INFO_VALID)
+ || CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)
+ || CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
+ return 0;
+ }
- /* If this is not the bestpath then check to see if there is an enabled addpath
- * feature that requires us to advertise it */
- if (! CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
- {
- if (! bgp_addpath_tx_path(peer, afi, safi, ri))
- {
- return 0;
- }
- }
+ /* If this is not the bestpath then check to see if there is an enabled
+ * addpath
+ * feature that requires us to advertise it */
+ if (!CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
+ if (!bgp_addpath_tx_path(peer, afi, safi, ri)) {
+ return 0;
+ }
+ }
- /* Aggregate-address suppress check. */
- if (ri->extra && ri->extra->suppress)
- if (! UNSUPPRESS_MAP_NAME (filter))
- {
- return 0;
- }
+ /* Aggregate-address suppress check. */
+ if (ri->extra && ri->extra->suppress)
+ if (!UNSUPPRESS_MAP_NAME(filter)) {
+ return 0;
+ }
- /* Do not send back route to sender. */
- if (onlypeer && from == onlypeer)
- {
- return 0;
- }
+ /* Do not send back route to sender. */
+ if (onlypeer && from == onlypeer) {
+ 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;
- else if (p->family == AF_INET6 && p->prefixlen == 0)
- 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;
+ else if (p->family == AF_INET6 && p->prefixlen == 0)
+ return 0;
+ }
- /* 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))
- transparent = 1;
- else
- transparent = 0;
+ /* 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))
+ transparent = 1;
+ else
+ transparent = 0;
+
+ /* If community is not disabled check the no-export and local. */
+ if (!transparent && bgp_community_filter(peer, riattr)) {
+ if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
+ zlog_debug(
+ "subgrpannouncecheck: community filter check fail");
+ return 0;
+ }
- /* If community is not disabled check the no-export and local. */
- if (! transparent && bgp_community_filter (peer, riattr))
- {
- if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
- zlog_debug ("subgrpannouncecheck: community filter check fail");
- return 0;
- }
+ /* If the attribute has originator-id and it is same as remote
+ peer's id. */
+ if (onlypeer && riattr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
+ && (IPV4_ADDR_SAME(&onlypeer->remote_id,
+ &riattr->extra->originator_id))) {
+ if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
+ zlog_debug(
+ "%s [Update:SEND] %s originator-id is same as "
+ "remote router-id",
+ onlypeer->host,
+ prefix2str(p, buf, sizeof(buf)));
+ return 0;
+ }
- /* If the attribute has originator-id and it is same as remote
- peer's id. */
- if (onlypeer &&
- riattr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID) &&
- (IPV4_ADDR_SAME (&onlypeer->remote_id, &riattr->extra->originator_id)))
- {
- if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
- zlog_debug ("%s [Update:SEND] %s originator-id is same as "
- "remote router-id",
- onlypeer->host, prefix2str (p, buf, sizeof (buf)));
- return 0;
- }
-
- /* ORF prefix-list filter check */
- if (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
- && (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
- || CHECK_FLAG (peer->af_cap[afi][safi],
- PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
- if (peer->orf_plist[afi][safi])
- {
- if (prefix_list_apply (peer->orf_plist[afi][safi], p) == PREFIX_DENY)
- {
- if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
- zlog_debug ("%s [Update:SEND] %s is filtered via ORF",
- peer->host, prefix2str (p, buf, sizeof (buf)));
- return 0;
- }
- }
-
- /* Output filter check. */
- if (bgp_output_filter (peer, p, riattr, afi, safi) == FILTER_DENY)
- {
- if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
- zlog_debug ("%s [Update:SEND] %s is filtered",
- peer->host, prefix2str (p, buf, sizeof (buf)));
- return 0;
- }
+ /* ORF prefix-list filter check */
+ if (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_RM_ADV)
+ && (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ORF_PREFIX_SM_RCV)
+ || CHECK_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ORF_PREFIX_SM_OLD_RCV)))
+ if (peer->orf_plist[afi][safi]) {
+ if (prefix_list_apply(peer->orf_plist[afi][safi], p)
+ == PREFIX_DENY) {
+ if (bgp_debug_update(NULL, p,
+ subgrp->update_group, 0))
+ zlog_debug(
+ "%s [Update:SEND] %s is filtered via ORF",
+ peer->host,
+ prefix2str(p, buf,
+ sizeof(buf)));
+ return 0;
+ }
+ }
+
+ /* Output filter check. */
+ if (bgp_output_filter(peer, p, riattr, afi, safi) == FILTER_DENY) {
+ if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
+ zlog_debug("%s [Update:SEND] %s is filtered",
+ peer->host, prefix2str(p, buf, sizeof(buf)));
+ return 0;
+ }
#ifdef BGP_SEND_ASPATH_CHECK
- /* AS path loop check. */
- if (onlypeer && aspath_loop_check (riattr->aspath, onlypeer->as))
- {
- if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
- zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u "
- "that is part of AS path.",
- onlypeer->host, onlypeer->as);
- return 0;
- }
+ /* AS path loop check. */
+ if (onlypeer && aspath_loop_check(riattr->aspath, onlypeer->as)) {
+ if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
+ zlog_debug(
+ "%s [Update:SEND] suppress announcement to peer AS %u "
+ "that is part of AS path.",
+ onlypeer->host, onlypeer->as);
+ return 0;
+ }
#endif /* BGP_SEND_ASPATH_CHECK */
- /* If we're a CONFED we need to loop check the CONFED ID too */
- if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
- {
- if (aspath_loop_check(riattr->aspath, bgp->confed_id))
- {
- if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
- zlog_debug ("%s [Update:SEND] suppress announcement to peer AS %u"
- " is AS path.",
- peer->host,
- bgp->confed_id);
- return 0;
+ /* If we're a CONFED we need to loop check the CONFED ID too */
+ if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)) {
+ if (aspath_loop_check(riattr->aspath, bgp->confed_id)) {
+ if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
+ zlog_debug(
+ "%s [Update:SEND] suppress announcement to peer AS %u"
+ " is AS path.",
+ peer->host, bgp->confed_id);
+ return 0;
+ }
}
- }
- /* Route-Reflect check. */
- if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
- reflect = 1;
- else
- reflect = 0;
+ /* Route-Reflect check. */
+ if (from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
+ reflect = 1;
+ else
+ reflect = 0;
+
+ /* IBGP reflection check. */
+ if (reflect && !samepeer_safe) {
+ /* A route from a Client peer. */
+ if (CHECK_FLAG(from->af_flags[afi][safi],
+ PEER_FLAG_REFLECTOR_CLIENT)) {
+ /* Reflect to all the Non-Client peers and also to the
+ Client peers other than the originator. Originator
+ check
+ is already done. So there is noting to do. */
+ /* no bgp client-to-client reflection check. */
+ if (bgp_flag_check(bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
+ if (CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_REFLECTOR_CLIENT))
+ return 0;
+ } else {
+ /* A route from a Non-client peer. Reflect to all other
+ clients. */
+ if (!CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_REFLECTOR_CLIENT))
+ return 0;
+ }
+ }
- /* IBGP reflection check. */
- if (reflect && !samepeer_safe)
- {
- /* A route from a Client peer. */
- if (CHECK_FLAG (from->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
- {
- /* Reflect to all the Non-Client peers and also to the
- Client peers other than the originator. Originator check
- is already done. So there is noting to do. */
- /* no bgp client-to-client reflection check. */
- if (bgp_flag_check (bgp, BGP_FLAG_NO_CLIENT_TO_CLIENT))
- if (CHECK_FLAG (peer->af_flags[afi][safi],
- PEER_FLAG_REFLECTOR_CLIENT))
- return 0;
- }
- else
- {
- /* A route from a Non-client peer. Reflect to all other
- clients. */
- if (! CHECK_FLAG (peer->af_flags[afi][safi],
- PEER_FLAG_REFLECTOR_CLIENT))
- return 0;
+ /* For modify attribute, copy it to temporary structure. */
+ bgp_attr_dup(attr, riattr);
+
+ /* If local-preference is not set. */
+ if ((peer->sort == BGP_PEER_IBGP || peer->sort == BGP_PEER_CONFED)
+ && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))) {
+ attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF);
+ attr->local_pref = bgp->default_local_pref;
}
- }
- /* For modify attribute, copy it to temporary structure. */
- bgp_attr_dup (attr, riattr);
+ /* If originator-id is not set and the route is to be reflected,
+ set the originator id */
+ if (reflect
+ && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))) {
+ attr->extra = bgp_attr_extra_get(attr);
+ IPV4_ADDR_COPY(&(attr->extra->originator_id),
+ &(from->remote_id));
+ SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
+ }
- /* If local-preference is not set. */
- if ((peer->sort == BGP_PEER_IBGP
- || peer->sort == BGP_PEER_CONFED)
- && (! (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))))
- {
- attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
- attr->local_pref = bgp->default_local_pref;
- }
+ /* Remove MED if its an EBGP peer - will get overwritten by route-maps
+ */
+ if (peer->sort == BGP_PEER_EBGP
+ && attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
+ if (from != bgp->peer_self && !transparent
+ && !CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_MED_UNCHANGED))
+ attr->flag &=
+ ~(ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC));
+ }
- /* If originator-id is not set and the route is to be reflected,
- set the originator id */
- if (reflect && (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))))
- {
- attr->extra = bgp_attr_extra_get(attr);
- IPV4_ADDR_COPY(&(attr->extra->originator_id), &(from->remote_id));
- SET_FLAG(attr->flag, BGP_ATTR_ORIGINATOR_ID);
- }
+ /* Since the nexthop attribute can vary per peer, it is not explicitly
+ * set
+ * in announce check, only certain flags and length (or number of
+ * nexthops
+ * -- for IPv6/MP_REACH) are set here in order to guide the update
+ * formation
+ * code in setting the nexthop(s) on a per peer basis in
+ * reformat_peer().
+ * Typically, the source nexthop in the attribute is preserved but in
+ * the
+ * scenarios where we know it will always be overwritten, we reset the
+ * nexthop to "0" in an attempt to achieve better Update packing. An
+ * example of this is when a prefix from each of 2 IBGP peers needs to
+ * be
+ * announced to an EBGP peer (and they have the same attributes barring
+ * their nexthop).
+ */
+ if (reflect)
+ SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
+
+#define NEXTHOP_IS_V6 \
+ ((safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN \
+ && (p->family == AF_INET6 || peer_cap_enhe(peer))) \
+ || ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) \
+ && attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
+
+ /* IPv6/MP starts with 1 nexthop. The link-local address is passed only
+ * if
+ * the peer (group) is configured to receive link-local nexthop
+ * unchanged
+ * and it is available in the prefix OR we're not reflecting the route
+ * and
+ * the peer (group) to whom we're going to announce is on a shared
+ * network
+ * and this is either a self-originated route or the peer is EBGP.
+ */
+ if (NEXTHOP_IS_V6) {
+ attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
+ if ((CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)
+ && IN6_IS_ADDR_LINKLOCAL(&attr->extra->mp_nexthop_local))
+ || (!reflect && peer->shared_network
+ && (from == bgp->peer_self
+ || peer->sort == BGP_PEER_EBGP))) {
+ attr->extra->mp_nexthop_len =
+ BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
+ }
- /* Remove MED if its an EBGP peer - will get overwritten by route-maps */
- if (peer->sort == BGP_PEER_EBGP
- && attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
- {
- if (from != bgp->peer_self && ! transparent
- && ! CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MED_UNCHANGED))
- attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC));
- }
+ /* Clear off link-local nexthop in source, whenever it is not
+ * needed to
+ * ensure more prefixes share the same attribute for
+ * announcement.
+ */
+ if (!(CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
+ memset(&attr->extra->mp_nexthop_local, 0,
+ IPV6_MAX_BYTELEN);
+ }
- /* Since the nexthop attribute can vary per peer, it is not explicitly set
- * in announce check, only certain flags and length (or number of nexthops
- * -- for IPv6/MP_REACH) are set here in order to guide the update formation
- * code in setting the nexthop(s) on a per peer basis in reformat_peer().
- * Typically, the source nexthop in the attribute is preserved but in the
- * scenarios where we know it will always be overwritten, we reset the
- * nexthop to "0" in an attempt to achieve better Update packing. An
- * example of this is when a prefix from each of 2 IBGP peers needs to be
- * announced to an EBGP peer (and they have the same attributes barring
- * their nexthop).
- */
- if (reflect)
- SET_FLAG(attr->rmap_change_flags, BATTR_REFLECTED);
-
-#define NEXTHOP_IS_V6 (\
- (safi != SAFI_ENCAP && safi != SAFI_MPLS_VPN &&\
- (p->family == AF_INET6 || peer_cap_enhe(peer))) || \
- ((safi == SAFI_ENCAP || safi == SAFI_MPLS_VPN) &&\
- attr->extra->mp_nexthop_len >= IPV6_MAX_BYTELEN))
-
- /* IPv6/MP starts with 1 nexthop. The link-local address is passed only if
- * the peer (group) is configured to receive link-local nexthop unchanged
- * and it is available in the prefix OR we're not reflecting the route and
- * the peer (group) to whom we're going to announce is on a shared network
- * and this is either a self-originated route or the peer is EBGP.
- */
- if (NEXTHOP_IS_V6)
- {
- attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
- if ((CHECK_FLAG (peer->af_flags[afi][safi],
- PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) &&
- IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_local)) ||
- (!reflect && peer->shared_network &&
- (from == bgp->peer_self || peer->sort == BGP_PEER_EBGP)))
- {
- attr->extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL;
- }
-
- /* Clear off link-local nexthop in source, whenever it is not needed to
- * ensure more prefixes share the same attribute for announcement.
- */
- if (!(CHECK_FLAG (peer->af_flags[afi][safi],
- PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED)))
- memset (&attr->extra->mp_nexthop_local, 0, IPV6_MAX_BYTELEN);
- }
+ bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
+ bgp_peer_as_override(bgp, afi, safi, peer, attr);
+
+ /* Route map & unsuppress-map apply. */
+ if (ROUTE_MAP_OUT_NAME(filter) || (ri->extra && ri->extra->suppress)) {
+ struct bgp_info info;
+ struct attr dummy_attr;
+ struct attr_extra dummy_extra;
+
+ dummy_attr.extra = &dummy_extra;
+
+ info.peer = peer;
+ info.attr = attr;
+ /* don't confuse inbound and outbound setting */
+ RESET_FLAG(attr->rmap_change_flags);
+
+ /*
+ * The route reflector is not allowed to modify the attributes
+ * of the reflected IBGP routes unless explicitly allowed.
+ */
+ if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
+ && !bgp_flag_check(bgp,
+ BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
+ bgp_attr_dup(&dummy_attr, attr);
+ info.attr = &dummy_attr;
+ }
- bgp_peer_remove_private_as(bgp, afi, safi, peer, attr);
- bgp_peer_as_override(bgp, afi, safi, peer, attr);
+ SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
- /* Route map & unsuppress-map apply. */
- if (ROUTE_MAP_OUT_NAME (filter)
- || (ri->extra && ri->extra->suppress) )
- {
- struct bgp_info info;
- struct attr dummy_attr;
- struct attr_extra dummy_extra;
-
- dummy_attr.extra = &dummy_extra;
-
- info.peer = peer;
- info.attr = attr;
- /* don't confuse inbound and outbound setting */
- RESET_FLAG(attr->rmap_change_flags);
-
- /*
- * The route reflector is not allowed to modify the attributes
- * of the reflected IBGP routes unless explicitly allowed.
- */
- if ((from->sort == BGP_PEER_IBGP && peer->sort == BGP_PEER_IBGP)
- && !bgp_flag_check(bgp, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY))
- {
- bgp_attr_dup (&dummy_attr, attr);
- info.attr = &dummy_attr;
- }
-
- SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT);
-
- if (ri->extra && ri->extra->suppress)
- ret = route_map_apply (UNSUPPRESS_MAP (filter), p, RMAP_BGP, &info);
- else
- ret = route_map_apply (ROUTE_MAP_OUT (filter), p, RMAP_BGP, &info);
-
- peer->rmap_type = 0;
-
- if (ret == RMAP_DENYMATCH)
- {
- bgp_attr_flush (attr);
- return 0;
+ if (ri->extra && ri->extra->suppress)
+ ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
+ RMAP_BGP, &info);
+ else
+ ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
+ RMAP_BGP, &info);
+
+ peer->rmap_type = 0;
+
+ if (ret == RMAP_DENYMATCH) {
+ bgp_attr_flush(attr);
+ return 0;
+ }
}
- }
- /* After route-map has been applied, we check to see if the nexthop to
- * be carried in the attribute (that is used for the announcement) can
- * be cleared off or not. We do this in all cases where we would be
- * setting the nexthop to "ourselves". For IPv6, we only need to consider
- * the global nexthop here; the link-local nexthop would have been cleared
- * already, and if not, it is required by the update formation code.
- * Also see earlier comments in this function.
- */
- /*
- * If route-map has performed some operation on the nexthop or the peer
- * configuration says to pass it unchanged, we cannot reset the nexthop
- * here, so only attempt to do it if these aren't true. Note that the
- * route-map handler itself might have cleared the nexthop, if for example,
- * it is configured as 'peer-address'.
- */
- if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
- riattr->rmap_change_flags) &&
- !transparent &&
- !CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED))
- {
- /* We can reset the nexthop, if setting (or forcing) it to 'self' */
- if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF) ||
- CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_FORCE_NEXTHOP_SELF))
- {
- if (!reflect ||
- CHECK_FLAG (peer->af_flags[afi][safi],
- PEER_FLAG_FORCE_NEXTHOP_SELF))
- subgroup_announce_reset_nhop ((peer_cap_enhe(peer) ?
- AF_INET6 : p->family), attr);
- }
- else if (peer->sort == BGP_PEER_EBGP)
- {
- /* Can also reset the nexthop if announcing to EBGP, but only if
- * no peer in the subgroup is on a shared subnet.
- * Note: 3rd party nexthop currently implemented for IPv4 only.
- */
- SUBGRP_FOREACH_PEER (subgrp, paf)
- {
- if (bgp_multiaccess_check_v4 (riattr->nexthop, paf->peer))
- break;
- }
- if (!paf)
- subgroup_announce_reset_nhop ((peer_cap_enhe(peer) ? AF_INET6 : p->family), attr);
- }
- /* If IPv6/MP and nexthop does not have any override and happens to
- * be a link-local address, reset it so that we don't pass along the
- * source's link-local IPv6 address to recipients who may not be on
- * the same interface.
- */
- if (p->family == AF_INET6 || peer_cap_enhe(peer))
- {
- if (IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_global))
- subgroup_announce_reset_nhop (AF_INET6, attr);
- }
- }
+ /* After route-map has been applied, we check to see if the nexthop to
+ * be carried in the attribute (that is used for the announcement) can
+ * be cleared off or not. We do this in all cases where we would be
+ * setting the nexthop to "ourselves". For IPv6, we only need to
+ * consider
+ * the global nexthop here; the link-local nexthop would have been
+ * cleared
+ * already, and if not, it is required by the update formation code.
+ * Also see earlier comments in this function.
+ */
+ /*
+ * If route-map has performed some operation on the nexthop or the peer
+ * configuration says to pass it unchanged, we cannot reset the nexthop
+ * here, so only attempt to do it if these aren't true. Note that the
+ * route-map handler itself might have cleared the nexthop, if for
+ * example,
+ * it is configured as 'peer-address'.
+ */
+ if (!bgp_rmap_nhop_changed(attr->rmap_change_flags,
+ riattr->rmap_change_flags)
+ && !transparent
+ && !CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_NEXTHOP_UNCHANGED)) {
+ /* We can reset the nexthop, if setting (or forcing) it to
+ * 'self' */
+ if (CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_NEXTHOP_SELF)
+ || CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_FORCE_NEXTHOP_SELF)) {
+ if (!reflect
+ || CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_FORCE_NEXTHOP_SELF))
+ subgroup_announce_reset_nhop(
+ (peer_cap_enhe(peer) ? AF_INET6
+ : p->family),
+ attr);
+ } else if (peer->sort == BGP_PEER_EBGP) {
+ /* Can also reset the nexthop if announcing to EBGP, but
+ * only if
+ * no peer in the subgroup is on a shared subnet.
+ * Note: 3rd party nexthop currently implemented for
+ * IPv4 only.
+ */
+ SUBGRP_FOREACH_PEER(subgrp, paf)
+ {
+ if (bgp_multiaccess_check_v4(riattr->nexthop,
+ paf->peer))
+ break;
+ }
+ if (!paf)
+ subgroup_announce_reset_nhop(
+ (peer_cap_enhe(peer) ? AF_INET6
+ : p->family),
+ attr);
+ }
+ /* If IPv6/MP and nexthop does not have any override and happens
+ * to
+ * be a link-local address, reset it so that we don't pass along
+ * the
+ * source's link-local IPv6 address to recipients who may not be
+ * on
+ * the same interface.
+ */
+ if (p->family == AF_INET6 || peer_cap_enhe(peer)) {
+ if (IN6_IS_ADDR_LINKLOCAL(
+ &attr->extra->mp_nexthop_global))
+ subgroup_announce_reset_nhop(AF_INET6, attr);
+ }
+ }
- return 1;
+ return 1;
}
-struct bgp_info_pair
-{
- struct bgp_info *old;
- struct bgp_info *new;
+struct bgp_info_pair {
+ struct bgp_info *old;
+ struct bgp_info *new;
};
-static void
-bgp_best_selection (struct bgp *bgp, struct bgp_node *rn,
- struct bgp_maxpaths_cfg *mpath_cfg,
- struct bgp_info_pair *result)
-{
- struct bgp_info *new_select;
- struct bgp_info *old_select;
- struct bgp_info *ri;
- struct bgp_info *ri1;
- struct bgp_info *ri2;
- struct bgp_info *nextri = NULL;
- int paths_eq, do_mpath, debug;
- struct list mp_list;
- char pfx_buf[PREFIX2STR_BUFFER];
- char path_buf[PATH_ADDPATH_STR_BUFFER];
-
- bgp_mp_list_init (&mp_list);
- do_mpath = (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
-
- debug = bgp_debug_bestpath(&rn->p);
-
- if (debug)
- prefix2str (&rn->p, pfx_buf, sizeof (pfx_buf));
-
- /* bgp deterministic-med */
- new_select = NULL;
- if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
- {
+static void bgp_best_selection(struct bgp *bgp, struct bgp_node *rn,
+ struct bgp_maxpaths_cfg *mpath_cfg,
+ struct bgp_info_pair *result)
+{
+ struct bgp_info *new_select;
+ struct bgp_info *old_select;
+ struct bgp_info *ri;
+ struct bgp_info *ri1;
+ struct bgp_info *ri2;
+ struct bgp_info *nextri = NULL;
+ int paths_eq, do_mpath, debug;
+ struct list mp_list;
+ char pfx_buf[PREFIX2STR_BUFFER];
+ char path_buf[PATH_ADDPATH_STR_BUFFER];
+
+ bgp_mp_list_init(&mp_list);
+ do_mpath =
+ (mpath_cfg->maxpaths_ebgp > 1 || mpath_cfg->maxpaths_ibgp > 1);
+
+ debug = bgp_debug_bestpath(&rn->p);
+
+ if (debug)
+ prefix2str(&rn->p, pfx_buf, sizeof(pfx_buf));
+
+ /* bgp deterministic-med */
+ new_select = NULL;
+ if (bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)) {
+
+ /* Clear BGP_INFO_DMED_SELECTED for all paths */
+ for (ri1 = rn->info; ri1; ri1 = ri1->next)
+ bgp_info_unset_flag(rn, ri1, BGP_INFO_DMED_SELECTED);
+
+ for (ri1 = rn->info; ri1; ri1 = ri1->next) {
+ if (CHECK_FLAG(ri1->flags, BGP_INFO_DMED_CHECK))
+ continue;
+ if (BGP_INFO_HOLDDOWN(ri1))
+ continue;
+ if (ri1->peer && ri1->peer != bgp->peer_self)
+ if (ri1->peer->status != Established)
+ continue;
+
+ new_select = ri1;
+ if (ri1->next) {
+ for (ri2 = ri1->next; ri2; ri2 = ri2->next) {
+ if (CHECK_FLAG(ri2->flags,
+ BGP_INFO_DMED_CHECK))
+ continue;
+ if (BGP_INFO_HOLDDOWN(ri2))
+ continue;
+ if (ri2->peer
+ && ri2->peer != bgp->peer_self
+ && !CHECK_FLAG(
+ ri2->peer->sflags,
+ PEER_STATUS_NSF_WAIT))
+ if (ri2->peer->status
+ != Established)
+ continue;
+
+ if (aspath_cmp_left(ri1->attr->aspath,
+ ri2->attr->aspath)
+ || aspath_cmp_left_confed(
+ ri1->attr->aspath,
+ ri2->attr->aspath)) {
+ if (bgp_info_cmp(bgp, ri2,
+ new_select,
+ &paths_eq,
+ mpath_cfg,
+ debug,
+ pfx_buf)) {
+ bgp_info_unset_flag(
+ rn, new_select,
+ BGP_INFO_DMED_SELECTED);
+ new_select = ri2;
+ }
+
+ bgp_info_set_flag(
+ rn, ri2,
+ BGP_INFO_DMED_CHECK);
+ }
+ }
+ }
+ bgp_info_set_flag(rn, new_select, BGP_INFO_DMED_CHECK);
+ bgp_info_set_flag(rn, new_select,
+ BGP_INFO_DMED_SELECTED);
+
+ if (debug) {
+ bgp_info_path_with_addpath_rx_str(new_select,
+ path_buf);
+ zlog_debug("%s: %s is the bestpath from AS %d",
+ pfx_buf, path_buf,
+ aspath_get_first_as(
+ new_select->attr->aspath));
+ }
+ }
+ }
- /* Clear BGP_INFO_DMED_SELECTED for all paths */
- for (ri1 = rn->info; ri1; ri1 = ri1->next)
- bgp_info_unset_flag (rn, ri1, BGP_INFO_DMED_SELECTED);
-
- for (ri1 = rn->info; ri1; ri1 = ri1->next)
- {
- if (CHECK_FLAG (ri1->flags, BGP_INFO_DMED_CHECK))
- continue;
- if (BGP_INFO_HOLDDOWN (ri1))
- continue;
- if (ri1->peer && ri1->peer != bgp->peer_self)
- if (ri1->peer->status != Established)
- continue;
-
- new_select = ri1;
- if (ri1->next)
- {
- for (ri2 = ri1->next; ri2; ri2 = ri2->next)
- {
- if (CHECK_FLAG (ri2->flags, BGP_INFO_DMED_CHECK))
- continue;
- if (BGP_INFO_HOLDDOWN (ri2))
- continue;
- if (ri2->peer &&
- ri2->peer != bgp->peer_self &&
- !CHECK_FLAG (ri2->peer->sflags, PEER_STATUS_NSF_WAIT))
- if (ri2->peer->status != Established)
- continue;
-
- if (aspath_cmp_left (ri1->attr->aspath, ri2->attr->aspath)
- || aspath_cmp_left_confed (ri1->attr->aspath,
- ri2->attr->aspath))
- {
- if (bgp_info_cmp (bgp, ri2, new_select, &paths_eq,
- mpath_cfg, debug, pfx_buf))
- {
- bgp_info_unset_flag (rn, new_select, BGP_INFO_DMED_SELECTED);
- new_select = ri2;
- }
-
- bgp_info_set_flag (rn, ri2, BGP_INFO_DMED_CHECK);
- }
- }
- }
- bgp_info_set_flag (rn, new_select, BGP_INFO_DMED_CHECK);
- bgp_info_set_flag (rn, new_select, BGP_INFO_DMED_SELECTED);
-
- if (debug)
- {
- bgp_info_path_with_addpath_rx_str (new_select, path_buf);
- zlog_debug("%s: %s is the bestpath from AS %d",
- pfx_buf, path_buf, aspath_get_first_as(new_select->attr->aspath));
- }
- }
- }
+ /* Check old selected route and new selected route. */
+ old_select = NULL;
+ new_select = NULL;
+ for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1);
+ ri = nextri) {
+ if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED))
+ old_select = ri;
+
+ if (BGP_INFO_HOLDDOWN(ri)) {
+ /* reap REMOVED routes, if needs be
+ * selected route must stay for a while longer though
+ */
+ if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)
+ && (ri != old_select))
+ bgp_info_reap(rn, ri);
+
+ continue;
+ }
- /* Check old selected route and new selected route. */
- old_select = NULL;
- new_select = NULL;
- for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1); ri = nextri)
- {
- if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
- old_select = ri;
-
- if (BGP_INFO_HOLDDOWN (ri))
- {
- /* reap REMOVED routes, if needs be
- * selected route must stay for a while longer though
- */
- if (CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)
- && (ri != old_select))
- bgp_info_reap (rn, ri);
-
- continue;
- }
-
- if (ri->peer &&
- ri->peer != bgp->peer_self &&
- !CHECK_FLAG (ri->peer->sflags, PEER_STATUS_NSF_WAIT))
- if (ri->peer->status != Established)
- continue;
-
- if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED)
- && (! CHECK_FLAG (ri->flags, BGP_INFO_DMED_SELECTED)))
- {
- bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_CHECK);
- continue;
- }
-
- bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_CHECK);
-
- if (bgp_info_cmp (bgp, ri, new_select, &paths_eq, mpath_cfg, debug, pfx_buf))
- {
- new_select = ri;
+ if (ri->peer && ri->peer != bgp->peer_self
+ && !CHECK_FLAG(ri->peer->sflags, PEER_STATUS_NSF_WAIT))
+ if (ri->peer->status != Established)
+ continue;
+
+ if (bgp_flag_check(bgp, BGP_FLAG_DETERMINISTIC_MED)
+ && (!CHECK_FLAG(ri->flags, BGP_INFO_DMED_SELECTED))) {
+ bgp_info_unset_flag(rn, ri, BGP_INFO_DMED_CHECK);
+ continue;
+ }
+
+ bgp_info_unset_flag(rn, ri, BGP_INFO_DMED_CHECK);
+
+ if (bgp_info_cmp(bgp, ri, new_select, &paths_eq, mpath_cfg,
+ debug, pfx_buf)) {
+ new_select = ri;
+ }
}
- }
-
- /* Now that we know which path is the bestpath see if any of the other paths
- * qualify as multipaths
- */
- if (debug)
- {
- if (new_select)
- bgp_info_path_with_addpath_rx_str (new_select, path_buf);
- else
- sprintf (path_buf, "NONE");
- zlog_debug("%s: After path selection, newbest is %s oldbest was %s",
- pfx_buf, path_buf,
- old_select ? old_select->peer->host : "NONE");
- }
- if (do_mpath && new_select)
- {
- for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1); ri = nextri)
- {
-
- if (debug)
- bgp_info_path_with_addpath_rx_str (ri, path_buf);
-
- if (ri == new_select)
- {
- if (debug)
- zlog_debug("%s: %s is the bestpath, add to the multipath list",
- pfx_buf, path_buf);
- bgp_mp_list_add (&mp_list, ri);
- continue;
- }
-
- if (BGP_INFO_HOLDDOWN (ri))
- continue;
-
- if (ri->peer &&
- ri->peer != bgp->peer_self &&
- !CHECK_FLAG (ri->peer->sflags, PEER_STATUS_NSF_WAIT))
- if (ri->peer->status != Established)
- continue;
-
- if (!bgp_info_nexthop_cmp (ri, new_select))
- {
- if (debug)
- zlog_debug("%s: %s has the same nexthop as the bestpath, skip it",
- pfx_buf, path_buf);
- continue;
- }
-
- bgp_info_cmp (bgp, ri, new_select, &paths_eq, mpath_cfg, debug, pfx_buf);
-
- if (paths_eq)
- {
- if (debug)
- zlog_debug("%s: %s is equivalent to the bestpath, add to the multipath list",
- pfx_buf, path_buf);
- bgp_mp_list_add (&mp_list, ri);
- }
- }
- }
+ /* Now that we know which path is the bestpath see if any of the other
+ * paths
+ * qualify as multipaths
+ */
+ if (debug) {
+ if (new_select)
+ bgp_info_path_with_addpath_rx_str(new_select, path_buf);
+ else
+ sprintf(path_buf, "NONE");
+ zlog_debug(
+ "%s: After path selection, newbest is %s oldbest was %s",
+ pfx_buf, path_buf,
+ old_select ? old_select->peer->host : "NONE");
+ }
- bgp_info_mpath_update (rn, new_select, old_select, &mp_list, mpath_cfg);
- bgp_info_mpath_aggregate_update (new_select, old_select);
- bgp_mp_list_clear (&mp_list);
+ if (do_mpath && new_select) {
+ for (ri = rn->info; (ri != NULL) && (nextri = ri->next, 1);
+ ri = nextri) {
+
+ if (debug)
+ bgp_info_path_with_addpath_rx_str(ri, path_buf);
+
+ if (ri == new_select) {
+ if (debug)
+ zlog_debug(
+ "%s: %s is the bestpath, add to the multipath list",
+ pfx_buf, path_buf);
+ bgp_mp_list_add(&mp_list, ri);
+ continue;
+ }
+
+ if (BGP_INFO_HOLDDOWN(ri))
+ continue;
+
+ if (ri->peer && ri->peer != bgp->peer_self
+ && !CHECK_FLAG(ri->peer->sflags,
+ PEER_STATUS_NSF_WAIT))
+ if (ri->peer->status != Established)
+ continue;
+
+ if (!bgp_info_nexthop_cmp(ri, new_select)) {
+ if (debug)
+ zlog_debug(
+ "%s: %s has the same nexthop as the bestpath, skip it",
+ pfx_buf, path_buf);
+ continue;
+ }
+
+ bgp_info_cmp(bgp, ri, new_select, &paths_eq, mpath_cfg,
+ debug, pfx_buf);
+
+ if (paths_eq) {
+ if (debug)
+ zlog_debug(
+ "%s: %s is equivalent to the bestpath, add to the multipath list",
+ pfx_buf, path_buf);
+ bgp_mp_list_add(&mp_list, ri);
+ }
+ }
+ }
- result->old = old_select;
- result->new = new_select;
+ bgp_info_mpath_update(rn, new_select, old_select, &mp_list, mpath_cfg);
+ bgp_info_mpath_aggregate_update(new_select, old_select);
+ bgp_mp_list_clear(&mp_list);
- return;
+ result->old = old_select;
+ result->new = new_select;
+
+ return;
}
/*
* A new route/change in bestpath of an existing route. Evaluate the path
* for advertisement to the subgroup.
*/
-int
-subgroup_process_announce_selected (struct update_subgroup *subgrp,
- struct bgp_info *selected,
- struct bgp_node *rn,
- u_int32_t addpath_tx_id)
-{
- struct prefix *p;
- struct peer *onlypeer;
- struct attr attr;
- struct attr_extra extra;
- afi_t afi;
- safi_t safi;
-
- p = &rn->p;
- afi = SUBGRP_AFI(subgrp);
- safi = SUBGRP_SAFI(subgrp);
- onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ?
- (SUBGRP_PFIRST(subgrp))->peer : NULL);
-
- /* First update is deferred until ORF or ROUTE-REFRESH is received */
- if (onlypeer && CHECK_FLAG (onlypeer->af_sflags[afi][safi],
- PEER_STATUS_ORF_WAIT_REFRESH))
- return 0;
-
- memset(&extra, 0, sizeof(struct attr_extra));
- /* It's initialized in bgp_announce_check() */
- attr.extra = &extra;
-
- /* Announcement to the subgroup. If the route is filtered withdraw it. */
- if (selected)
- {
- if (subgroup_announce_check(selected, subgrp, p, &attr))
- bgp_adj_out_set_subgroup(rn, subgrp, &attr, selected);
- else
- bgp_adj_out_unset_subgroup(rn, subgrp, 1, selected->addpath_tx_id);
- }
+int subgroup_process_announce_selected(struct update_subgroup *subgrp,
+ struct bgp_info *selected,
+ struct bgp_node *rn,
+ u_int32_t addpath_tx_id)
+{
+ struct prefix *p;
+ struct peer *onlypeer;
+ struct attr attr;
+ struct attr_extra extra;
+ afi_t afi;
+ safi_t safi;
- /* If selected is NULL we must withdraw the path using addpath_tx_id */
- else
- {
- bgp_adj_out_unset_subgroup(rn, subgrp, 1, addpath_tx_id);
- }
+ p = &rn->p;
+ afi = SUBGRP_AFI(subgrp);
+ safi = SUBGRP_SAFI(subgrp);
+ onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
+ : NULL);
+
+ /* First update is deferred until ORF or ROUTE-REFRESH is received */
+ if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
+ PEER_STATUS_ORF_WAIT_REFRESH))
+ return 0;
+
+ memset(&extra, 0, sizeof(struct attr_extra));
+ /* It's initialized in bgp_announce_check() */
+ attr.extra = &extra;
+
+ /* Announcement to the subgroup. If the route is filtered withdraw it.
+ */
+ if (selected) {
+ if (subgroup_announce_check(selected, subgrp, p, &attr))
+ bgp_adj_out_set_subgroup(rn, subgrp, &attr, selected);
+ else
+ bgp_adj_out_unset_subgroup(rn, subgrp, 1,
+ selected->addpath_tx_id);
+ }
- return 0;
+ /* If selected is NULL we must withdraw the path using addpath_tx_id */
+ else {
+ bgp_adj_out_unset_subgroup(rn, subgrp, 1, addpath_tx_id);
+ }
+
+ return 0;
}
/*
* Clear IGP changed flag and attribute changed flag for a route (all paths).
* This is called at the end of route processing.
*/
-static void
-bgp_zebra_clear_route_change_flags (struct bgp_node *rn)
+static void bgp_zebra_clear_route_change_flags(struct bgp_node *rn)
{
- struct bgp_info *ri;
+ struct bgp_info *ri;
- for (ri = rn->info; ri; ri = ri->next)
- {
- if (BGP_INFO_HOLDDOWN (ri))
- continue;
- UNSET_FLAG (ri->flags, BGP_INFO_IGP_CHANGED);
- UNSET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED);
- }
+ for (ri = rn->info; ri; ri = ri->next) {
+ if (BGP_INFO_HOLDDOWN(ri))
+ continue;
+ UNSET_FLAG(ri->flags, BGP_INFO_IGP_CHANGED);
+ UNSET_FLAG(ri->flags, BGP_INFO_ATTR_CHANGED);
+ }
}
/*
@@ -1841,1155 +1853,1147 @@ bgp_zebra_clear_route_change_flags (struct bgp_node *rn)
* if the route selection returns the same best route as earlier - to
* determine if we need to update zebra or not.
*/
-static int
-bgp_zebra_has_route_changed (struct bgp_node *rn, struct bgp_info *selected)
-{
- struct bgp_info *mpinfo;
-
- /* If this is multipath, check all selected paths for any nexthop change or
- * attribute change. Some attribute changes (e.g., community) aren't of
- * relevance to the RIB, but we'll update zebra to ensure we handle the
- * case of BGP nexthop change. This is the behavior when the best path has
- * an attribute change anyway.
- */
- if (CHECK_FLAG (selected->flags, BGP_INFO_IGP_CHANGED) ||
- CHECK_FLAG (selected->flags, BGP_INFO_MULTIPATH_CHG))
- return 1;
-
- /* If this is multipath, check all selected paths for any nexthop change */
- for (mpinfo = bgp_info_mpath_first (selected); mpinfo;
- mpinfo = bgp_info_mpath_next (mpinfo))
- {
- if (CHECK_FLAG (mpinfo->flags, BGP_INFO_IGP_CHANGED)
- || CHECK_FLAG (mpinfo->flags, BGP_INFO_ATTR_CHANGED))
- return 1;
- }
+static int bgp_zebra_has_route_changed(struct bgp_node *rn,
+ struct bgp_info *selected)
+{
+ struct bgp_info *mpinfo;
+
+ /* If this is multipath, check all selected paths for any nexthop change
+ * or
+ * attribute change. Some attribute changes (e.g., community) aren't of
+ * relevance to the RIB, but we'll update zebra to ensure we handle the
+ * case of BGP nexthop change. This is the behavior when the best path
+ * has
+ * an attribute change anyway.
+ */
+ if (CHECK_FLAG(selected->flags, BGP_INFO_IGP_CHANGED)
+ || CHECK_FLAG(selected->flags, BGP_INFO_MULTIPATH_CHG))
+ return 1;
+
+ /* If this is multipath, check all selected paths for any nexthop change
+ */
+ for (mpinfo = bgp_info_mpath_first(selected); mpinfo;
+ mpinfo = bgp_info_mpath_next(mpinfo)) {
+ if (CHECK_FLAG(mpinfo->flags, BGP_INFO_IGP_CHANGED)
+ || CHECK_FLAG(mpinfo->flags, BGP_INFO_ATTR_CHANGED))
+ return 1;
+ }
- /* Nothing has changed from the RIB's perspective. */
- return 0;
+ /* Nothing has changed from the RIB's perspective. */
+ return 0;
}
-struct bgp_process_queue
-{
- struct bgp *bgp;
- struct bgp_node *rn;
- afi_t afi;
- safi_t safi;
+struct bgp_process_queue {
+ struct bgp *bgp;
+ struct bgp_node *rn;
+ afi_t afi;
+ safi_t safi;
};
-static wq_item_status
-bgp_process_main (struct work_queue *wq, void *data)
-{
- struct bgp_process_queue *pq = data;
- struct bgp *bgp = pq->bgp;
- struct bgp_node *rn = pq->rn;
- afi_t afi = pq->afi;
- safi_t safi = pq->safi;
- struct prefix *p = &rn->p;
- struct bgp_info *new_select;
- struct bgp_info *old_select;
- struct bgp_info_pair old_and_new;
-
- /* Is it end of initial update? (after startup) */
- if (!rn)
- {
- quagga_timestamp(3, bgp->update_delay_zebra_resume_time,
- sizeof(bgp->update_delay_zebra_resume_time));
-
- bgp->main_zebra_update_hold = 0;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- {
- bgp_zebra_announce_table(bgp, afi, safi);
- }
- bgp->main_peers_update_hold = 0;
-
- bgp_start_routeadv(bgp);
- return WQ_SUCCESS;
- }
-
- /* Best path selection. */
- bgp_best_selection (bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new);
- old_select = old_and_new.old;
- new_select = old_and_new.new;
+static wq_item_status bgp_process_main(struct work_queue *wq, void *data)
+{
+ struct bgp_process_queue *pq = data;
+ struct bgp *bgp = pq->bgp;
+ struct bgp_node *rn = pq->rn;
+ afi_t afi = pq->afi;
+ safi_t safi = pq->safi;
+ struct prefix *p = &rn->p;
+ struct bgp_info *new_select;
+ struct bgp_info *old_select;
+ struct bgp_info_pair old_and_new;
+
+ /* Is it end of initial update? (after startup) */
+ if (!rn) {
+ quagga_timestamp(3, bgp->update_delay_zebra_resume_time,
+ sizeof(bgp->update_delay_zebra_resume_time));
+
+ bgp->main_zebra_update_hold = 0;
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
+ bgp_zebra_announce_table(bgp, afi, safi);
+ }
+ bgp->main_peers_update_hold = 0;
+
+ bgp_start_routeadv(bgp);
+ return WQ_SUCCESS;
+ }
- /* Nothing to do. */
- if (old_select && old_select == new_select &&
- !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR) &&
- !CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED) &&
- !bgp->addpath_tx_used[afi][safi])
- {
- if (bgp_zebra_has_route_changed (rn, old_select))
- {
+ /* Best path selection. */
+ bgp_best_selection(bgp, rn, &bgp->maxpaths[afi][safi], &old_and_new);
+ old_select = old_and_new.old;
+ new_select = old_and_new.new;
+
+ /* Nothing to do. */
+ if (old_select && old_select == new_select
+ && !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR)
+ && !CHECK_FLAG(old_select->flags, BGP_INFO_ATTR_CHANGED)
+ && !bgp->addpath_tx_used[afi][safi]) {
+ if (bgp_zebra_has_route_changed(rn, old_select)) {
#if ENABLE_BGP_VNC
- vnc_import_bgp_add_route(bgp, p, old_select);
- vnc_import_bgp_exterior_add_route(bgp, p, old_select);
+ vnc_import_bgp_add_route(bgp, p, old_select);
+ vnc_import_bgp_exterior_add_route(bgp, p, old_select);
#endif
- bgp_zebra_announce (p, old_select, bgp, afi, safi);
- }
- UNSET_FLAG (old_select->flags, BGP_INFO_MULTIPATH_CHG);
- bgp_zebra_clear_route_change_flags (rn);
- UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
- return WQ_SUCCESS;
- }
+ bgp_zebra_announce(p, old_select, bgp, afi, safi);
+ }
+ UNSET_FLAG(old_select->flags, BGP_INFO_MULTIPATH_CHG);
+ bgp_zebra_clear_route_change_flags(rn);
+ UNSET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
+ return WQ_SUCCESS;
+ }
- /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set */
- UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
+ /* If the user did "clear ip bgp prefix x.x.x.x" this flag will be set
+ */
+ UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
- /* bestpath has changed; bump version */
- if (old_select || new_select)
- {
- bgp_bump_version(rn);
-
- if (!bgp->t_rmap_def_originate_eval)
- {
- bgp_lock (bgp);
- THREAD_TIMER_ON(bm->master, bgp->t_rmap_def_originate_eval,
- update_group_refresh_default_originate_route_map,
- bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER);
- }
- }
+ /* bestpath has changed; bump version */
+ if (old_select || new_select) {
+ bgp_bump_version(rn);
- if (old_select)
- bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED);
- if (new_select)
- {
- bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED);
- bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED);
- UNSET_FLAG (new_select->flags, BGP_INFO_MULTIPATH_CHG);
- }
+ if (!bgp->t_rmap_def_originate_eval) {
+ bgp_lock(bgp);
+ THREAD_TIMER_ON(
+ bm->master, bgp->t_rmap_def_originate_eval,
+ update_group_refresh_default_originate_route_map,
+ bgp, RMAP_DEFAULT_ORIGINATE_EVAL_TIMER);
+ }
+ }
+
+ if (old_select)
+ bgp_info_unset_flag(rn, old_select, BGP_INFO_SELECTED);
+ if (new_select) {
+ bgp_info_set_flag(rn, new_select, BGP_INFO_SELECTED);
+ bgp_info_unset_flag(rn, new_select, BGP_INFO_ATTR_CHANGED);
+ UNSET_FLAG(new_select->flags, BGP_INFO_MULTIPATH_CHG);
+ }
#if ENABLE_BGP_VNC
- if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
- if (old_select != new_select) {
- if (old_select) {
- vnc_import_bgp_exterior_del_route(bgp, p, old_select);
- vnc_import_bgp_del_route(bgp, p, old_select);
- }
- if (new_select) {
- vnc_import_bgp_exterior_add_route(bgp, p, new_select);
- vnc_import_bgp_add_route(bgp, p, new_select);
- }
- }
- }
+ if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
+ if (old_select != new_select) {
+ if (old_select) {
+ vnc_import_bgp_exterior_del_route(bgp, p,
+ old_select);
+ vnc_import_bgp_del_route(bgp, p, old_select);
+ }
+ if (new_select) {
+ vnc_import_bgp_exterior_add_route(bgp, p,
+ new_select);
+ vnc_import_bgp_add_route(bgp, p, new_select);
+ }
+ }
+ }
#endif
- group_announce_route(bgp, afi, safi, rn, new_select);
-
- /* FIB update. */
- if ((safi == SAFI_UNICAST || safi == SAFI_MULTICAST) &&
- (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW) &&
- !bgp_option_check (BGP_OPT_NO_FIB))
- {
- if (new_select
- && new_select->type == ZEBRA_ROUTE_BGP
- && (new_select->sub_type == BGP_ROUTE_NORMAL ||
- new_select->sub_type == BGP_ROUTE_AGGREGATE))
- bgp_zebra_announce (p, new_select, bgp, afi, safi);
- else
- {
- /* Withdraw the route from the kernel. */
- if (old_select
- && old_select->type == ZEBRA_ROUTE_BGP
- && (old_select->sub_type == BGP_ROUTE_NORMAL ||
- old_select->sub_type == BGP_ROUTE_AGGREGATE))
- bgp_zebra_withdraw (p, old_select, safi);
+ group_announce_route(bgp, afi, safi, rn, new_select);
+
+ /* FIB update. */
+ if ((safi == SAFI_UNICAST || safi == SAFI_MULTICAST)
+ && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW)
+ && !bgp_option_check(BGP_OPT_NO_FIB)) {
+ if (new_select && new_select->type == ZEBRA_ROUTE_BGP
+ && (new_select->sub_type == BGP_ROUTE_NORMAL
+ || new_select->sub_type == BGP_ROUTE_AGGREGATE))
+ bgp_zebra_announce(p, new_select, bgp, afi, safi);
+ else {
+ /* Withdraw the route from the kernel. */
+ if (old_select && old_select->type == ZEBRA_ROUTE_BGP
+ && (old_select->sub_type == BGP_ROUTE_NORMAL
+ || old_select->sub_type == BGP_ROUTE_AGGREGATE))
+ bgp_zebra_withdraw(p, old_select, safi);
+ }
}
- }
- /* Clear any route change flags. */
- bgp_zebra_clear_route_change_flags (rn);
+ /* Clear any route change flags. */
+ bgp_zebra_clear_route_change_flags(rn);
- /* Reap old select bgp_info, if it has been removed */
- if (old_select && CHECK_FLAG (old_select->flags, BGP_INFO_REMOVED))
- bgp_info_reap (rn, old_select);
-
- UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
- return WQ_SUCCESS;
+ /* Reap old select bgp_info, if it has been removed */
+ if (old_select && CHECK_FLAG(old_select->flags, BGP_INFO_REMOVED))
+ bgp_info_reap(rn, old_select);
+
+ UNSET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
+ return WQ_SUCCESS;
}
-static void
-bgp_processq_del (struct work_queue *wq, void *data)
+static void bgp_processq_del(struct work_queue *wq, void *data)
{
- struct bgp_process_queue *pq = data;
- struct bgp_table *table;
+ struct bgp_process_queue *pq = data;
+ struct bgp_table *table;
- bgp_unlock (pq->bgp);
- if (pq->rn)
- {
- table = bgp_node_table (pq->rn);
- bgp_unlock_node (pq->rn);
- bgp_table_unlock (table);
- }
- XFREE (MTYPE_BGP_PROCESS_QUEUE, pq);
+ bgp_unlock(pq->bgp);
+ if (pq->rn) {
+ table = bgp_node_table(pq->rn);
+ bgp_unlock_node(pq->rn);
+ bgp_table_unlock(table);
+ }
+ XFREE(MTYPE_BGP_PROCESS_QUEUE, pq);
}
-void
-bgp_process_queue_init (void)
+void bgp_process_queue_init(void)
{
- if (!bm->process_main_queue)
- {
- bm->process_main_queue
- = work_queue_new (bm->master, "process_main_queue");
-
- if ( !bm->process_main_queue)
- {
- zlog_err ("%s: Failed to allocate work queue", __func__);
- exit (1);
- }
- }
-
- bm->process_main_queue->spec.workfunc = &bgp_process_main;
- bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
- bm->process_main_queue->spec.max_retries = 0;
- bm->process_main_queue->spec.hold = 50;
- /* Use a higher yield value of 50ms for main queue processing */
- bm->process_main_queue->spec.yield = 50 * 1000L;
+ if (!bm->process_main_queue) {
+ bm->process_main_queue =
+ work_queue_new(bm->master, "process_main_queue");
+
+ if (!bm->process_main_queue) {
+ zlog_err("%s: Failed to allocate work queue", __func__);
+ exit(1);
+ }
+ }
+
+ bm->process_main_queue->spec.workfunc = &bgp_process_main;
+ bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
+ bm->process_main_queue->spec.max_retries = 0;
+ bm->process_main_queue->spec.hold = 50;
+ /* Use a higher yield value of 50ms for main queue processing */
+ bm->process_main_queue->spec.yield = 50 * 1000L;
}
-void
-bgp_process (struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
+void bgp_process(struct bgp *bgp, struct bgp_node *rn, afi_t afi, safi_t safi)
{
- struct bgp_process_queue *pqnode;
-
- /* already scheduled for processing? */
- if (CHECK_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED))
- return;
+ struct bgp_process_queue *pqnode;
+
+ /* already scheduled for processing? */
+ if (CHECK_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED))
+ return;
- if (bm->process_main_queue == NULL)
- return;
+ if (bm->process_main_queue == NULL)
+ return;
- pqnode = XCALLOC (MTYPE_BGP_PROCESS_QUEUE,
- sizeof (struct bgp_process_queue));
- if (!pqnode)
- return;
+ pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
+ sizeof(struct bgp_process_queue));
+ if (!pqnode)
+ return;
- /* all unlocked in bgp_processq_del */
- bgp_table_lock (bgp_node_table (rn));
- pqnode->rn = bgp_lock_node (rn);
- pqnode->bgp = bgp;
- bgp_lock (bgp);
- pqnode->afi = afi;
- pqnode->safi = safi;
- work_queue_add (bm->process_main_queue, pqnode);
- SET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
- return;
+ /* all unlocked in bgp_processq_del */
+ bgp_table_lock(bgp_node_table(rn));
+ pqnode->rn = bgp_lock_node(rn);
+ pqnode->bgp = bgp;
+ bgp_lock(bgp);
+ pqnode->afi = afi;
+ pqnode->safi = safi;
+ work_queue_add(bm->process_main_queue, pqnode);
+ SET_FLAG(rn->flags, BGP_NODE_PROCESS_SCHEDULED);
+ return;
}
-void
-bgp_add_eoiu_mark (struct bgp *bgp)
+void bgp_add_eoiu_mark(struct bgp *bgp)
{
- struct bgp_process_queue *pqnode;
+ struct bgp_process_queue *pqnode;
- if (bm->process_main_queue == NULL)
- return;
+ if (bm->process_main_queue == NULL)
+ return;
- pqnode = XCALLOC (MTYPE_BGP_PROCESS_QUEUE,
- sizeof (struct bgp_process_queue));
- if (!pqnode)
- return;
+ pqnode = XCALLOC(MTYPE_BGP_PROCESS_QUEUE,
+ sizeof(struct bgp_process_queue));
+ if (!pqnode)
+ return;
- pqnode->rn = NULL;
- pqnode->bgp = bgp;
- bgp_lock (bgp);
- work_queue_add (bm->process_main_queue, pqnode);
+ pqnode->rn = NULL;
+ pqnode->bgp = bgp;
+ bgp_lock(bgp);
+ work_queue_add(bm->process_main_queue, pqnode);
}
-static int
-bgp_maximum_prefix_restart_timer (struct thread *thread)
+static int bgp_maximum_prefix_restart_timer(struct thread *thread)
{
- struct peer *peer;
+ struct peer *peer;
- peer = THREAD_ARG (thread);
- peer->t_pmax_restart = NULL;
+ peer = THREAD_ARG(thread);
+ peer->t_pmax_restart = NULL;
- if (bgp_debug_neighbor_events(peer))
- zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
- peer->host);
+ if (bgp_debug_neighbor_events(peer))
+ zlog_debug(
+ "%s Maximum-prefix restart timer expired, restore peering",
+ peer->host);
- peer_clear (peer, NULL);
+ peer_clear(peer, NULL);
- return 0;
+ return 0;
}
-int
-bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
- safi_t safi, int always)
+int bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
+ int always)
{
- iana_afi_t pkt_afi;
- safi_t pkt_safi;
+ iana_afi_t pkt_afi;
+ safi_t pkt_safi;
- if (!CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
- return 0;
+ if (!CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
+ return 0;
- if (peer->pcount[afi][safi] > peer->pmax[afi][safi])
- {
- if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT)
- && ! always)
- return 0;
-
- zlog_info ("%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
- "limit %ld", afi_safi_print (afi, safi), peer->host,
- peer->pcount[afi][safi], peer->pmax[afi][safi]);
- SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
-
- if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX_WARNING))
- return 0;
-
- /* Convert AFI, SAFI to values for packet. */
- pkt_afi = afi_int2iana (afi);
- pkt_safi = safi_int2iana (safi);
- {
- u_int8_t ndata[7];
-
- ndata[0] = (pkt_afi >> 8);
- ndata[1] = pkt_afi;
- ndata[2] = pkt_safi;
- ndata[3] = (peer->pmax[afi][safi] >> 24);
- ndata[4] = (peer->pmax[afi][safi] >> 16);
- ndata[5] = (peer->pmax[afi][safi] >> 8);
- ndata[6] = (peer->pmax[afi][safi]);
-
- SET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
- bgp_notify_send_with_data (peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_MAX_PREFIX, ndata, 7);
- }
-
- /* Dynamic peers will just close their connection. */
- if (peer_dynamic_neighbor (peer))
- return 1;
-
- /* restart timer start */
- if (peer->pmax_restart[afi][safi])
- {
- peer->v_pmax_restart = peer->pmax_restart[afi][safi] * 60;
-
- if (bgp_debug_neighbor_events(peer))
- zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
- peer->host, peer->v_pmax_restart);
-
- BGP_TIMER_ON (peer->t_pmax_restart, bgp_maximum_prefix_restart_timer,
- peer->v_pmax_restart);
- }
-
- return 1;
- }
- else
- UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
+ if (peer->pcount[afi][safi] > peer->pmax[afi][safi]) {
+ if (CHECK_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_PREFIX_LIMIT)
+ && !always)
+ return 0;
- if (peer->pcount[afi][safi] > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100))
- {
- if (CHECK_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD)
- && ! always)
- return 0;
-
- zlog_info ("%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
- afi_safi_print (afi, safi), peer->host, peer->pcount[afi][safi],
- peer->pmax[afi][safi]);
- SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD);
- }
- else
- UNSET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_THRESHOLD);
- return 0;
+ zlog_info(
+ "%%MAXPFXEXCEED: No. of %s prefix received from %s %ld exceed, "
+ "limit %ld",
+ afi_safi_print(afi, safi), peer->host,
+ peer->pcount[afi][safi], peer->pmax[afi][safi]);
+ SET_FLAG(peer->af_sflags[afi][safi], PEER_STATUS_PREFIX_LIMIT);
+
+ if (CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_MAX_PREFIX_WARNING))
+ return 0;
+
+ /* Convert AFI, SAFI to values for packet. */
+ pkt_afi = afi_int2iana(afi);
+ pkt_safi = safi_int2iana(safi);
+ {
+ u_int8_t ndata[7];
+
+ ndata[0] = (pkt_afi >> 8);
+ ndata[1] = pkt_afi;
+ ndata[2] = pkt_safi;
+ ndata[3] = (peer->pmax[afi][safi] >> 24);
+ ndata[4] = (peer->pmax[afi][safi] >> 16);
+ ndata[5] = (peer->pmax[afi][safi] >> 8);
+ ndata[6] = (peer->pmax[afi][safi]);
+
+ SET_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
+ bgp_notify_send_with_data(peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_MAX_PREFIX,
+ ndata, 7);
+ }
+
+ /* Dynamic peers will just close their connection. */
+ if (peer_dynamic_neighbor(peer))
+ return 1;
+
+ /* restart timer start */
+ if (peer->pmax_restart[afi][safi]) {
+ peer->v_pmax_restart =
+ peer->pmax_restart[afi][safi] * 60;
+
+ if (bgp_debug_neighbor_events(peer))
+ zlog_debug(
+ "%s Maximum-prefix restart timer started for %d secs",
+ peer->host, peer->v_pmax_restart);
+
+ BGP_TIMER_ON(peer->t_pmax_restart,
+ bgp_maximum_prefix_restart_timer,
+ peer->v_pmax_restart);
+ }
+
+ return 1;
+ } else
+ UNSET_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_PREFIX_LIMIT);
+
+ if (peer->pcount[afi][safi]
+ > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
+ if (CHECK_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_PREFIX_THRESHOLD)
+ && !always)
+ return 0;
+
+ zlog_info(
+ "%%MAXPFX: No. of %s prefix received from %s reaches %ld, max %ld",
+ afi_safi_print(afi, safi), peer->host,
+ peer->pcount[afi][safi], peer->pmax[afi][safi]);
+ SET_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_PREFIX_THRESHOLD);
+ } else
+ UNSET_FLAG(peer->af_sflags[afi][safi],
+ PEER_STATUS_PREFIX_THRESHOLD);
+ return 0;
}
/* Unconditionally remove the route from the RIB, without taking
* damping into consideration (eg, because the session went down)
*/
-static void
-bgp_rib_remove (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
- afi_t afi, safi_t safi)
+static void bgp_rib_remove(struct bgp_node *rn, struct bgp_info *ri,
+ struct peer *peer, afi_t afi, safi_t safi)
{
- bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
-
- if (!CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
- bgp_info_delete (rn, ri); /* keep historical info */
-
- bgp_process (peer->bgp, rn, afi, safi);
-}
-
-static void
-bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
- afi_t afi, safi_t safi, struct prefix_rd *prd)
-{
- int status = BGP_DAMP_NONE;
-
- /* apply dampening, if result is suppressed, we'll be retaining
- * the bgp_info in the RIB for historical reference.
- */
- if (CHECK_FLAG (peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
- && peer->sort == BGP_PEER_EBGP)
- if ( (status = bgp_damp_withdraw (ri, rn, afi, safi, 0))
- == BGP_DAMP_SUPPRESSED)
- {
- bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
- return;
- }
-
-#if ENABLE_BGP_VNC
- if (safi == SAFI_MPLS_VPN) {
- struct bgp_node *prn = NULL;
- struct bgp_table *table = NULL;
-
- prn = bgp_node_get(peer->bgp->rib[afi][safi], (struct prefix *) prd);
- if (prn->info) {
- table = (struct bgp_table *)(prn->info);
-
- vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
- peer->bgp,
- prd,
- table,
- &rn->p,
- ri);
- }
- bgp_unlock_node(prn);
- }
- if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
- if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) {
+ bgp_aggregate_decrement(peer->bgp, &rn->p, ri, afi, safi);
- vnc_import_bgp_del_route(peer->bgp, &rn->p, ri);
- vnc_import_bgp_exterior_del_route(peer->bgp, &rn->p, ri);
- }
- }
-#endif
- bgp_rib_remove (rn, ri, peer, afi, safi);
+ if (!CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
+ bgp_info_delete(rn, ri); /* keep historical info */
+
+ bgp_process(peer->bgp, rn, afi, safi);
}
-static struct bgp_info *
-info_make (int type, int sub_type, u_short instance, struct peer *peer, struct attr *attr,
- struct bgp_node *rn)
+static void bgp_rib_withdraw(struct bgp_node *rn, struct bgp_info *ri,
+ struct peer *peer, afi_t afi, safi_t safi,
+ struct prefix_rd *prd)
{
- struct bgp_info *new;
+ int status = BGP_DAMP_NONE;
- /* Make new BGP info. */
- new = XCALLOC (MTYPE_BGP_ROUTE, sizeof (struct bgp_info));
- new->type = type;
- new->instance = instance;
- new->sub_type = sub_type;
- new->peer = peer;
- new->attr = attr;
- new->uptime = bgp_clock ();
- new->net = rn;
- new->addpath_tx_id = ++peer->bgp->addpath_tx_id;
- return new;
-}
+ /* apply dampening, if result is suppressed, we'll be retaining
+ * the bgp_info in the RIB for historical reference.
+ */
+ if (CHECK_FLAG(peer->bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
+ && peer->sort == BGP_PEER_EBGP)
+ if ((status = bgp_damp_withdraw(ri, rn, afi, safi, 0))
+ == BGP_DAMP_SUPPRESSED) {
+ bgp_aggregate_decrement(peer->bgp, &rn->p, ri, afi,
+ safi);
+ return;
+ }
-static void
-overlay_index_update(struct attr *attr, struct eth_segment_id *eth_s_id, union gw_addr *gw_ip)
-{
- struct attr_extra *extra;
+#if ENABLE_BGP_VNC
+ if (safi == SAFI_MPLS_VPN) {
+ struct bgp_node *prn = NULL;
+ struct bgp_table *table = NULL;
- if(!attr)
- return;
- extra = bgp_attr_extra_get(attr);
+ prn = bgp_node_get(peer->bgp->rib[afi][safi],
+ (struct prefix *)prd);
+ if (prn->info) {
+ table = (struct bgp_table *)(prn->info);
- if(eth_s_id == NULL)
- {
- memset(&(extra->evpn_overlay.eth_s_id),0, sizeof(struct eth_segment_id));
- }
- else
- {
- memcpy(&(extra->evpn_overlay.eth_s_id), eth_s_id, sizeof(struct eth_segment_id));
- }
- if(gw_ip == NULL)
- {
- memset(&(extra->evpn_overlay.gw_ip), 0, sizeof(union gw_addr));
- }
- else
- {
- memcpy(&(extra->evpn_overlay.gw_ip),gw_ip, sizeof(union gw_addr));
- }
+ vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
+ peer->bgp, prd, table, &rn->p, ri);
+ }
+ bgp_unlock_node(prn);
+ }
+ if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
+ if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
+
+ vnc_import_bgp_del_route(peer->bgp, &rn->p, ri);
+ vnc_import_bgp_exterior_del_route(peer->bgp, &rn->p,
+ ri);
+ }
+ }
+#endif
+ bgp_rib_remove(rn, ri, peer, afi, safi);
}
-static bool
-overlay_index_equal(afi_t afi, struct bgp_info *info, struct eth_segment_id *eth_s_id, union gw_addr *gw_ip)
+static struct bgp_info *info_make(int type, int sub_type, u_short instance,
+ struct peer *peer, struct attr *attr,
+ struct bgp_node *rn)
{
- struct eth_segment_id *info_eth_s_id, *info_eth_s_id_remote;
- union gw_addr *info_gw_ip, *info_gw_ip_remote;
- char temp[16];
+ struct bgp_info *new;
- if(afi != AFI_L2VPN)
- return true;
- if (!info->attr || !info->attr->extra)
- {
- memset(&temp, 0, 16);
- info_eth_s_id = (struct eth_segment_id *)&temp;
- info_gw_ip = (union gw_addr *)&temp;
- if(eth_s_id == NULL && gw_ip == NULL)
- return true;
- }
- else
- {
- info_eth_s_id = &(info->attr->extra->evpn_overlay.eth_s_id);
- info_gw_ip = &(info->attr->extra->evpn_overlay.gw_ip);
- }
- if(gw_ip == NULL)
- info_gw_ip_remote = (union gw_addr *)&temp;
- else
- info_gw_ip_remote = gw_ip;
- if(eth_s_id == NULL)
- info_eth_s_id_remote = (struct eth_segment_id *)&temp;
- else
- info_eth_s_id_remote = eth_s_id;
- if(!memcmp(info_gw_ip, info_gw_ip_remote, sizeof(union gw_addr)))
- return false;
- return !memcmp(info_eth_s_id, info_eth_s_id_remote, sizeof(struct eth_segment_id));
+ /* Make new BGP info. */
+ new = XCALLOC(MTYPE_BGP_ROUTE, sizeof(struct bgp_info));
+ new->type = type;
+ new->instance = instance;
+ new->sub_type = sub_type;
+ new->peer = peer;
+ new->attr = attr;
+ new->uptime = bgp_clock();
+ new->net = rn;
+ new->addpath_tx_id = ++peer->bgp->addpath_tx_id;
+ return new;
}
-/* Check if received nexthop is valid or not. */
-static int
-bgp_update_martian_nexthop (struct bgp *bgp, afi_t afi, safi_t safi, struct attr *attr)
+static void overlay_index_update(struct attr *attr,
+ struct eth_segment_id *eth_s_id,
+ union gw_addr *gw_ip)
{
- struct attr_extra *attre = attr->extra;
- int ret = 0;
+ struct attr_extra *extra;
- /* Only validated for unicast and multicast currently. */
- if (safi != SAFI_UNICAST && safi != SAFI_MULTICAST)
- return 0;
+ if (!attr)
+ return;
+ extra = bgp_attr_extra_get(attr);
+
+ if (eth_s_id == NULL) {
+ memset(&(extra->evpn_overlay.eth_s_id), 0,
+ sizeof(struct eth_segment_id));
+ } else {
+ memcpy(&(extra->evpn_overlay.eth_s_id), eth_s_id,
+ sizeof(struct eth_segment_id));
+ }
+ if (gw_ip == NULL) {
+ memset(&(extra->evpn_overlay.gw_ip), 0, sizeof(union gw_addr));
+ } else {
+ memcpy(&(extra->evpn_overlay.gw_ip), gw_ip,
+ sizeof(union gw_addr));
+ }
+}
- /* If NEXT_HOP is present, validate it. */
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP))
- {
- if (attr->nexthop.s_addr == 0 ||
- IPV4_CLASS_DE (ntohl (attr->nexthop.s_addr)) ||
- bgp_nexthop_self (bgp, attr))
- ret = 1;
- }
+static bool overlay_index_equal(afi_t afi, struct bgp_info *info,
+ struct eth_segment_id *eth_s_id,
+ union gw_addr *gw_ip)
+{
+ struct eth_segment_id *info_eth_s_id, *info_eth_s_id_remote;
+ union gw_addr *info_gw_ip, *info_gw_ip_remote;
+ char temp[16];
+
+ if (afi != AFI_L2VPN)
+ return true;
+ if (!info->attr || !info->attr->extra) {
+ memset(&temp, 0, 16);
+ info_eth_s_id = (struct eth_segment_id *)&temp;
+ info_gw_ip = (union gw_addr *)&temp;
+ if (eth_s_id == NULL && gw_ip == NULL)
+ return true;
+ } else {
+ info_eth_s_id = &(info->attr->extra->evpn_overlay.eth_s_id);
+ info_gw_ip = &(info->attr->extra->evpn_overlay.gw_ip);
+ }
+ if (gw_ip == NULL)
+ info_gw_ip_remote = (union gw_addr *)&temp;
+ else
+ info_gw_ip_remote = gw_ip;
+ if (eth_s_id == NULL)
+ info_eth_s_id_remote = (struct eth_segment_id *)&temp;
+ else
+ info_eth_s_id_remote = eth_s_id;
+ if (!memcmp(info_gw_ip, info_gw_ip_remote, sizeof(union gw_addr)))
+ return false;
+ return !memcmp(info_eth_s_id, info_eth_s_id_remote,
+ sizeof(struct eth_segment_id));
+}
- /* If MP_NEXTHOP is present, validate it. */
- /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
- * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
- * it is not an IPv6 link-local address.
- */
- if (attre && attre->mp_nexthop_len)
- {
- switch (attre->mp_nexthop_len)
- {
- case BGP_ATTR_NHLEN_IPV4:
- case BGP_ATTR_NHLEN_VPNV4:
- ret = (attre->mp_nexthop_global_in.s_addr == 0 ||
- IPV4_CLASS_DE (ntohl (attre->mp_nexthop_global_in.s_addr)));
- break;
-
- case BGP_ATTR_NHLEN_IPV6_GLOBAL:
- case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
- case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
- ret = (IN6_IS_ADDR_UNSPECIFIED(&attre->mp_nexthop_global) ||
- IN6_IS_ADDR_LOOPBACK(&attre->mp_nexthop_global) ||
- IN6_IS_ADDR_MULTICAST(&attre->mp_nexthop_global));
- break;
-
- default:
- ret = 1;
- break;
- }
- }
+/* Check if received nexthop is valid or not. */
+static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
+ struct attr *attr)
+{
+ struct attr_extra *attre = attr->extra;
+ int ret = 0;
+
+ /* Only validated for unicast and multicast currently. */
+ if (safi != SAFI_UNICAST && safi != SAFI_MULTICAST)
+ return 0;
+
+ /* If NEXT_HOP is present, validate it. */
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
+ if (attr->nexthop.s_addr == 0
+ || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr))
+ || bgp_nexthop_self(bgp, attr))
+ ret = 1;
+ }
+
+ /* If MP_NEXTHOP is present, validate it. */
+ /* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
+ * there is code in bgp_attr.c to ignore the link-local (2nd) nexthop if
+ * it is not an IPv6 link-local address.
+ */
+ if (attre && attre->mp_nexthop_len) {
+ switch (attre->mp_nexthop_len) {
+ case BGP_ATTR_NHLEN_IPV4:
+ case BGP_ATTR_NHLEN_VPNV4:
+ ret = (attre->mp_nexthop_global_in.s_addr == 0
+ || IPV4_CLASS_DE(ntohl(
+ attre->mp_nexthop_global_in.s_addr)));
+ break;
+
+ case BGP_ATTR_NHLEN_IPV6_GLOBAL:
+ case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
+ case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
+ ret = (IN6_IS_ADDR_UNSPECIFIED(
+ &attre->mp_nexthop_global)
+ || IN6_IS_ADDR_LOOPBACK(
+ &attre->mp_nexthop_global)
+ || IN6_IS_ADDR_MULTICAST(
+ &attre->mp_nexthop_global));
+ break;
+
+ default:
+ ret = 1;
+ break;
+ }
+ }
- return ret;
-}
-
-int
-bgp_update (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
- struct attr *attr, afi_t afi, safi_t safi, int type,
- int sub_type, struct prefix_rd *prd, u_char *tag,
- int soft_reconfig, struct bgp_route_evpn* evpn)
-{
- int ret;
- int aspath_loop_count = 0;
- struct bgp_node *rn;
- struct bgp *bgp;
- struct attr new_attr;
- struct attr_extra new_extra;
- struct attr *attr_new;
- struct bgp_info *ri;
- struct bgp_info *new;
- const char *reason;
- char pfx_buf[BGP_PRD_PATH_STRLEN];
- int connected = 0;
- int do_loop_check = 1;
+ return ret;
+}
+
+int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
+ struct attr *attr, afi_t afi, safi_t safi, int type,
+ int sub_type, struct prefix_rd *prd, u_char *tag,
+ int soft_reconfig, struct bgp_route_evpn *evpn)
+{
+ int ret;
+ int aspath_loop_count = 0;
+ struct bgp_node *rn;
+ struct bgp *bgp;
+ struct attr new_attr;
+ struct attr_extra new_extra;
+ struct attr *attr_new;
+ struct bgp_info *ri;
+ struct bgp_info *new;
+ const char *reason;
+ char pfx_buf[BGP_PRD_PATH_STRLEN];
+ int connected = 0;
+ int do_loop_check = 1;
#if ENABLE_BGP_VNC
- int vnc_implicit_withdraw = 0;
+ int vnc_implicit_withdraw = 0;
#endif
- memset (&new_attr, 0, sizeof(struct attr));
- memset (&new_extra, 0, sizeof(struct attr_extra));
+ memset(&new_attr, 0, sizeof(struct attr));
+ memset(&new_extra, 0, sizeof(struct attr_extra));
- bgp = peer->bgp;
- rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
-
- /* When peer's soft reconfiguration enabled. Record input packet in
- Adj-RIBs-In. */
- if (! soft_reconfig && CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
- && peer != bgp->peer_self)
- bgp_adj_in_set (rn, peer, attr, addpath_id);
-
- /* Check previously received route. */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type &&
- ri->addpath_rx_id == addpath_id)
- break;
-
- /* AS path local-as loop check. */
- if (peer->change_local_as)
- {
- if (! CHECK_FLAG (peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND))
- aspath_loop_count = 1;
+ bgp = peer->bgp;
+ rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
- if (aspath_loop_check (attr->aspath, peer->change_local_as) > aspath_loop_count)
- {
- reason = "as-path contains our own AS;";
- goto filtered;
- }
- }
+ /* When peer's soft reconfiguration enabled. Record input packet in
+ Adj-RIBs-In. */
+ if (!soft_reconfig
+ && CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
+ && peer != bgp->peer_self)
+ bgp_adj_in_set(rn, peer, attr, addpath_id);
- /* If the peer is configured for "allowas-in origin" and the last ASN in the
- * as-path is our ASN then we do not need to call aspath_loop_check
- */
- if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
- if (aspath_get_last_as(attr->aspath) == bgp->as)
- do_loop_check = 0;
+ /* Check previously received route. */
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == peer && ri->type == type
+ && ri->sub_type == sub_type
+ && ri->addpath_rx_id == addpath_id)
+ break;
+
+ /* AS path local-as loop check. */
+ if (peer->change_local_as) {
+ if (!CHECK_FLAG(peer->flags, PEER_FLAG_LOCAL_AS_NO_PREPEND))
+ aspath_loop_count = 1;
+
+ if (aspath_loop_check(attr->aspath, peer->change_local_as)
+ > aspath_loop_count) {
+ reason = "as-path contains our own AS;";
+ goto filtered;
+ }
+ }
- /* AS path loop check. */
- if (do_loop_check)
- {
- if (aspath_loop_check (attr->aspath, bgp->as) > peer->allowas_in[afi][safi]
- || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
- && aspath_loop_check(attr->aspath, bgp->confed_id) > peer->allowas_in[afi][safi]))
- {
- reason = "as-path contains our own AS;";
- goto filtered;
- }
- }
+ /* If the peer is configured for "allowas-in origin" and the last ASN in
+ * the
+ * as-path is our ASN then we do not need to call aspath_loop_check
+ */
+ if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN_ORIGIN))
+ if (aspath_get_last_as(attr->aspath) == bgp->as)
+ do_loop_check = 0;
+
+ /* AS path loop check. */
+ if (do_loop_check) {
+ if (aspath_loop_check(attr->aspath, bgp->as)
+ > peer->allowas_in[afi][safi]
+ || (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION)
+ && aspath_loop_check(attr->aspath, bgp->confed_id)
+ > peer->allowas_in[afi][safi])) {
+ reason = "as-path contains our own AS;";
+ goto filtered;
+ }
+ }
- /* Route reflector originator ID check. */
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID)
- && IPV4_ADDR_SAME (&bgp->router_id, &attr->extra->originator_id))
- {
- reason = "originator is us;";
- goto filtered;
- }
+ /* Route reflector originator ID check. */
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)
+ && IPV4_ADDR_SAME(&bgp->router_id, &attr->extra->originator_id)) {
+ reason = "originator is us;";
+ goto filtered;
+ }
- /* Route reflector cluster ID check. */
- if (bgp_cluster_filter (peer, attr))
- {
- reason = "reflected from the same cluster;";
- goto filtered;
- }
+ /* Route reflector cluster ID check. */
+ if (bgp_cluster_filter(peer, attr)) {
+ reason = "reflected from the same cluster;";
+ goto filtered;
+ }
- /* Apply incoming filter. */
- if (bgp_input_filter (peer, p, attr, afi, safi) == FILTER_DENY)
- {
- reason = "filter;";
- goto filtered;
- }
+ /* Apply incoming filter. */
+ if (bgp_input_filter(peer, p, attr, afi, safi) == FILTER_DENY) {
+ reason = "filter;";
+ goto filtered;
+ }
- new_attr.extra = &new_extra;
- bgp_attr_dup (&new_attr, attr);
+ new_attr.extra = &new_extra;
+ bgp_attr_dup(&new_attr, attr);
+
+ /* Apply incoming route-map.
+ * NB: new_attr may now contain newly allocated values from route-map
+ * "set"
+ * commands, so we need bgp_attr_flush in the error paths, until we
+ * intern
+ * the attr (which takes over the memory references) */
+ if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL)
+ == RMAP_DENY) {
+ reason = "route-map;";
+ bgp_attr_flush(&new_attr);
+ goto filtered;
+ }
- /* Apply incoming route-map.
- * NB: new_attr may now contain newly allocated values from route-map "set"
- * commands, so we need bgp_attr_flush in the error paths, until we intern
- * the attr (which takes over the memory references) */
- if (bgp_input_modifier (peer, p, &new_attr, afi, safi, NULL) == RMAP_DENY)
- {
- reason = "route-map;";
- bgp_attr_flush (&new_attr);
- goto filtered;
- }
+ /* next hop check. */
+ if (bgp_update_martian_nexthop(bgp, afi, safi, &new_attr)) {
+ reason = "martian or self next-hop;";
+ bgp_attr_flush(&new_attr);
+ goto filtered;
+ }
- /* next hop check. */
- if (bgp_update_martian_nexthop (bgp, afi, safi, &new_attr))
- {
- reason = "martian or self next-hop;";
- bgp_attr_flush (&new_attr);
- goto filtered;
- }
+ attr_new = bgp_attr_intern(&new_attr);
+
+ /* If the update is implicit withdraw. */
+ if (ri) {
+ ri->uptime = bgp_clock();
+
+ /* Same attribute comes in. */
+ if (!CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)
+ && attrhash_cmp(ri->attr, attr_new)
+ && (overlay_index_equal(
+ afi, ri, evpn == NULL ? NULL : &evpn->eth_s_id,
+ evpn == NULL ? NULL : &evpn->gw_ip))) {
+ if (CHECK_FLAG(bgp->af_flags[afi][safi],
+ BGP_CONFIG_DAMPENING)
+ && peer->sort == BGP_PEER_EBGP
+ && CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)) {
+ if (bgp_debug_update(peer, p, NULL, 1))
+ zlog_debug("%s rcvd %s", peer->host,
+ bgp_debug_rdpfxpath2str(
+ prd, p,
+ addpath_id ? 1 : 0,
+ addpath_id, pfx_buf,
+ sizeof(pfx_buf)));
+
+ if (bgp_damp_update(ri, rn, afi, safi)
+ != BGP_DAMP_SUPPRESSED) {
+ bgp_aggregate_increment(bgp, p, ri, afi,
+ safi);
+ bgp_process(bgp, rn, afi, safi);
+ }
+ } else /* Duplicate - odd */
+ {
+ if (bgp_debug_update(peer, p, NULL, 1)) {
+ if (!peer->rcvd_attr_printed) {
+ zlog_debug(
+ "%s rcvd UPDATE w/ attr: %s",
+ peer->host,
+ peer->rcvd_attr_str);
+ peer->rcvd_attr_printed = 1;
+ }
+
+ zlog_debug(
+ "%s rcvd %s...duplicate ignored",
+ peer->host,
+ bgp_debug_rdpfxpath2str(
+ prd, p,
+ addpath_id ? 1 : 0,
+ addpath_id, pfx_buf,
+ sizeof(pfx_buf)));
+ }
+
+ /* graceful restart STALE flag unset. */
+ if (CHECK_FLAG(ri->flags, BGP_INFO_STALE)) {
+ bgp_info_unset_flag(rn, ri,
+ BGP_INFO_STALE);
+ bgp_process(bgp, rn, afi, safi);
+ }
+ }
+
+ bgp_unlock_node(rn);
+ bgp_attr_unintern(&attr_new);
+
+ return 0;
+ }
- attr_new = bgp_attr_intern (&new_attr);
+ /* Withdraw/Announce before we fully processed the withdraw */
+ if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
+ if (bgp_debug_update(peer, p, NULL, 1))
+ zlog_debug(
+ "%s rcvd %s, flapped quicker than processing",
+ peer->host,
+ bgp_debug_rdpfxpath2str(
+ prd, p, addpath_id ? 1 : 0,
+ addpath_id, pfx_buf,
+ sizeof(pfx_buf)));
+ bgp_info_restore(rn, ri);
+ }
- /* If the update is implicit withdraw. */
- if (ri)
- {
- ri->uptime = bgp_clock ();
-
- /* Same attribute comes in. */
- if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)
- && attrhash_cmp (ri->attr, attr_new)
- && (overlay_index_equal(afi, ri, evpn==NULL?NULL:&evpn->eth_s_id,
- evpn==NULL?NULL:&evpn->gw_ip)))
- {
- if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
- && peer->sort == BGP_PEER_EBGP
- && CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
- {
- if (bgp_debug_update(peer, p, NULL, 1))
- zlog_debug ("%s rcvd %s", peer->host,
- bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
-
- if (bgp_damp_update (ri, rn, afi, safi) != BGP_DAMP_SUPPRESSED)
- {
- bgp_aggregate_increment (bgp, p, ri, afi, safi);
- bgp_process (bgp, rn, afi, safi);
- }
- }
- else /* Duplicate - odd */
- {
- if (bgp_debug_update(peer, p, NULL, 1))
- {
- if (!peer->rcvd_attr_printed)
- {
- zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer->host, peer->rcvd_attr_str);
- peer->rcvd_attr_printed = 1;
- }
-
- zlog_debug ("%s rcvd %s...duplicate ignored",
- peer->host,
- bgp_debug_rdpfxpath2str (prd, p, addpath_id ?
- 1 : 0, addpath_id, pfx_buf, sizeof (pfx_buf)));
- }
-
- /* graceful restart STALE flag unset. */
- if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
- {
- bgp_info_unset_flag (rn, ri, BGP_INFO_STALE);
- bgp_process (bgp, rn, afi, safi);
- }
- }
-
- bgp_unlock_node (rn);
- bgp_attr_unintern (&attr_new);
-
- return 0;
- }
-
- /* Withdraw/Announce before we fully processed the withdraw */
- if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
- {
- if (bgp_debug_update(peer, p, NULL, 1))
- zlog_debug ("%s rcvd %s, flapped quicker than processing",
- peer->host,
- bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
- bgp_info_restore (rn, ri);
- }
-
- /* Received Logging. */
- if (bgp_debug_update(peer, p, NULL, 1))
- zlog_debug ("%s rcvd %s", peer->host,
- bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
-
- /* graceful restart STALE flag unset. */
- if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
- bgp_info_unset_flag (rn, ri, BGP_INFO_STALE);
-
- /* The attribute is changed. */
- bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
-
- /* implicit withdraw, decrement aggregate and pcount here.
- * only if update is accepted, they'll increment below.
- */
- bgp_aggregate_decrement (bgp, p, ri, afi, safi);
-
- /* Update bgp route dampening information. */
- if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
- && peer->sort == BGP_PEER_EBGP)
- {
- /* This is implicit withdraw so we should update dampening
- information. */
- if (! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
- bgp_damp_withdraw (ri, rn, afi, safi, 1);
- }
+ /* Received Logging. */
+ if (bgp_debug_update(peer, p, NULL, 1))
+ zlog_debug("%s rcvd %s", peer->host,
+ bgp_debug_rdpfxpath2str(prd, p,
+ addpath_id ? 1 : 0,
+ addpath_id, pfx_buf,
+ sizeof(pfx_buf)));
+
+ /* graceful restart STALE flag unset. */
+ if (CHECK_FLAG(ri->flags, BGP_INFO_STALE))
+ bgp_info_unset_flag(rn, ri, BGP_INFO_STALE);
+
+ /* The attribute is changed. */
+ bgp_info_set_flag(rn, ri, BGP_INFO_ATTR_CHANGED);
+
+ /* implicit withdraw, decrement aggregate and pcount here.
+ * only if update is accepted, they'll increment below.
+ */
+ bgp_aggregate_decrement(bgp, p, ri, afi, safi);
+
+ /* Update bgp route dampening information. */
+ if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
+ && peer->sort == BGP_PEER_EBGP) {
+ /* This is implicit withdraw so we should update
+ dampening
+ information. */
+ if (!CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
+ bgp_damp_withdraw(ri, rn, afi, safi, 1);
+ }
#if ENABLE_BGP_VNC
- if (safi == SAFI_MPLS_VPN) {
- struct bgp_node *prn = NULL;
- struct bgp_table *table = NULL;
-
- prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *) prd);
- if (prn->info) {
- table = (struct bgp_table *)(prn->info);
-
- vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
- bgp,
- prd,
- table,
- p,
- ri);
- }
- bgp_unlock_node(prn);
- }
- if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
- if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) {
- /*
- * Implicit withdraw case.
- */
- ++vnc_implicit_withdraw;
- vnc_import_bgp_del_route(bgp, p, ri);
- vnc_import_bgp_exterior_del_route(bgp, p, ri);
- }
- }
+ if (safi == SAFI_MPLS_VPN) {
+ struct bgp_node *prn = NULL;
+ struct bgp_table *table = NULL;
+
+ prn = bgp_node_get(bgp->rib[afi][safi],
+ (struct prefix *)prd);
+ if (prn->info) {
+ table = (struct bgp_table *)(prn->info);
+
+ vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
+ bgp, prd, table, p, ri);
+ }
+ bgp_unlock_node(prn);
+ }
+ if ((afi == AFI_IP || afi == AFI_IP6)
+ && (safi == SAFI_UNICAST)) {
+ if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
+ /*
+ * Implicit withdraw case.
+ */
+ ++vnc_implicit_withdraw;
+ vnc_import_bgp_del_route(bgp, p, ri);
+ vnc_import_bgp_exterior_del_route(bgp, p, ri);
+ }
+ }
#endif
-
- /* Update to new attribute. */
- bgp_attr_unintern (&ri->attr);
- ri->attr = attr_new;
- /* Update MPLS tag. */
- if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN)
- memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
+ /* Update to new attribute. */
+ bgp_attr_unintern(&ri->attr);
+ ri->attr = attr_new;
+
+ /* Update MPLS tag. */
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN)
+ memcpy((bgp_info_extra_get(ri))->tag, tag, 3);
#if ENABLE_BGP_VNC
- if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST))
- {
- if (vnc_implicit_withdraw)
- {
- /*
- * Add back the route with its new attributes (e.g., nexthop).
- * The route is still selected, until the route selection
- * queued by bgp_process actually runs. We have to make this
- * update to the VNC side immediately to avoid racing against
- * configuration changes (e.g., route-map changes) which
- * trigger re-importation of the entire RIB.
- */
- vnc_import_bgp_add_route(bgp, p, ri);
- vnc_import_bgp_exterior_add_route(bgp, p, ri);
- }
- }
+ if ((afi == AFI_IP || afi == AFI_IP6)
+ && (safi == SAFI_UNICAST)) {
+ if (vnc_implicit_withdraw) {
+ /*
+ * Add back the route with its new attributes
+ * (e.g., nexthop).
+ * The route is still selected, until the route
+ * selection
+ * queued by bgp_process actually runs. We have
+ * to make this
+ * update to the VNC side immediately to avoid
+ * racing against
+ * configuration changes (e.g., route-map
+ * changes) which
+ * trigger re-importation of the entire RIB.
+ */
+ vnc_import_bgp_add_route(bgp, p, ri);
+ vnc_import_bgp_exterior_add_route(bgp, p, ri);
+ }
+ }
#endif
- /* Update Overlay Index */
- if(afi == AFI_L2VPN)
- {
- overlay_index_update(ri->attr, evpn==NULL?NULL:&evpn->eth_s_id,
- evpn==NULL?NULL:&evpn->gw_ip);
- }
-
- /* Update bgp route dampening information. */
- if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
- && peer->sort == BGP_PEER_EBGP)
- {
- /* Now we do normal update dampening. */
- ret = bgp_damp_update (ri, rn, afi, safi);
- if (ret == BGP_DAMP_SUPPRESSED)
- {
- bgp_unlock_node (rn);
- return 0;
- }
- }
-
- /* Nexthop reachability check. */
- if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)
- {
- if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 &&
- ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
- && ! bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
- connected = 1;
- else
- connected = 0;
-
- if (bgp_find_or_add_nexthop (bgp, afi, ri, NULL, connected))
- bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
- else
- {
- if (BGP_DEBUG(nht, NHT))
- {
- char buf1[INET6_ADDRSTRLEN];
- inet_ntop(AF_INET, (const void *)&attr_new->nexthop, buf1, INET6_ADDRSTRLEN);
- zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1);
+ /* Update Overlay Index */
+ if (afi == AFI_L2VPN) {
+ overlay_index_update(
+ ri->attr, evpn == NULL ? NULL : &evpn->eth_s_id,
+ evpn == NULL ? NULL : &evpn->gw_ip);
}
- bgp_info_unset_flag (rn, ri, BGP_INFO_VALID);
- }
- }
- else
- bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
+
+ /* Update bgp route dampening information. */
+ if (CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
+ && peer->sort == BGP_PEER_EBGP) {
+ /* Now we do normal update dampening. */
+ ret = bgp_damp_update(ri, rn, afi, safi);
+ if (ret == BGP_DAMP_SUPPRESSED) {
+ bgp_unlock_node(rn);
+ return 0;
+ }
+ }
+
+ /* Nexthop reachability check. */
+ if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST) {
+ if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1
+ && !CHECK_FLAG(peer->flags,
+ PEER_FLAG_DISABLE_CONNECTED_CHECK)
+ && !bgp_flag_check(
+ bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
+ connected = 1;
+ else
+ connected = 0;
+
+ if (bgp_find_or_add_nexthop(bgp, afi, ri, NULL,
+ connected))
+ bgp_info_set_flag(rn, ri, BGP_INFO_VALID);
+ else {
+ if (BGP_DEBUG(nht, NHT)) {
+ char buf1[INET6_ADDRSTRLEN];
+ inet_ntop(AF_INET,
+ (const void *)&attr_new
+ ->nexthop,
+ buf1, INET6_ADDRSTRLEN);
+ zlog_debug("%s(%s): NH unresolved",
+ __FUNCTION__, buf1);
+ }
+ bgp_info_unset_flag(rn, ri, BGP_INFO_VALID);
+ }
+ } else
+ bgp_info_set_flag(rn, ri, BGP_INFO_VALID);
#if ENABLE_BGP_VNC
- if (safi == SAFI_MPLS_VPN)
- {
- struct bgp_node *prn = NULL;
- struct bgp_table *table = NULL;
-
- prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *) prd);
- if (prn->info)
- {
- table = (struct bgp_table *)(prn->info);
-
- vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
- bgp,
- prd,
- table,
- p,
- ri);
- }
- bgp_unlock_node(prn);
- }
+ if (safi == SAFI_MPLS_VPN) {
+ struct bgp_node *prn = NULL;
+ struct bgp_table *table = NULL;
+
+ prn = bgp_node_get(bgp->rib[afi][safi],
+ (struct prefix *)prd);
+ if (prn->info) {
+ table = (struct bgp_table *)(prn->info);
+
+ vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
+ bgp, prd, table, p, ri);
+ }
+ bgp_unlock_node(prn);
+ }
#endif
- /* Process change. */
- bgp_aggregate_increment (bgp, p, ri, afi, safi);
+ /* Process change. */
+ bgp_aggregate_increment(bgp, p, ri, afi, safi);
- bgp_process (bgp, rn, afi, safi);
- bgp_unlock_node (rn);
+ bgp_process(bgp, rn, afi, safi);
+ bgp_unlock_node(rn);
#if ENABLE_BGP_VNC
- if (SAFI_MPLS_VPN == safi)
- {
- uint32_t label = decode_label(tag);
+ if (SAFI_MPLS_VPN == safi) {
+ uint32_t label = decode_label(tag);
- rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
- &label);
- }
- if (SAFI_ENCAP == safi)
- {
- rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
- NULL);
- }
+ rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
+ type, sub_type, &label);
+ }
+ if (SAFI_ENCAP == safi) {
+ rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi,
+ type, sub_type, NULL);
+ }
#endif
- return 0;
- } // End of implicit withdraw
+ return 0;
+ } // End of implicit withdraw
- /* Received Logging. */
- if (bgp_debug_update(peer, p, NULL, 1))
- {
- if (!peer->rcvd_attr_printed)
- {
- zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer->host, peer->rcvd_attr_str);
- peer->rcvd_attr_printed = 1;
- }
-
- zlog_debug ("%s rcvd %s", peer->host,
- bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
- }
+ /* Received Logging. */
+ if (bgp_debug_update(peer, p, NULL, 1)) {
+ if (!peer->rcvd_attr_printed) {
+ zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
+ peer->rcvd_attr_str);
+ peer->rcvd_attr_printed = 1;
+ }
- /* Make new BGP info. */
- new = info_make(type, sub_type, 0, peer, attr_new, rn);
+ zlog_debug("%s rcvd %s", peer->host,
+ bgp_debug_rdpfxpath2str(prd, p, addpath_id ? 1 : 0,
+ addpath_id, pfx_buf,
+ sizeof(pfx_buf)));
+ }
- /* Update MPLS tag. */
- if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN)
- memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
+ /* Make new BGP info. */
+ new = info_make(type, sub_type, 0, peer, attr_new, rn);
- /* Update Overlay Index */
- if(afi == AFI_L2VPN)
- {
- overlay_index_update(new->attr, evpn==NULL?NULL:&evpn->eth_s_id,
- evpn==NULL?NULL:&evpn->gw_ip);
- }
- /* Nexthop reachability check. */
- if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST)
- {
- if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1 &&
- ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)
- && ! bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
- connected = 1;
- else
- connected = 0;
-
- if (bgp_find_or_add_nexthop (bgp, afi, new, NULL, connected))
- bgp_info_set_flag (rn, new, BGP_INFO_VALID);
- else
- {
- if (BGP_DEBUG(nht, NHT))
- {
- char buf1[INET6_ADDRSTRLEN];
- inet_ntop(AF_INET, (const void *)&attr_new->nexthop, buf1, INET6_ADDRSTRLEN);
- zlog_debug("%s(%s): NH unresolved", __FUNCTION__, buf1);
- }
- bgp_info_unset_flag (rn, new, BGP_INFO_VALID);
+ /* Update MPLS tag. */
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_EVPN)
+ memcpy((bgp_info_extra_get(new))->tag, tag, 3);
+
+ /* Update Overlay Index */
+ if (afi == AFI_L2VPN) {
+ overlay_index_update(new->attr,
+ evpn == NULL ? NULL : &evpn->eth_s_id,
+ evpn == NULL ? NULL : &evpn->gw_ip);
}
- }
- else
- bgp_info_set_flag (rn, new, BGP_INFO_VALID);
+ /* Nexthop reachability check. */
+ if ((afi == AFI_IP || afi == AFI_IP6) && safi == SAFI_UNICAST) {
+ if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1
+ && !CHECK_FLAG(peer->flags,
+ PEER_FLAG_DISABLE_CONNECTED_CHECK)
+ && !bgp_flag_check(bgp, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
+ connected = 1;
+ else
+ connected = 0;
+
+ if (bgp_find_or_add_nexthop(bgp, afi, new, NULL, connected))
+ bgp_info_set_flag(rn, new, BGP_INFO_VALID);
+ else {
+ if (BGP_DEBUG(nht, NHT)) {
+ char buf1[INET6_ADDRSTRLEN];
+ inet_ntop(AF_INET,
+ (const void *)&attr_new->nexthop,
+ buf1, INET6_ADDRSTRLEN);
+ zlog_debug("%s(%s): NH unresolved",
+ __FUNCTION__, buf1);
+ }
+ bgp_info_unset_flag(rn, new, BGP_INFO_VALID);
+ }
+ } else
+ bgp_info_set_flag(rn, new, BGP_INFO_VALID);
- /* Addpath ID */
- new->addpath_rx_id = addpath_id;
+ /* Addpath ID */
+ new->addpath_rx_id = addpath_id;
- /* Increment prefix */
- bgp_aggregate_increment (bgp, p, new, afi, safi);
-
- /* Register new BGP information. */
- bgp_info_add (rn, new);
-
- /* route_node_get lock */
- bgp_unlock_node (rn);
+ /* Increment prefix */
+ bgp_aggregate_increment(bgp, p, new, afi, safi);
+
+ /* Register new BGP information. */
+ bgp_info_add(rn, new);
+
+ /* route_node_get lock */
+ bgp_unlock_node(rn);
#if ENABLE_BGP_VNC
- if (safi == SAFI_MPLS_VPN)
- {
- struct bgp_node *prn = NULL;
- struct bgp_table *table = NULL;
-
- prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *) prd);
- if (prn->info)
- {
- table = (struct bgp_table *)(prn->info);
-
- vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
- bgp,
- prd,
- table,
- p,
- new);
- }
- bgp_unlock_node(prn);
- }
+ if (safi == SAFI_MPLS_VPN) {
+ struct bgp_node *prn = NULL;
+ struct bgp_table *table = NULL;
+
+ prn = bgp_node_get(bgp->rib[afi][safi], (struct prefix *)prd);
+ if (prn->info) {
+ table = (struct bgp_table *)(prn->info);
+
+ vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
+ bgp, prd, table, p, new);
+ }
+ bgp_unlock_node(prn);
+ }
#endif
- /* If maximum prefix count is configured and current prefix
- count exeed it. */
- if (bgp_maximum_prefix_overflow (peer, afi, safi, 0))
- return -1;
+ /* If maximum prefix count is configured and current prefix
+ count exeed it. */
+ if (bgp_maximum_prefix_overflow(peer, afi, safi, 0))
+ return -1;
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
+ /* Process change. */
+ bgp_process(bgp, rn, afi, safi);
#if ENABLE_BGP_VNC
- if (SAFI_MPLS_VPN == safi)
- {
- uint32_t label = decode_label(tag);
+ if (SAFI_MPLS_VPN == safi) {
+ uint32_t label = decode_label(tag);
- rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
- &label);
- }
- if (SAFI_ENCAP == safi)
- {
- rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type, sub_type,
- NULL);
- }
+ rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
+ sub_type, &label);
+ }
+ if (SAFI_ENCAP == safi) {
+ rfapiProcessUpdate(peer, NULL, p, prd, attr, afi, safi, type,
+ sub_type, NULL);
+ }
#endif
- return 0;
+ return 0;
- /* This BGP update is filtered. Log the reason then update BGP
- entry. */
- filtered:
- if (bgp_debug_update(peer, p, NULL, 1))
- {
- if (!peer->rcvd_attr_printed)
- {
- zlog_debug ("%s rcvd UPDATE w/ attr: %s", peer->host, peer->rcvd_attr_str);
- peer->rcvd_attr_printed = 1;
- }
-
- zlog_debug ("%s rcvd UPDATE about %s -- DENIED due to: %s",
- peer->host,
- bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)), reason);
- }
+/* This BGP update is filtered. Log the reason then update BGP
+ entry. */
+filtered:
+ if (bgp_debug_update(peer, p, NULL, 1)) {
+ if (!peer->rcvd_attr_printed) {
+ zlog_debug("%s rcvd UPDATE w/ attr: %s", peer->host,
+ peer->rcvd_attr_str);
+ peer->rcvd_attr_printed = 1;
+ }
- if (ri)
- bgp_rib_remove (rn, ri, peer, afi, safi);
+ zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
+ peer->host,
+ bgp_debug_rdpfxpath2str(prd, p, addpath_id ? 1 : 0,
+ addpath_id, pfx_buf,
+ sizeof(pfx_buf)),
+ reason);
+ }
+
+ if (ri)
+ bgp_rib_remove(rn, ri, peer, afi, safi);
- bgp_unlock_node (rn);
+ bgp_unlock_node(rn);
#if ENABLE_BGP_VNC
- /*
- * Filtered update is treated as an implicit withdrawal (see bgp_rib_remove()
- * a few lines above)
- */
- if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi))
- {
- rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type, 0);
- }
+ /*
+ * Filtered update is treated as an implicit withdrawal (see
+ * bgp_rib_remove()
+ * a few lines above)
+ */
+ if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
+ rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
+ 0);
+ }
#endif
- return 0;
+ return 0;
}
-int
-bgp_withdraw (struct peer *peer, struct prefix *p, u_int32_t addpath_id,
- struct attr *attr, afi_t afi, safi_t safi, int type, int sub_type,
- struct prefix_rd *prd, u_char *tag, struct bgp_route_evpn *evpn)
+int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
+ struct attr *attr, afi_t afi, safi_t safi, int type,
+ int sub_type, struct prefix_rd *prd, u_char *tag,
+ struct bgp_route_evpn *evpn)
{
- struct bgp *bgp;
- char pfx_buf[BGP_PRD_PATH_STRLEN];
- struct bgp_node *rn;
- struct bgp_info *ri;
+ struct bgp *bgp;
+ char pfx_buf[BGP_PRD_PATH_STRLEN];
+ struct bgp_node *rn;
+ struct bgp_info *ri;
#if ENABLE_BGP_VNC
- if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi))
- {
- rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type, 0);
- }
+ if ((SAFI_MPLS_VPN == safi) || (SAFI_ENCAP == safi)) {
+ rfapiProcessWithdraw(peer, NULL, p, prd, NULL, afi, safi, type,
+ 0);
+ }
#endif
- bgp = peer->bgp;
-
- /* Lookup node. */
- rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
-
- /* If peer is soft reconfiguration enabled. Record input packet for
- * further calculation.
- *
- * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
- * routes that are filtered. This tanks out Quagga RS pretty badly due to
- * the iteration over all RS clients.
- * Since we need to remove the entry from adj_in anyway, do that first and
- * if there was no entry, we don't need to do anything more.
- */
- if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
- && peer != bgp->peer_self)
- if (!bgp_adj_in_unset (rn, peer, addpath_id))
- {
- if (bgp_debug_update (peer, p, NULL, 1))
- zlog_debug ("%s withdrawing route %s not in adj-in",
- peer->host,
- bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
- bgp_unlock_node (rn);
- return 0;
- }
-
- /* Lookup withdrawn route. */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type &&
- ri->addpath_rx_id == addpath_id)
- break;
-
- /* Logging. */
- if (bgp_debug_update(peer, p, NULL, 1))
- {
- zlog_debug ("%s rcvd UPDATE about %s -- withdrawn",
- peer->host,
- bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
- }
+ bgp = peer->bgp;
+
+ /* Lookup node. */
+ rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
+
+ /* If peer is soft reconfiguration enabled. Record input packet for
+ * further calculation.
+ *
+ * Cisco IOS 12.4(24)T4 on session establishment sends withdraws for all
+ * routes that are filtered. This tanks out Quagga RS pretty badly due
+ * to
+ * the iteration over all RS clients.
+ * Since we need to remove the entry from adj_in anyway, do that first
+ * and
+ * if there was no entry, we don't need to do anything more.
+ */
+ if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
+ && peer != bgp->peer_self)
+ if (!bgp_adj_in_unset(rn, peer, addpath_id)) {
+ if (bgp_debug_update(peer, p, NULL, 1))
+ zlog_debug(
+ "%s withdrawing route %s not in adj-in",
+ peer->host,
+ bgp_debug_rdpfxpath2str(
+ prd, p, addpath_id ? 1 : 0,
+ addpath_id, pfx_buf,
+ sizeof(pfx_buf)));
+ bgp_unlock_node(rn);
+ return 0;
+ }
- /* Withdraw specified route from routing table. */
- if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
- bgp_rib_withdraw (rn, ri, peer, afi, safi, prd);
- else if (bgp_debug_update(peer, p, NULL, 1))
- zlog_debug ("%s Can't find the route %s",
- peer->host,
- bgp_debug_rdpfxpath2str (prd, p, addpath_id ? 1 : 0,
- addpath_id, pfx_buf, sizeof (pfx_buf)));
+ /* Lookup withdrawn route. */
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == peer && ri->type == type
+ && ri->sub_type == sub_type
+ && ri->addpath_rx_id == addpath_id)
+ break;
+
+ /* Logging. */
+ if (bgp_debug_update(peer, p, NULL, 1)) {
+ zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
+ bgp_debug_rdpfxpath2str(prd, p, addpath_id ? 1 : 0,
+ addpath_id, pfx_buf,
+ sizeof(pfx_buf)));
+ }
+
+ /* Withdraw specified route from routing table. */
+ if (ri && !CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
+ bgp_rib_withdraw(rn, ri, peer, afi, safi, prd);
+ else if (bgp_debug_update(peer, p, NULL, 1))
+ zlog_debug("%s Can't find the route %s", peer->host,
+ bgp_debug_rdpfxpath2str(prd, p, addpath_id ? 1 : 0,
+ addpath_id, pfx_buf,
+ sizeof(pfx_buf)));
- /* Unlock bgp_node_get() lock. */
- bgp_unlock_node (rn);
+ /* Unlock bgp_node_get() lock. */
+ bgp_unlock_node(rn);
- return 0;
+ return 0;
}
-void
-bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
+void bgp_default_originate(struct peer *peer, afi_t afi, safi_t safi,
+ int withdraw)
{
- struct update_subgroup *subgrp;
- subgrp = peer_subgroup(peer, afi, safi);
- subgroup_default_originate(subgrp, withdraw);
+ struct update_subgroup *subgrp;
+ subgrp = peer_subgroup(peer, afi, safi);
+ subgroup_default_originate(subgrp, withdraw);
}
/*
* bgp_stop_announce_route_timer
*/
-void
-bgp_stop_announce_route_timer (struct peer_af *paf)
+void bgp_stop_announce_route_timer(struct peer_af *paf)
{
- if (!paf->t_announce_route)
- return;
-
- THREAD_TIMER_OFF (paf->t_announce_route);
+ if (!paf->t_announce_route)
+ return;
+
+ THREAD_TIMER_OFF(paf->t_announce_route);
}
/*
@@ -2998,26 +3002,25 @@ bgp_stop_announce_route_timer (struct peer_af *paf)
* Callback that is invoked when the route announcement timer for a
* peer_af expires.
*/
-static int
-bgp_announce_route_timer_expired (struct thread *t)
+static int bgp_announce_route_timer_expired(struct thread *t)
{
- struct peer_af *paf;
- struct peer *peer;
+ struct peer_af *paf;
+ struct peer *peer;
- paf = THREAD_ARG (t);
- peer = paf->peer;
+ paf = THREAD_ARG(t);
+ peer = paf->peer;
- assert (paf->t_announce_route);
- paf->t_announce_route = NULL;
+ assert(paf->t_announce_route);
+ paf->t_announce_route = NULL;
- if (peer->status != Established)
- return 0;
+ if (peer->status != Established)
+ return 0;
- if (!peer->afc_nego[paf->afi][paf->safi])
- return 0;
+ if (!peer->afc_nego[paf->afi][paf->safi])
+ return 0;
- peer_af_announce_route (paf, 1);
- return 0;
+ peer_af_announce_route(paf, 1);
+ return 0;
}
/*
@@ -3025,35 +3028,34 @@ bgp_announce_route_timer_expired (struct thread *t)
*
* *Triggers* announcement of routes of a given AFI/SAFI to a peer.
*/
-void
-bgp_announce_route (struct peer *peer, afi_t afi, safi_t safi)
-{
- struct peer_af *paf;
- struct update_subgroup *subgrp;
-
- paf = peer_af_find (peer, afi, safi);
- if (!paf)
- return;
- subgrp = PAF_SUBGRP(paf);
-
- /*
- * Ignore if subgroup doesn't exist (implies AF is not negotiated)
- * or a refresh has already been triggered.
- */
- if (!subgrp || paf->t_announce_route)
- return;
-
- /*
- * Start a timer to stagger/delay the announce. This serves
- * two purposes - announcement can potentially be combined for
- * multiple peers and the announcement doesn't happen in the
- * vty context.
- */
- THREAD_TIMER_MSEC_ON (bm->master, paf->t_announce_route,
- bgp_announce_route_timer_expired, paf,
- (subgrp->peer_count == 1) ?
- BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS :
- BGP_ANNOUNCE_ROUTE_DELAY_MS);
+void bgp_announce_route(struct peer *peer, afi_t afi, safi_t safi)
+{
+ struct peer_af *paf;
+ struct update_subgroup *subgrp;
+
+ paf = peer_af_find(peer, afi, safi);
+ if (!paf)
+ return;
+ subgrp = PAF_SUBGRP(paf);
+
+ /*
+ * Ignore if subgroup doesn't exist (implies AF is not negotiated)
+ * or a refresh has already been triggered.
+ */
+ if (!subgrp || paf->t_announce_route)
+ return;
+
+ /*
+ * Start a timer to stagger/delay the announce. This serves
+ * two purposes - announcement can potentially be combined for
+ * multiple peers and the announcement doesn't happen in the
+ * vty context.
+ */
+ THREAD_TIMER_MSEC_ON(bm->master, paf->t_announce_route,
+ bgp_announce_route_timer_expired, paf,
+ (subgrp->peer_count == 1)
+ ? BGP_ANNOUNCE_ROUTE_SHORT_DELAY_MS
+ : BGP_ANNOUNCE_ROUTE_DELAY_MS);
}
/*
@@ -3065,1385 +3067,1345 @@ bgp_announce_route (struct peer *peer, afi_t afi, safi_t safi)
* The operation will result in splitting the peer from its existing
* subgroups and putting it in new subgroups.
*/
-void
-bgp_announce_route_all (struct peer *peer)
+void bgp_announce_route_all(struct peer *peer)
{
- afi_t afi;
- safi_t safi;
-
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- bgp_announce_route (peer, afi, safi);
+ afi_t afi;
+ safi_t safi;
+
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ bgp_announce_route(peer, afi, safi);
}
-static void
-bgp_soft_reconfig_table (struct peer *peer, afi_t afi, safi_t safi,
- struct bgp_table *table, struct prefix_rd *prd)
+static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
+ struct bgp_table *table,
+ struct prefix_rd *prd)
{
- int ret;
- struct bgp_node *rn;
- struct bgp_adj_in *ain;
+ int ret;
+ struct bgp_node *rn;
+ struct bgp_adj_in *ain;
- if (! table)
- table = peer->bgp->rib[afi][safi];
+ if (!table)
+ table = peer->bgp->rib[afi][safi];
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- for (ain = rn->adj_in; ain; ain = ain->next)
- {
- if (ain->peer == peer)
- {
- struct bgp_info *ri = rn->info;
- u_char *tag = (ri && ri->extra) ? ri->extra->tag : NULL;
+ for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
+ for (ain = rn->adj_in; ain; ain = ain->next) {
+ if (ain->peer == peer) {
+ struct bgp_info *ri = rn->info;
+ u_char *tag = (ri && ri->extra) ? ri->extra->tag
+ : NULL;
- ret = bgp_update (peer, &rn->p, ain->addpath_rx_id, ain->attr,
- afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
- prd, tag, 1, NULL);
+ ret = bgp_update(
+ peer, &rn->p, ain->addpath_rx_id,
+ ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
+ BGP_ROUTE_NORMAL, prd, tag, 1, NULL);
- if (ret < 0)
- {
- bgp_unlock_node (rn);
- return;
- }
- }
- }
+ if (ret < 0) {
+ bgp_unlock_node(rn);
+ return;
+ }
+ }
+ }
}
-void
-bgp_soft_reconfig_in (struct peer *peer, afi_t afi, safi_t safi)
+void bgp_soft_reconfig_in(struct peer *peer, afi_t afi, safi_t safi)
{
- struct bgp_node *rn;
- struct bgp_table *table;
+ struct bgp_node *rn;
+ struct bgp_table *table;
- if (peer->status != Established)
- return;
+ if (peer->status != Established)
+ return;
- if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP) && (safi != SAFI_EVPN))
- bgp_soft_reconfig_table (peer, afi, safi, NULL, NULL);
- else
- for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
- rn = bgp_route_next (rn))
- if ((table = rn->info) != NULL)
- {
- struct prefix_rd prd;
- prd.family = AF_UNSPEC;
- prd.prefixlen = 64;
- memcpy(&prd.val, rn->p.u.val, 8);
+ if ((safi != SAFI_MPLS_VPN) && (safi != SAFI_ENCAP)
+ && (safi != SAFI_EVPN))
+ bgp_soft_reconfig_table(peer, afi, safi, NULL, NULL);
+ else
+ for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
+ rn = bgp_route_next(rn))
+ if ((table = rn->info) != NULL) {
+ struct prefix_rd prd;
+ prd.family = AF_UNSPEC;
+ prd.prefixlen = 64;
+ memcpy(&prd.val, rn->p.u.val, 8);
- bgp_soft_reconfig_table (peer, afi, safi, table, &prd);
- }
+ bgp_soft_reconfig_table(peer, afi, safi, table,
+ &prd);
+ }
}
-struct bgp_clear_node_queue
-{
- struct bgp_node *rn;
+struct bgp_clear_node_queue {
+ struct bgp_node *rn;
};
-static wq_item_status
-bgp_clear_route_node (struct work_queue *wq, void *data)
+static wq_item_status bgp_clear_route_node(struct work_queue *wq, void *data)
{
- struct bgp_clear_node_queue *cnq = data;
- struct bgp_node *rn = cnq->rn;
- struct peer *peer = wq->spec.data;
- struct bgp_info *ri;
- afi_t afi = bgp_node_table (rn)->afi;
- safi_t safi = bgp_node_table (rn)->safi;
-
- assert (rn && peer);
-
- /* It is possible that we have multiple paths for a prefix from a peer
- * if that peer is using AddPath.
- */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer)
- {
- /* graceful restart STALE flag set. */
- if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT)
- && peer->nsf[afi][safi]
- && ! CHECK_FLAG (ri->flags, BGP_INFO_STALE)
- && ! CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
- bgp_info_set_flag (rn, ri, BGP_INFO_STALE);
- else
- bgp_rib_remove (rn, ri, peer, afi, safi);
- }
- return WQ_SUCCESS;
-}
-
-static void
-bgp_clear_node_queue_del (struct work_queue *wq, void *data)
-{
- struct bgp_clear_node_queue *cnq = data;
- struct bgp_node *rn = cnq->rn;
- struct bgp_table *table = bgp_node_table (rn);
-
- bgp_unlock_node (rn);
- bgp_table_unlock (table);
- XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
+ struct bgp_clear_node_queue *cnq = data;
+ struct bgp_node *rn = cnq->rn;
+ struct peer *peer = wq->spec.data;
+ struct bgp_info *ri;
+ afi_t afi = bgp_node_table(rn)->afi;
+ safi_t safi = bgp_node_table(rn)->safi;
+
+ assert(rn && peer);
+
+ /* It is possible that we have multiple paths for a prefix from a peer
+ * if that peer is using AddPath.
+ */
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == peer) {
+ /* graceful restart STALE flag set. */
+ if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)
+ && peer->nsf[afi][safi]
+ && !CHECK_FLAG(ri->flags, BGP_INFO_STALE)
+ && !CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
+ bgp_info_set_flag(rn, ri, BGP_INFO_STALE);
+ else
+ bgp_rib_remove(rn, ri, peer, afi, safi);
+ }
+ return WQ_SUCCESS;
}
-static void
-bgp_clear_node_complete (struct work_queue *wq)
+static void bgp_clear_node_queue_del(struct work_queue *wq, void *data)
{
- struct peer *peer = wq->spec.data;
-
- /* Tickle FSM to start moving again */
- BGP_EVENT_ADD (peer, Clearing_Completed);
+ struct bgp_clear_node_queue *cnq = data;
+ struct bgp_node *rn = cnq->rn;
+ struct bgp_table *table = bgp_node_table(rn);
- peer_unlock (peer); /* bgp_clear_route */
+ bgp_unlock_node(rn);
+ bgp_table_unlock(table);
+ XFREE(MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
}
-static void
-bgp_clear_node_queue_init (struct peer *peer)
+static void bgp_clear_node_complete(struct work_queue *wq)
{
- char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
-
- snprintf (wname, sizeof(wname), "clear %s", peer->host);
-#undef CLEAR_QUEUE_NAME_LEN
+ struct peer *peer = wq->spec.data;
- if ( (peer->clear_node_queue = work_queue_new (bm->master, wname)) == NULL)
- {
- zlog_err ("%s: Failed to allocate work queue", __func__);
- exit (1);
- }
- peer->clear_node_queue->spec.hold = 10;
- peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
- peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
- peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
- peer->clear_node_queue->spec.max_retries = 0;
-
- /* we only 'lock' this peer reference when the queue is actually active */
- peer->clear_node_queue->spec.data = peer;
+ /* Tickle FSM to start moving again */
+ BGP_EVENT_ADD(peer, Clearing_Completed);
+
+ peer_unlock(peer); /* bgp_clear_route */
}
-static void
-bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
- struct bgp_table *table)
+static void bgp_clear_node_queue_init(struct peer *peer)
{
- struct bgp_node *rn;
- int force = bm->process_main_queue ? 0 : 1;
-
- if (! table)
- table = peer->bgp->rib[afi][safi];
-
- /* If still no table => afi/safi isn't configured at all or smth. */
- if (! table)
- return;
-
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- {
- struct bgp_info *ri, *next;
- struct bgp_adj_in *ain;
- struct bgp_adj_in *ain_next;
-
- /* XXX:TODO: This is suboptimal, every non-empty route_node is
- * queued for every clearing peer, regardless of whether it is
- * relevant to the peer at hand.
- *
- * Overview: There are 3 different indices which need to be
- * scrubbed, potentially, when a peer is removed:
- *
- * 1 peer's routes visible via the RIB (ie accepted routes)
- * 2 peer's routes visible by the (optional) peer's adj-in index
- * 3 other routes visible by the peer's adj-out index
- *
- * 3 there is no hurry in scrubbing, once the struct peer is
- * removed from bgp->peer, we could just GC such deleted peer's
- * adj-outs at our leisure.
- *
- * 1 and 2 must be 'scrubbed' in some way, at least made
- * invisible via RIB index before peer session is allowed to be
- * brought back up. So one needs to know when such a 'search' is
- * complete.
- *
- * Ideally:
- *
- * - there'd be a single global queue or a single RIB walker
- * - rather than tracking which route_nodes still need to be
- * examined on a peer basis, we'd track which peers still
- * aren't cleared
- *
- * Given that our per-peer prefix-counts now should be reliable,
- * this may actually be achievable. It doesn't seem to be a huge
- * problem at this time,
- *
- * It is possible that we have multiple paths for a prefix from a peer
- * if that peer is using AddPath.
- */
- ain = rn->adj_in;
- while (ain)
- {
- ain_next = ain->next;
-
- if (ain->peer == peer)
- {
- bgp_adj_in_remove (rn, ain);
- bgp_unlock_node (rn);
- }
-
- ain = ain_next;
- }
-
- for (ri = rn->info; ri; ri = next)
- {
- next = ri->next;
- if (ri->peer != peer)
- continue;
-
- if (force)
- bgp_info_reap (rn, ri);
- else
- {
- struct bgp_clear_node_queue *cnq;
-
- /* both unlocked in bgp_clear_node_queue_del */
- bgp_table_lock (bgp_node_table (rn));
- bgp_lock_node (rn);
- cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE,
- sizeof (struct bgp_clear_node_queue));
- cnq->rn = rn;
- work_queue_add (peer->clear_node_queue, cnq);
- break;
- }
+ char wname[sizeof("clear xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx")];
+
+ snprintf(wname, sizeof(wname), "clear %s", peer->host);
+#undef CLEAR_QUEUE_NAME_LEN
+
+ if ((peer->clear_node_queue = work_queue_new(bm->master, wname))
+ == NULL) {
+ zlog_err("%s: Failed to allocate work queue", __func__);
+ exit(1);
}
- }
- return;
+ peer->clear_node_queue->spec.hold = 10;
+ peer->clear_node_queue->spec.workfunc = &bgp_clear_route_node;
+ peer->clear_node_queue->spec.del_item_data = &bgp_clear_node_queue_del;
+ peer->clear_node_queue->spec.completion_func = &bgp_clear_node_complete;
+ peer->clear_node_queue->spec.max_retries = 0;
+
+ /* we only 'lock' this peer reference when the queue is actually active
+ */
+ peer->clear_node_queue->spec.data = peer;
}
-void
-bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi)
+static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
+ struct bgp_table *table)
{
- struct bgp_node *rn;
- struct bgp_table *table;
+ struct bgp_node *rn;
+ int force = bm->process_main_queue ? 0 : 1;
- if (peer->clear_node_queue == NULL)
- bgp_clear_node_queue_init (peer);
-
- /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
- * Idle until it receives a Clearing_Completed event. This protects
- * against peers which flap faster than we can we clear, which could
- * lead to:
- *
- * a) race with routes from the new session being installed before
- * clear_route_node visits the node (to delete the route of that
- * peer)
- * b) resource exhaustion, clear_route_node likely leads to an entry
- * on the process_main queue. Fast-flapping could cause that queue
- * to grow and grow.
- */
-
- /* lock peer in assumption that clear-node-queue will get nodes; if so,
- * the unlock will happen upon work-queue completion; other wise, the
- * unlock happens at the end of this function.
- */
- if (!peer->clear_node_queue->thread)
- peer_lock (peer);
-
- if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
- bgp_clear_route_table (peer, afi, safi, NULL);
- else
- for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn;
- rn = bgp_route_next (rn))
- if ((table = rn->info) != NULL)
- bgp_clear_route_table (peer, afi, safi, table);
+ if (!table)
+ table = peer->bgp->rib[afi][safi];
+
+ /* If still no table => afi/safi isn't configured at all or smth. */
+ if (!table)
+ return;
- /* unlock if no nodes got added to the clear-node-queue. */
- if (!peer->clear_node_queue->thread)
- peer_unlock (peer);
+ for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
+ struct bgp_info *ri, *next;
+ struct bgp_adj_in *ain;
+ struct bgp_adj_in *ain_next;
+
+ /* XXX:TODO: This is suboptimal, every non-empty route_node is
+ * queued for every clearing peer, regardless of whether it is
+ * relevant to the peer at hand.
+ *
+ * Overview: There are 3 different indices which need to be
+ * scrubbed, potentially, when a peer is removed:
+ *
+ * 1 peer's routes visible via the RIB (ie accepted routes)
+ * 2 peer's routes visible by the (optional) peer's adj-in index
+ * 3 other routes visible by the peer's adj-out index
+ *
+ * 3 there is no hurry in scrubbing, once the struct peer is
+ * removed from bgp->peer, we could just GC such deleted peer's
+ * adj-outs at our leisure.
+ *
+ * 1 and 2 must be 'scrubbed' in some way, at least made
+ * invisible via RIB index before peer session is allowed to be
+ * brought back up. So one needs to know when such a 'search' is
+ * complete.
+ *
+ * Ideally:
+ *
+ * - there'd be a single global queue or a single RIB walker
+ * - rather than tracking which route_nodes still need to be
+ * examined on a peer basis, we'd track which peers still
+ * aren't cleared
+ *
+ * Given that our per-peer prefix-counts now should be reliable,
+ * this may actually be achievable. It doesn't seem to be a huge
+ * problem at this time,
+ *
+ * It is possible that we have multiple paths for a prefix from
+ * a peer
+ * if that peer is using AddPath.
+ */
+ ain = rn->adj_in;
+ while (ain) {
+ ain_next = ain->next;
+
+ if (ain->peer == peer) {
+ bgp_adj_in_remove(rn, ain);
+ bgp_unlock_node(rn);
+ }
+
+ ain = ain_next;
+ }
+ for (ri = rn->info; ri; ri = next) {
+ next = ri->next;
+ if (ri->peer != peer)
+ continue;
+
+ if (force)
+ bgp_info_reap(rn, ri);
+ else {
+ struct bgp_clear_node_queue *cnq;
+
+ /* both unlocked in bgp_clear_node_queue_del */
+ bgp_table_lock(bgp_node_table(rn));
+ bgp_lock_node(rn);
+ cnq = XCALLOC(
+ MTYPE_BGP_CLEAR_NODE_QUEUE,
+ sizeof(struct bgp_clear_node_queue));
+ cnq->rn = rn;
+ work_queue_add(peer->clear_node_queue, cnq);
+ break;
+ }
+ }
+ }
+ return;
+}
+
+void bgp_clear_route(struct peer *peer, afi_t afi, safi_t safi)
+{
+ struct bgp_node *rn;
+ struct bgp_table *table;
+
+ if (peer->clear_node_queue == NULL)
+ bgp_clear_node_queue_init(peer);
+
+ /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to
+ * Idle until it receives a Clearing_Completed event. This protects
+ * against peers which flap faster than we can we clear, which could
+ * lead to:
+ *
+ * a) race with routes from the new session being installed before
+ * clear_route_node visits the node (to delete the route of that
+ * peer)
+ * b) resource exhaustion, clear_route_node likely leads to an entry
+ * on the process_main queue. Fast-flapping could cause that queue
+ * to grow and grow.
+ */
+
+ /* lock peer in assumption that clear-node-queue will get nodes; if so,
+ * the unlock will happen upon work-queue completion; other wise, the
+ * unlock happens at the end of this function.
+ */
+ if (!peer->clear_node_queue->thread)
+ peer_lock(peer);
+
+ if (safi != SAFI_MPLS_VPN && safi != SAFI_ENCAP && safi != SAFI_EVPN)
+ bgp_clear_route_table(peer, afi, safi, NULL);
+ else
+ for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
+ rn = bgp_route_next(rn))
+ if ((table = rn->info) != NULL)
+ bgp_clear_route_table(peer, afi, safi, table);
+
+ /* unlock if no nodes got added to the clear-node-queue. */
+ if (!peer->clear_node_queue->thread)
+ peer_unlock(peer);
}
-
-void
-bgp_clear_route_all (struct peer *peer)
+
+void bgp_clear_route_all(struct peer *peer)
{
- afi_t afi;
- safi_t safi;
+ afi_t afi;
+ safi_t safi;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- bgp_clear_route (peer, afi, safi);
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ bgp_clear_route(peer, afi, safi);
#if ENABLE_BGP_VNC
- rfapiProcessPeerDown(peer);
+ rfapiProcessPeerDown(peer);
#endif
}
-void
-bgp_clear_adj_in (struct peer *peer, afi_t afi, safi_t safi)
+void bgp_clear_adj_in(struct peer *peer, afi_t afi, safi_t safi)
{
- struct bgp_table *table;
- struct bgp_node *rn;
- struct bgp_adj_in *ain;
- struct bgp_adj_in *ain_next;
+ struct bgp_table *table;
+ struct bgp_node *rn;
+ struct bgp_adj_in *ain;
+ struct bgp_adj_in *ain_next;
- table = peer->bgp->rib[afi][safi];
+ table = peer->bgp->rib[afi][safi];
- /* It is possible that we have multiple paths for a prefix from a peer
- * if that peer is using AddPath.
- */
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- {
- ain = rn->adj_in;
+ /* It is possible that we have multiple paths for a prefix from a peer
+ * if that peer is using AddPath.
+ */
+ for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
+ ain = rn->adj_in;
- while (ain)
- {
- ain_next = ain->next;
+ while (ain) {
+ ain_next = ain->next;
- if (ain->peer == peer)
- {
- bgp_adj_in_remove (rn, ain);
- bgp_unlock_node (rn);
- }
+ if (ain->peer == peer) {
+ bgp_adj_in_remove(rn, ain);
+ bgp_unlock_node(rn);
+ }
- ain = ain_next;
- }
- }
+ ain = ain_next;
+ }
+ }
}
-void
-bgp_clear_stale_route (struct peer *peer, afi_t afi, safi_t safi)
-{
- struct bgp_node *rn;
- struct bgp_info *ri;
- struct bgp_table *table;
-
- if ( safi == SAFI_MPLS_VPN)
- {
- for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; rn = bgp_route_next (rn))
- {
- struct bgp_node *rm;
- struct bgp_info *ri;
-
- /* look for neighbor in tables */
- if ((table = rn->info) != NULL)
- {
- for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
- for (ri = rm->info; ri; ri = ri->next)
- if (ri->peer == peer)
- {
- if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
- bgp_rib_remove (rm, ri, peer, afi, safi);
- break;
- }
- }
- }
- }
- else
- {
- for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; rn = bgp_route_next (rn))
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer)
- {
- if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
- bgp_rib_remove (rn, ri, peer, afi, safi);
- break;
- }
- }
+void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
+{
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+ struct bgp_table *table;
+
+ if (safi == SAFI_MPLS_VPN) {
+ for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
+ rn = bgp_route_next(rn)) {
+ struct bgp_node *rm;
+ struct bgp_info *ri;
+
+ /* look for neighbor in tables */
+ if ((table = rn->info) != NULL) {
+ for (rm = bgp_table_top(table); rm;
+ rm = bgp_route_next(rm))
+ for (ri = rm->info; ri; ri = ri->next)
+ if (ri->peer == peer) {
+ if (CHECK_FLAG(
+ ri->flags,
+ BGP_INFO_STALE))
+ bgp_rib_remove(
+ rm, ri,
+ peer,
+ afi,
+ safi);
+ break;
+ }
+ }
+ }
+ } else {
+ for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
+ rn = bgp_route_next(rn))
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == peer) {
+ if (CHECK_FLAG(ri->flags,
+ BGP_INFO_STALE))
+ bgp_rib_remove(rn, ri, peer,
+ afi, safi);
+ break;
+ }
+ }
}
-static void
-bgp_cleanup_table(struct bgp_table *table, safi_t safi)
+static void bgp_cleanup_table(struct bgp_table *table, safi_t safi)
{
- struct bgp_node *rn;
- struct bgp_info *ri;
- struct bgp_info *next;
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+ struct bgp_info *next;
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- for (ri = rn->info; ri; ri = next)
- {
- next = ri->next;
- if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
- && ri->type == ZEBRA_ROUTE_BGP
- && (ri->sub_type == BGP_ROUTE_NORMAL ||
- ri->sub_type == BGP_ROUTE_AGGREGATE))
- {
+ for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
+ for (ri = rn->info; ri; ri = next) {
+ next = ri->next;
+ if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)
+ && ri->type == ZEBRA_ROUTE_BGP
+ && (ri->sub_type == BGP_ROUTE_NORMAL
+ || ri->sub_type == BGP_ROUTE_AGGREGATE)) {
#if ENABLE_BGP_VNC
- if (table->owner && table->owner->bgp)
- vnc_import_bgp_del_route(table->owner->bgp, &rn->p, ri);
+ if (table->owner && table->owner->bgp)
+ vnc_import_bgp_del_route(
+ table->owner->bgp, &rn->p, ri);
#endif
- bgp_zebra_withdraw (&rn->p, ri, safi);
- bgp_info_reap (rn, ri);
- }
- }
+ bgp_zebra_withdraw(&rn->p, ri, safi);
+ bgp_info_reap(rn, ri);
+ }
+ }
}
/* Delete all kernel routes. */
-void
-bgp_cleanup_routes (struct bgp *bgp)
-{
- afi_t afi;
- struct bgp_node *rn;
-
- for (afi = AFI_IP; afi < AFI_MAX; ++afi)
- {
- if (afi == AFI_L2VPN)
- continue;
- bgp_cleanup_table(bgp->rib[afi][SAFI_UNICAST], SAFI_UNICAST);
- /*
- * VPN and ENCAP and EVPN tables are two-level (RD is top level)
- */
- if (afi != AFI_L2VPN)
- {
- safi_t safi;
- safi = SAFI_MPLS_VPN;
- for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
- rn = bgp_route_next (rn))
- {
- if (rn->info)
- {
- bgp_cleanup_table((struct bgp_table *)(rn->info), safi);
- bgp_table_finish ((struct bgp_table **)&(rn->info));
- rn->info = NULL;
- bgp_unlock_node(rn);
- }
- }
- safi = SAFI_ENCAP;
- for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
- rn = bgp_route_next (rn))
- {
- if (rn->info)
- {
- bgp_cleanup_table((struct bgp_table *)(rn->info), safi);
- bgp_table_finish ((struct bgp_table **)&(rn->info));
- rn->info = NULL;
- bgp_unlock_node(rn);
- }
- }
+void bgp_cleanup_routes(struct bgp *bgp)
+{
+ afi_t afi;
+ struct bgp_node *rn;
+
+ for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
+ if (afi == AFI_L2VPN)
+ continue;
+ bgp_cleanup_table(bgp->rib[afi][SAFI_UNICAST], SAFI_UNICAST);
+ /*
+ * VPN and ENCAP and EVPN tables are two-level (RD is top level)
+ */
+ if (afi != AFI_L2VPN) {
+ safi_t safi;
+ safi = SAFI_MPLS_VPN;
+ for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
+ rn = bgp_route_next(rn)) {
+ if (rn->info) {
+ bgp_cleanup_table(
+ (struct bgp_table *)(rn->info),
+ safi);
+ bgp_table_finish((struct bgp_table **)&(
+ rn->info));
+ rn->info = NULL;
+ bgp_unlock_node(rn);
+ }
+ }
+ safi = SAFI_ENCAP;
+ for (rn = bgp_table_top(bgp->rib[afi][safi]); rn;
+ rn = bgp_route_next(rn)) {
+ if (rn->info) {
+ bgp_cleanup_table(
+ (struct bgp_table *)(rn->info),
+ safi);
+ bgp_table_finish((struct bgp_table **)&(
+ rn->info));
+ rn->info = NULL;
+ bgp_unlock_node(rn);
+ }
+ }
+ }
+ }
+ for (rn = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); rn;
+ rn = bgp_route_next(rn)) {
+ if (rn->info) {
+ bgp_cleanup_table((struct bgp_table *)(rn->info),
+ SAFI_EVPN);
+ bgp_table_finish((struct bgp_table **)&(rn->info));
+ rn->info = NULL;
+ bgp_unlock_node(rn);
+ }
}
- }
- for (rn = bgp_table_top(bgp->rib[AFI_L2VPN][SAFI_EVPN]); rn;
- rn = bgp_route_next (rn))
- {
- if (rn->info)
- {
- bgp_cleanup_table((struct bgp_table *)(rn->info), SAFI_EVPN);
- bgp_table_finish ((struct bgp_table **)&(rn->info));
- rn->info = NULL;
- bgp_unlock_node(rn);
- }
- }
}
-void
-bgp_reset (void)
+void bgp_reset(void)
{
- vty_reset ();
- bgp_zclient_reset ();
- access_list_reset ();
- prefix_list_reset ();
+ vty_reset();
+ bgp_zclient_reset();
+ access_list_reset();
+ prefix_list_reset();
}
-static int
-bgp_addpath_encode_rx (struct peer *peer, afi_t afi, safi_t safi)
+static int bgp_addpath_encode_rx(struct peer *peer, afi_t afi, safi_t safi)
{
- return (CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV) &&
- CHECK_FLAG (peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_TX_RCV));
+ return (CHECK_FLAG(peer->af_cap[afi][safi], PEER_CAP_ADDPATH_AF_RX_ADV)
+ && CHECK_FLAG(peer->af_cap[afi][safi],
+ PEER_CAP_ADDPATH_AF_TX_RCV));
}
/* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
value. */
-int
-bgp_nlri_parse_ip (struct peer *peer, struct attr *attr,
- struct bgp_nlri *packet)
-{
- u_char *pnt;
- u_char *lim;
- struct prefix p;
- int psize;
- int ret;
- afi_t afi;
- safi_t safi;
- int addpath_encoded;
- u_int32_t addpath_id;
-
- /* Check peer status. */
- if (peer->status != Established)
- return 0;
-
- pnt = packet->nlri;
- lim = pnt + packet->length;
- afi = packet->afi;
- safi = packet->safi;
- addpath_id = 0;
- addpath_encoded = bgp_addpath_encode_rx (peer, afi, safi);
-
- /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
- syntactic validity. If the field is syntactically incorrect,
- then the Error Subcode is set to Invalid Network Field. */
- for (; pnt < lim; pnt += psize)
- {
- /* Clear prefix structure. */
- memset (&p, 0, sizeof (struct prefix));
-
- if (addpath_encoded)
- {
-
- /* When packet overflow occurs return immediately. */
- if (pnt + BGP_ADDPATH_ID_LEN > lim)
- return -1;
-
- addpath_id = ntohl(*((uint32_t*) pnt));
- pnt += BGP_ADDPATH_ID_LEN;
- }
-
- /* Fetch prefix length. */
- p.prefixlen = *pnt++;
- /* afi/safi validity already verified by caller, bgp_update_receive */
- p.family = afi2family (afi);
-
- /* Prefix length check. */
- if (p.prefixlen > prefix_blen (&p) * 8)
- {
- zlog_err("%s [Error] Update packet error (wrong perfix length %d for afi %u)",
- peer->host, p.prefixlen, packet->afi);
- return -1;
- }
-
- /* Packet size overflow check. */
- psize = PSIZE (p.prefixlen);
-
- /* When packet overflow occur return immediately. */
- if (pnt + psize > lim)
- {
- zlog_err("%s [Error] Update packet error (prefix length %d overflows packet)",
- peer->host, p.prefixlen);
- return -1;
- }
-
- /* Defensive coding, double-check the psize fits in a struct prefix */
- if (psize > (ssize_t) sizeof(p.u))
- {
- zlog_err("%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
- peer->host, p.prefixlen, sizeof(p.u));
- return -1;
- }
-
- /* Fetch prefix from NLRI packet. */
- memcpy (&p.u.prefix, pnt, psize);
-
- /* Check address. */
- if (afi == AFI_IP && safi == SAFI_UNICAST)
- {
- if (IN_CLASSD (ntohl (p.u.prefix4.s_addr)))
- {
- /* From RFC4271 Section 6.3:
- *
- * If a prefix in the NLRI field is semantically incorrect
- * (e.g., an unexpected multicast IP address), an error SHOULD
- * be logged locally, and the prefix SHOULD be ignored.
- */
- zlog_err ("%s: IPv4 unicast NLRI is multicast address %s, ignoring",
- peer->host, inet_ntoa (p.u.prefix4));
- continue;
- }
- }
-
- /* Check address. */
- if (afi == AFI_IP6 && safi == SAFI_UNICAST)
- {
- if (IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
- {
- char buf[BUFSIZ];
-
- zlog_err ("%s: IPv6 unicast NLRI is link-local address %s, ignoring",
- peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
-
- continue;
- }
- if (IN6_IS_ADDR_MULTICAST (&p.u.prefix6))
- {
- char buf[BUFSIZ];
-
- zlog_err ("%s: IPv6 unicast NLRI is multicast address %s, ignoring",
- peer->host, inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
-
- continue;
- }
- }
-
- /* Normal process. */
- if (attr)
- ret = bgp_update (peer, &p, addpath_id, attr, afi, safi,
- ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0, NULL);
- else
- ret = bgp_withdraw (peer, &p, addpath_id, attr, afi, safi,
- ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, NULL);
-
- /* Address family configuration mismatch or maximum-prefix count
- overflow. */
- if (ret < 0)
- return -1;
- }
+int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
+ struct bgp_nlri *packet)
+{
+ u_char *pnt;
+ u_char *lim;
+ struct prefix p;
+ int psize;
+ int ret;
+ afi_t afi;
+ safi_t safi;
+ int addpath_encoded;
+ u_int32_t addpath_id;
+
+ /* Check peer status. */
+ if (peer->status != Established)
+ return 0;
+
+ pnt = packet->nlri;
+ lim = pnt + packet->length;
+ afi = packet->afi;
+ safi = packet->safi;
+ addpath_id = 0;
+ addpath_encoded = bgp_addpath_encode_rx(peer, afi, safi);
+
+ /* RFC4771 6.3 The NLRI field in the UPDATE message is checked for
+ syntactic validity. If the field is syntactically incorrect,
+ then the Error Subcode is set to Invalid Network Field. */
+ for (; pnt < lim; pnt += psize) {
+ /* Clear prefix structure. */
+ memset(&p, 0, sizeof(struct prefix));
+
+ if (addpath_encoded) {
+
+ /* When packet overflow occurs return immediately. */
+ if (pnt + BGP_ADDPATH_ID_LEN > lim)
+ return -1;
+
+ addpath_id = ntohl(*((uint32_t *)pnt));
+ pnt += BGP_ADDPATH_ID_LEN;
+ }
- /* Packet length consistency check. */
- if (pnt != lim)
- {
- zlog_err ("%s [Error] Update packet error (prefix length mismatch with total length)",
- peer->host);
- return -1;
- }
+ /* Fetch prefix length. */
+ p.prefixlen = *pnt++;
+ /* afi/safi validity already verified by caller,
+ * bgp_update_receive */
+ p.family = afi2family(afi);
+
+ /* Prefix length check. */
+ if (p.prefixlen > prefix_blen(&p) * 8) {
+ zlog_err(
+ "%s [Error] Update packet error (wrong perfix length %d for afi %u)",
+ peer->host, p.prefixlen, packet->afi);
+ return -1;
+ }
- return 0;
-}
+ /* Packet size overflow check. */
+ psize = PSIZE(p.prefixlen);
-static struct bgp_static *
-bgp_static_new (void)
-{
- return XCALLOC (MTYPE_BGP_STATIC, sizeof (struct bgp_static));
+ /* When packet overflow occur return immediately. */
+ if (pnt + psize > lim) {
+ zlog_err(
+ "%s [Error] Update packet error (prefix length %d overflows packet)",
+ peer->host, p.prefixlen);
+ return -1;
+ }
+
+ /* Defensive coding, double-check the psize fits in a struct
+ * prefix */
+ if (psize > (ssize_t)sizeof(p.u)) {
+ zlog_err(
+ "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
+ peer->host, p.prefixlen, sizeof(p.u));
+ return -1;
+ }
+
+ /* Fetch prefix from NLRI packet. */
+ memcpy(&p.u.prefix, pnt, psize);
+
+ /* Check address. */
+ if (afi == AFI_IP && safi == SAFI_UNICAST) {
+ if (IN_CLASSD(ntohl(p.u.prefix4.s_addr))) {
+ /* From RFC4271 Section 6.3:
+ *
+ * If a prefix in the NLRI field is semantically
+ * incorrect
+ * (e.g., an unexpected multicast IP address),
+ * an error SHOULD
+ * be logged locally, and the prefix SHOULD be
+ * ignored.
+ */
+ zlog_err(
+ "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
+ peer->host, inet_ntoa(p.u.prefix4));
+ continue;
+ }
+ }
+
+ /* Check address. */
+ if (afi == AFI_IP6 && safi == SAFI_UNICAST) {
+ if (IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
+ char buf[BUFSIZ];
+
+ zlog_err(
+ "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
+ peer->host,
+ inet_ntop(AF_INET6, &p.u.prefix6, buf,
+ BUFSIZ));
+
+ continue;
+ }
+ if (IN6_IS_ADDR_MULTICAST(&p.u.prefix6)) {
+ char buf[BUFSIZ];
+
+ zlog_err(
+ "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
+ peer->host,
+ inet_ntop(AF_INET6, &p.u.prefix6, buf,
+ BUFSIZ));
+
+ continue;
+ }
+ }
+
+ /* Normal process. */
+ if (attr)
+ ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
+ NULL, NULL, 0, NULL);
+ else
+ ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
+ safi, ZEBRA_ROUTE_BGP,
+ BGP_ROUTE_NORMAL, NULL, NULL, NULL);
+
+ /* Address family configuration mismatch or maximum-prefix count
+ overflow. */
+ if (ret < 0)
+ return -1;
+ }
+
+ /* Packet length consistency check. */
+ if (pnt != lim) {
+ zlog_err(
+ "%s [Error] Update packet error (prefix length mismatch with total length)",
+ peer->host);
+ return -1;
+ }
+
+ return 0;
}
-static void
-bgp_static_free (struct bgp_static *bgp_static)
+static struct bgp_static *bgp_static_new(void)
{
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
- if(bgp_static->eth_s_id)
- XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
- XFREE (MTYPE_BGP_STATIC, bgp_static);
+ return XCALLOC(MTYPE_BGP_STATIC, sizeof(struct bgp_static));
}
-static void
-bgp_static_update_main (struct bgp *bgp, struct prefix *p,
- struct bgp_static *bgp_static, afi_t afi, safi_t safi)
+static void bgp_static_free(struct bgp_static *bgp_static)
{
- struct bgp_node *rn;
- struct bgp_info *ri;
- struct bgp_info *new;
- struct bgp_info info;
- struct attr attr;
- struct attr *attr_new;
- int ret;
+ if (bgp_static->rmap.name)
+ XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
+ if (bgp_static->eth_s_id)
+ XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
+ XFREE(MTYPE_BGP_STATIC, bgp_static);
+}
+
+static void bgp_static_update_main(struct bgp *bgp, struct prefix *p,
+ struct bgp_static *bgp_static, afi_t afi,
+ safi_t safi)
+{
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+ struct bgp_info *new;
+ struct bgp_info info;
+ struct attr attr;
+ struct attr *attr_new;
+ int ret;
#if ENABLE_BGP_VNC
- int vnc_implicit_withdraw = 0;
+ int vnc_implicit_withdraw = 0;
#endif
- assert (bgp_static);
- if (!bgp_static)
- return;
+ assert(bgp_static);
+ if (!bgp_static)
+ return;
- rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, NULL);
+ rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
- bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
-
- attr.nexthop = bgp_static->igpnexthop;
- attr.med = bgp_static->igpmetric;
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
+ bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
- if (bgp_static->atomic)
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
+ attr.nexthop = bgp_static->igpnexthop;
+ attr.med = bgp_static->igpmetric;
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
- /* Apply route-map. */
- if (bgp_static->rmap.name)
- {
- struct attr attr_tmp = attr;
- info.peer = bgp->peer_self;
- info.attr = &attr_tmp;
+ if (bgp_static->atomic)
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE);
- SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
+ /* Apply route-map. */
+ if (bgp_static->rmap.name) {
+ struct attr attr_tmp = attr;
+ info.peer = bgp->peer_self;
+ info.attr = &attr_tmp;
- ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
+ SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
- bgp->peer_self->rmap_type = 0;
+ ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP, &info);
- if (ret == RMAP_DENYMATCH)
- {
- /* Free uninterned attribute. */
- bgp_attr_flush (&attr_tmp);
+ bgp->peer_self->rmap_type = 0;
- /* Unintern original. */
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
- bgp_static_withdraw (bgp, p, afi, safi);
- return;
- }
- attr_new = bgp_attr_intern (&attr_tmp);
- }
- else
- attr_new = bgp_attr_intern (&attr);
+ if (ret == RMAP_DENYMATCH) {
+ /* Free uninterned attribute. */
+ bgp_attr_flush(&attr_tmp);
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
- && ri->sub_type == BGP_ROUTE_STATIC)
- break;
+ /* Unintern original. */
+ aspath_unintern(&attr.aspath);
+ bgp_attr_extra_free(&attr);
+ bgp_static_withdraw(bgp, p, afi, safi);
+ return;
+ }
+ attr_new = bgp_attr_intern(&attr_tmp);
+ } else
+ attr_new = bgp_attr_intern(&attr);
- if (ri)
- {
- if (attrhash_cmp (ri->attr, attr_new) &&
- !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED) &&
- !bgp_flag_check(bgp, BGP_FLAG_FORCE_STATIC_PROCESS))
- {
- bgp_unlock_node (rn);
- bgp_attr_unintern (&attr_new);
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
- return;
- }
- else
- {
- /* The attribute is changed. */
- 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);
- else
- bgp_aggregate_decrement (bgp, p, ri, afi, safi);
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
+ && ri->sub_type == BGP_ROUTE_STATIC)
+ break;
+
+ if (ri) {
+ if (attrhash_cmp(ri->attr, attr_new)
+ && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)
+ && !bgp_flag_check(bgp, BGP_FLAG_FORCE_STATIC_PROCESS)) {
+ bgp_unlock_node(rn);
+ bgp_attr_unintern(&attr_new);
+ aspath_unintern(&attr.aspath);
+ bgp_attr_extra_free(&attr);
+ return;
+ } else {
+ /* The attribute is changed. */
+ 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);
+ else
+ bgp_aggregate_decrement(bgp, p, ri, afi, safi);
#if ENABLE_BGP_VNC
- if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST))
- {
- if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
- {
- /*
- * Implicit withdraw case.
- * We have to do this before ri is changed
- */
- ++vnc_implicit_withdraw;
- vnc_import_bgp_del_route(bgp, p, ri);
- vnc_import_bgp_exterior_del_route(bgp, p, ri);
- }
- }
+ if ((afi == AFI_IP || afi == AFI_IP6)
+ && (safi == SAFI_UNICAST)) {
+ if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
+ /*
+ * Implicit withdraw case.
+ * We have to do this before ri is
+ * changed
+ */
+ ++vnc_implicit_withdraw;
+ vnc_import_bgp_del_route(bgp, p, ri);
+ vnc_import_bgp_exterior_del_route(
+ bgp, p, ri);
+ }
+ }
#endif
- bgp_attr_unintern (&ri->attr);
- ri->attr = attr_new;
- ri->uptime = bgp_clock ();
+ bgp_attr_unintern(&ri->attr);
+ ri->attr = attr_new;
+ ri->uptime = bgp_clock();
#if ENABLE_BGP_VNC
- if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST))
- {
- if (vnc_implicit_withdraw)
- {
- vnc_import_bgp_add_route(bgp, p, ri);
- vnc_import_bgp_exterior_add_route(bgp, p, ri);
- }
- }
+ if ((afi == AFI_IP || afi == AFI_IP6)
+ && (safi == SAFI_UNICAST)) {
+ if (vnc_implicit_withdraw) {
+ vnc_import_bgp_add_route(bgp, p, ri);
+ vnc_import_bgp_exterior_add_route(
+ bgp, p, ri);
+ }
+ }
#endif
- /* Nexthop reachability check. */
- if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
- {
- if (bgp_find_or_add_nexthop (bgp, afi, ri, NULL, 0))
- bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
- else
- {
- if (BGP_DEBUG(nht, NHT))
- {
- char buf1[INET6_ADDRSTRLEN];
- inet_ntop(p->family, &p->u.prefix, buf1,
- INET6_ADDRSTRLEN);
- zlog_debug("%s(%s): Route not in table, not advertising",
- __FUNCTION__, buf1);
- }
- bgp_info_unset_flag (rn, ri, BGP_INFO_VALID);
- }
- }
- else
- {
- /* Delete the NHT structure if any, if we're toggling between
- * enabling/disabling import check. We deregister the route
- * from NHT to avoid overloading NHT and the process interaction
- */
- bgp_unlink_nexthop(ri);
- bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
- }
- /* Process change. */
- bgp_aggregate_increment (bgp, p, ri, afi, safi);
- bgp_process (bgp, rn, afi, safi);
- bgp_unlock_node (rn);
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
- return;
+ /* Nexthop reachability check. */
+ if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) {
+ if (bgp_find_or_add_nexthop(bgp, afi, ri, NULL,
+ 0))
+ bgp_info_set_flag(rn, ri,
+ BGP_INFO_VALID);
+ else {
+ if (BGP_DEBUG(nht, NHT)) {
+ char buf1[INET6_ADDRSTRLEN];
+ inet_ntop(p->family,
+ &p->u.prefix, buf1,
+ INET6_ADDRSTRLEN);
+ zlog_debug(
+ "%s(%s): Route not in table, not advertising",
+ __FUNCTION__, buf1);
+ }
+ bgp_info_unset_flag(rn, ri,
+ BGP_INFO_VALID);
+ }
+ } else {
+ /* Delete the NHT structure if any, if we're
+ * toggling between
+ * enabling/disabling import check. We
+ * deregister the route
+ * from NHT to avoid overloading NHT and the
+ * process interaction
+ */
+ bgp_unlink_nexthop(ri);
+ bgp_info_set_flag(rn, ri, BGP_INFO_VALID);
+ }
+ /* Process change. */
+ bgp_aggregate_increment(bgp, p, ri, afi, safi);
+ bgp_process(bgp, rn, afi, safi);
+ bgp_unlock_node(rn);
+ aspath_unintern(&attr.aspath);
+ bgp_attr_extra_free(&attr);
+ return;
+ }
}
- }
- /* Make new BGP info. */
- new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self, attr_new,
- rn);
- /* Nexthop reachability check. */
- if (bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK))
- {
- if (bgp_find_or_add_nexthop (bgp, afi, new, NULL, 0))
- bgp_info_set_flag (rn, new, BGP_INFO_VALID);
- else
- {
- if (BGP_DEBUG(nht, NHT))
- {
- char buf1[INET6_ADDRSTRLEN];
- inet_ntop(p->family, &p->u.prefix, buf1,
- INET6_ADDRSTRLEN);
- zlog_debug("%s(%s): Route not in table, not advertising",
- __FUNCTION__, buf1);
- }
- bgp_info_unset_flag (rn, new, BGP_INFO_VALID);
+ /* Make new BGP info. */
+ new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
+ attr_new, rn);
+ /* Nexthop reachability check. */
+ if (bgp_flag_check(bgp, BGP_FLAG_IMPORT_CHECK)) {
+ if (bgp_find_or_add_nexthop(bgp, afi, new, NULL, 0))
+ bgp_info_set_flag(rn, new, BGP_INFO_VALID);
+ else {
+ if (BGP_DEBUG(nht, NHT)) {
+ char buf1[INET6_ADDRSTRLEN];
+ inet_ntop(p->family, &p->u.prefix, buf1,
+ INET6_ADDRSTRLEN);
+ zlog_debug(
+ "%s(%s): Route not in table, not advertising",
+ __FUNCTION__, buf1);
+ }
+ bgp_info_unset_flag(rn, new, BGP_INFO_VALID);
+ }
+ } else {
+ /* Delete the NHT structure if any, if we're toggling between
+ * enabling/disabling import check. We deregister the route
+ * from NHT to avoid overloading NHT and the process interaction
+ */
+ bgp_unlink_nexthop(new);
+
+ bgp_info_set_flag(rn, new, BGP_INFO_VALID);
}
- }
- else
- {
- /* Delete the NHT structure if any, if we're toggling between
- * enabling/disabling import check. We deregister the route
- * from NHT to avoid overloading NHT and the process interaction
- */
- bgp_unlink_nexthop(new);
- bgp_info_set_flag (rn, new, BGP_INFO_VALID);
- }
+ /* Aggregate address increment. */
+ bgp_aggregate_increment(bgp, p, new, afi, safi);
- /* Aggregate address increment. */
- bgp_aggregate_increment (bgp, p, new, afi, safi);
-
- /* Register new BGP information. */
- bgp_info_add (rn, new);
-
- /* route_node_get lock */
- bgp_unlock_node (rn);
-
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
+ /* Register new BGP information. */
+ bgp_info_add(rn, new);
+
+ /* route_node_get lock */
+ bgp_unlock_node(rn);
- /* Unintern original. */
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
+ /* Process change. */
+ bgp_process(bgp, rn, afi, safi);
+
+ /* Unintern original. */
+ aspath_unintern(&attr.aspath);
+ bgp_attr_extra_free(&attr);
}
-void
-bgp_static_update (struct bgp *bgp, struct prefix *p,
- struct bgp_static *bgp_static, afi_t afi, safi_t safi)
+void bgp_static_update(struct bgp *bgp, struct prefix *p,
+ struct bgp_static *bgp_static, afi_t afi, safi_t safi)
{
- bgp_static_update_main (bgp, p, bgp_static, afi, safi);
+ bgp_static_update_main(bgp, p, bgp_static, afi, safi);
}
-void
-bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
- safi_t safi)
+void bgp_static_withdraw(struct bgp *bgp, struct prefix *p, afi_t afi,
+ safi_t safi)
{
- struct bgp_node *rn;
- struct bgp_info *ri;
-
- rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, NULL);
+ struct bgp_node *rn;
+ struct bgp_info *ri;
- /* Check selected route and self inserted route. */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self
- && ri->type == ZEBRA_ROUTE_BGP
- && ri->sub_type == BGP_ROUTE_STATIC)
- break;
+ rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, NULL);
- /* Withdraw static BGP route from routing table. */
- if (ri)
- {
- bgp_aggregate_decrement (bgp, p, ri, afi, safi);
- bgp_unlink_nexthop(ri);
- bgp_info_delete (rn, ri);
- bgp_process (bgp, rn, afi, safi);
- }
+ /* Check selected route and self inserted route. */
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
+ && ri->sub_type == BGP_ROUTE_STATIC)
+ break;
+
+ /* Withdraw static BGP route from routing table. */
+ if (ri) {
+ bgp_aggregate_decrement(bgp, p, ri, afi, safi);
+ bgp_unlink_nexthop(ri);
+ bgp_info_delete(rn, ri);
+ bgp_process(bgp, rn, afi, safi);
+ }
- /* Unlock bgp_node_lookup. */
- bgp_unlock_node (rn);
+ /* Unlock bgp_node_lookup. */
+ bgp_unlock_node(rn);
}
/*
* Used for SAFI_MPLS_VPN and SAFI_ENCAP
*/
-static void
-bgp_static_withdraw_safi (struct bgp *bgp, struct prefix *p, afi_t afi,
- safi_t safi, struct prefix_rd *prd, u_char *tag)
+static void bgp_static_withdraw_safi(struct bgp *bgp, struct prefix *p,
+ afi_t afi, safi_t safi,
+ struct prefix_rd *prd, u_char *tag)
{
- struct bgp_node *rn;
- struct bgp_info *ri;
+ struct bgp_node *rn;
+ struct bgp_info *ri;
- rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
+ rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
- /* Check selected route and self inserted route. */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self
- && ri->type == ZEBRA_ROUTE_BGP
- && ri->sub_type == BGP_ROUTE_STATIC)
- break;
+ /* Check selected route and self inserted route. */
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
+ && ri->sub_type == BGP_ROUTE_STATIC)
+ break;
- /* Withdraw static BGP route from routing table. */
- if (ri)
- {
+ /* Withdraw static BGP route from routing table. */
+ if (ri) {
#if ENABLE_BGP_VNC
- rfapiProcessWithdraw(
- ri->peer,
- NULL,
- p,
- prd,
- ri->attr,
- afi,
- safi,
- ri->type,
- 1); /* Kill, since it is an administrative change */
+ rfapiProcessWithdraw(
+ ri->peer, NULL, p, prd, ri->attr, afi, safi, ri->type,
+ 1); /* Kill, since it is an administrative change */
#endif
- bgp_aggregate_decrement (bgp, p, ri, afi, safi);
- bgp_info_delete (rn, ri);
- bgp_process (bgp, rn, afi, safi);
- }
+ bgp_aggregate_decrement(bgp, p, ri, afi, safi);
+ bgp_info_delete(rn, ri);
+ bgp_process(bgp, rn, afi, safi);
+ }
- /* Unlock bgp_node_lookup. */
- bgp_unlock_node (rn);
+ /* Unlock bgp_node_lookup. */
+ bgp_unlock_node(rn);
}
-static void
-bgp_static_update_safi (struct bgp *bgp, struct prefix *p,
- struct bgp_static *bgp_static, afi_t afi, safi_t safi)
+static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
+ struct bgp_static *bgp_static, afi_t afi,
+ safi_t safi)
{
- struct bgp_node *rn;
- struct bgp_info *new;
- struct attr *attr_new;
- struct attr attr = { 0 };
- struct bgp_info *ri;
+ struct bgp_node *rn;
+ struct bgp_info *new;
+ struct attr *attr_new;
+ struct attr attr = {0};
+ struct bgp_info *ri;
#if ENABLE_BGP_VNC
- u_int32_t label = 0;
+ u_int32_t label = 0;
#endif
- union gw_addr add;
+ union gw_addr add;
- assert (bgp_static);
+ assert(bgp_static);
- rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, &bgp_static->prd);
+ rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
+ &bgp_static->prd);
- bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
+ bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
- attr.nexthop = bgp_static->igpnexthop;
- attr.med = bgp_static->igpmetric;
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
-
- if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
- {
- if (afi == AFI_IP)
- {
- bgp_attr_extra_get (&attr)->mp_nexthop_global_in = bgp_static->igpnexthop;
- bgp_attr_extra_get (&attr)->mp_nexthop_len = IPV4_MAX_BYTELEN;
- }
- }
- if(afi == AFI_L2VPN)
- {
- if (bgp_static->gatewayIp.family == AF_INET)
- add.ipv4.s_addr = bgp_static->gatewayIp.u.prefix4.s_addr;
- else if (bgp_static->gatewayIp.family == AF_INET6)
- memcpy( &(add.ipv6), &(bgp_static->gatewayIp.u.prefix6), sizeof (struct in6_addr));
- overlay_index_update(&attr, bgp_static->eth_s_id, &add);
- if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN)
- {
- struct bgp_encap_type_vxlan bet;
- memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
- bet.vnid = p->u.prefix_evpn.eth_tag;
- bgp_encap_type_vxlan_to_tlv(&bet, &attr);
- }
- if (bgp_static->router_mac)
- {
- bgp_add_routermac_ecom (&attr, bgp_static->router_mac);
- }
- }
- /* Apply route-map. */
- if (bgp_static->rmap.name)
- {
- struct attr attr_tmp = attr;
- struct bgp_info info;
- int ret;
+ attr.nexthop = bgp_static->igpnexthop;
+ attr.med = bgp_static->igpmetric;
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
- info.peer = bgp->peer_self;
- info.attr = &attr_tmp;
+ if ((safi == SAFI_EVPN) || (safi == SAFI_MPLS_VPN)
+ || (safi == SAFI_ENCAP)) {
+ if (afi == AFI_IP) {
+ bgp_attr_extra_get(&attr)->mp_nexthop_global_in =
+ bgp_static->igpnexthop;
+ bgp_attr_extra_get(&attr)->mp_nexthop_len =
+ IPV4_MAX_BYTELEN;
+ }
+ }
+ if (afi == AFI_L2VPN) {
+ if (bgp_static->gatewayIp.family == AF_INET)
+ add.ipv4.s_addr =
+ bgp_static->gatewayIp.u.prefix4.s_addr;
+ else if (bgp_static->gatewayIp.family == AF_INET6)
+ memcpy(&(add.ipv6), &(bgp_static->gatewayIp.u.prefix6),
+ sizeof(struct in6_addr));
+ overlay_index_update(&attr, bgp_static->eth_s_id, &add);
+ if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
+ struct bgp_encap_type_vxlan bet;
+ memset(&bet, 0, sizeof(struct bgp_encap_type_vxlan));
+ bet.vnid = p->u.prefix_evpn.eth_tag;
+ bgp_encap_type_vxlan_to_tlv(&bet, &attr);
+ }
+ if (bgp_static->router_mac) {
+ bgp_add_routermac_ecom(&attr, bgp_static->router_mac);
+ }
+ }
+ /* Apply route-map. */
+ if (bgp_static->rmap.name) {
+ struct attr attr_tmp = attr;
+ struct bgp_info info;
+ int ret;
- SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
+ info.peer = bgp->peer_self;
+ info.attr = &attr_tmp;
- ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
+ SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
- bgp->peer_self->rmap_type = 0;
+ ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP, &info);
- if (ret == RMAP_DENYMATCH)
- {
- /* Free uninterned attribute. */
- bgp_attr_flush (&attr_tmp);
+ bgp->peer_self->rmap_type = 0;
- /* Unintern original. */
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
- bgp_static_withdraw_safi (bgp, p, afi, safi, &bgp_static->prd,
- bgp_static->tag);
- return;
- }
+ if (ret == RMAP_DENYMATCH) {
+ /* Free uninterned attribute. */
+ bgp_attr_flush(&attr_tmp);
- attr_new = bgp_attr_intern (&attr_tmp);
- }
- else
- {
- attr_new = bgp_attr_intern (&attr);
- }
+ /* Unintern original. */
+ aspath_unintern(&attr.aspath);
+ bgp_attr_extra_free(&attr);
+ bgp_static_withdraw_safi(bgp, p, afi, safi,
+ &bgp_static->prd,
+ bgp_static->tag);
+ return;
+ }
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
- && ri->sub_type == BGP_ROUTE_STATIC)
- break;
+ attr_new = bgp_attr_intern(&attr_tmp);
+ } else {
+ attr_new = bgp_attr_intern(&attr);
+ }
- if (ri)
- {
- union gw_addr add;
- memset(&add, 0, sizeof(union gw_addr));
- if (attrhash_cmp (ri->attr, attr_new) &&
- overlay_index_equal(afi, ri, bgp_static->eth_s_id, &add) &&
- !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
- {
- bgp_unlock_node (rn);
- bgp_attr_unintern (&attr_new);
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
- return;
- }
- else
- {
- /* The attribute is changed. */
- 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);
- else
- bgp_aggregate_decrement (bgp, p, ri, afi, safi);
- bgp_attr_unintern (&ri->attr);
- ri->attr = attr_new;
- ri->uptime = bgp_clock ();
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
+ && ri->sub_type == BGP_ROUTE_STATIC)
+ break;
+
+ if (ri) {
+ union gw_addr add;
+ memset(&add, 0, sizeof(union gw_addr));
+ if (attrhash_cmp(ri->attr, attr_new)
+ && overlay_index_equal(afi, ri, bgp_static->eth_s_id, &add)
+ && !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
+ bgp_unlock_node(rn);
+ bgp_attr_unintern(&attr_new);
+ aspath_unintern(&attr.aspath);
+ bgp_attr_extra_free(&attr);
+ return;
+ } else {
+ /* The attribute is changed. */
+ 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);
+ else
+ bgp_aggregate_decrement(bgp, p, ri, afi, safi);
+ bgp_attr_unintern(&ri->attr);
+ ri->attr = attr_new;
+ ri->uptime = bgp_clock();
#if ENABLE_BGP_VNC
- if (ri->extra)
- label = decode_label (ri->extra->tag);
+ if (ri->extra)
+ label = decode_label(ri->extra->tag);
#endif
- /* Process change. */
- bgp_aggregate_increment (bgp, p, ri, afi, safi);
- bgp_process (bgp, rn, afi, safi);
+ /* Process change. */
+ bgp_aggregate_increment(bgp, p, ri, afi, safi);
+ bgp_process(bgp, rn, afi, safi);
#if ENABLE_BGP_VNC
- rfapiProcessUpdate(ri->peer, NULL, p, &bgp_static->prd,
- ri->attr, afi, safi,
- ri->type, ri->sub_type, &label);
+ rfapiProcessUpdate(ri->peer, NULL, p, &bgp_static->prd,
+ ri->attr, afi, safi, ri->type,
+ ri->sub_type, &label);
#endif
- bgp_unlock_node (rn);
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
- return;
- }
- }
+ bgp_unlock_node(rn);
+ aspath_unintern(&attr.aspath);
+ bgp_attr_extra_free(&attr);
+ return;
+ }
+ }
- /* Make new BGP info. */
- new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self, attr_new,
- rn);
- SET_FLAG (new->flags, BGP_INFO_VALID);
- new->extra = bgp_info_extra_new();
- memcpy (new->extra->tag, bgp_static->tag, 3);
+ /* Make new BGP info. */
+ new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, bgp->peer_self,
+ attr_new, rn);
+ SET_FLAG(new->flags, BGP_INFO_VALID);
+ new->extra = bgp_info_extra_new();
+ memcpy(new->extra->tag, bgp_static->tag, 3);
#if ENABLE_BGP_VNC
- label = decode_label (bgp_static->tag);
+ label = decode_label(bgp_static->tag);
#endif
- /* Aggregate address increment. */
- bgp_aggregate_increment (bgp, p, new, afi, safi);
+ /* Aggregate address increment. */
+ bgp_aggregate_increment(bgp, p, new, afi, safi);
- /* Register new BGP information. */
- bgp_info_add (rn, new);
- /* route_node_get lock */
- bgp_unlock_node (rn);
+ /* Register new BGP information. */
+ bgp_info_add(rn, new);
+ /* route_node_get lock */
+ bgp_unlock_node(rn);
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
+ /* Process change. */
+ bgp_process(bgp, rn, afi, safi);
#if ENABLE_BGP_VNC
- rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd,
- new->attr, afi, safi,
- new->type, new->sub_type, &label);
+ rfapiProcessUpdate(new->peer, NULL, p, &bgp_static->prd, new->attr, afi,
+ safi, new->type, new->sub_type, &label);
#endif
- /* Unintern original. */
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
+ /* Unintern original. */
+ aspath_unintern(&attr.aspath);
+ bgp_attr_extra_free(&attr);
}
/* Configure static BGP network. When user don't run zebra, static
route should be installed as valid. */
-static int
-bgp_static_set (struct vty *vty, const char *ip_str,
- afi_t afi, safi_t safi, const char *rmap, int backdoor)
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- int ret;
- struct prefix p;
- struct bgp_static *bgp_static;
- struct bgp_node *rn;
- u_char need_update = 0;
-
- /* Convert IP prefix string to struct prefix. */
- ret = str2prefix (ip_str, &p);
- if (! ret)
- {
- vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
- {
- vty_out (vty, "%% Malformed prefix (link-local address)%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
+static int bgp_static_set(struct vty *vty, const char *ip_str, afi_t afi,
+ safi_t safi, const char *rmap, int backdoor)
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int ret;
+ struct prefix p;
+ struct bgp_static *bgp_static;
+ struct bgp_node *rn;
+ u_char need_update = 0;
+
+ /* Convert IP prefix string to struct prefix. */
+ ret = str2prefix(ip_str, &p);
+ if (!ret) {
+ vty_out(vty, "%% Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
+ vty_out(vty, "%% Malformed prefix (link-local address)%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- apply_mask (&p);
+ apply_mask(&p);
- /* Set BGP static route configuration. */
- rn = bgp_node_get (bgp->route[afi][safi], &p);
+ /* Set BGP static route configuration. */
+ rn = bgp_node_get(bgp->route[afi][safi], &p);
- if (rn->info)
- {
- /* Configuration change. */
- bgp_static = rn->info;
-
- /* Check previous routes are installed into BGP. */
- if (bgp_static->valid && bgp_static->backdoor != backdoor)
- need_update = 1;
-
- bgp_static->backdoor = backdoor;
-
- if (rmap)
- {
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
- bgp_static->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
- bgp_static->rmap.map = route_map_lookup_by_name (rmap);
- }
- else
- {
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
- bgp_static->rmap.name = NULL;
- bgp_static->rmap.map = NULL;
- bgp_static->valid = 0;
- }
- bgp_unlock_node (rn);
- }
- else
- {
- /* New configuration. */
- bgp_static = bgp_static_new ();
- bgp_static->backdoor = backdoor;
- bgp_static->valid = 0;
- bgp_static->igpmetric = 0;
- bgp_static->igpnexthop.s_addr = 0;
-
- if (rmap)
- {
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
- bgp_static->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
- bgp_static->rmap.map = route_map_lookup_by_name (rmap);
- }
- rn->info = bgp_static;
- }
+ if (rn->info) {
+ /* Configuration change. */
+ bgp_static = rn->info;
- bgp_static->valid = 1;
- if (need_update)
- bgp_static_withdraw (bgp, &p, afi, safi);
+ /* Check previous routes are installed into BGP. */
+ if (bgp_static->valid && bgp_static->backdoor != backdoor)
+ need_update = 1;
+
+ bgp_static->backdoor = backdoor;
+
+ if (rmap) {
+ if (bgp_static->rmap.name)
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp_static->rmap.name);
+ bgp_static->rmap.name =
+ XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
+ bgp_static->rmap.map = route_map_lookup_by_name(rmap);
+ } else {
+ if (bgp_static->rmap.name)
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp_static->rmap.name);
+ bgp_static->rmap.name = NULL;
+ bgp_static->rmap.map = NULL;
+ bgp_static->valid = 0;
+ }
+ bgp_unlock_node(rn);
+ } else {
+ /* New configuration. */
+ bgp_static = bgp_static_new();
+ bgp_static->backdoor = backdoor;
+ bgp_static->valid = 0;
+ bgp_static->igpmetric = 0;
+ bgp_static->igpnexthop.s_addr = 0;
+
+ if (rmap) {
+ if (bgp_static->rmap.name)
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp_static->rmap.name);
+ bgp_static->rmap.name =
+ XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
+ bgp_static->rmap.map = route_map_lookup_by_name(rmap);
+ }
+ rn->info = bgp_static;
+ }
- if (! bgp_static->backdoor)
- bgp_static_update (bgp, &p, bgp_static, afi, safi);
+ bgp_static->valid = 1;
+ if (need_update)
+ bgp_static_withdraw(bgp, &p, afi, safi);
- return CMD_SUCCESS;
+ if (!bgp_static->backdoor)
+ bgp_static_update(bgp, &p, bgp_static, afi, safi);
+
+ return CMD_SUCCESS;
}
/* Configure static BGP network. */
-static int
-bgp_static_unset (struct vty *vty, const char *ip_str,
- afi_t afi, safi_t safi)
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- int ret;
- struct prefix p;
- struct bgp_static *bgp_static;
- struct bgp_node *rn;
-
- /* Convert IP prefix string to struct prefix. */
- ret = str2prefix (ip_str, &p);
- if (! ret)
- {
- vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL (&p.u.prefix6))
- {
- vty_out (vty, "%% Malformed prefix (link-local address)%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
+static int bgp_static_unset(struct vty *vty, const char *ip_str, afi_t afi,
+ safi_t safi)
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int ret;
+ struct prefix p;
+ struct bgp_static *bgp_static;
+ struct bgp_node *rn;
+
+ /* Convert IP prefix string to struct prefix. */
+ ret = str2prefix(ip_str, &p);
+ if (!ret) {
+ vty_out(vty, "%% Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
+ vty_out(vty, "%% Malformed prefix (link-local address)%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- apply_mask (&p);
+ apply_mask(&p);
- rn = bgp_node_lookup (bgp->route[afi][safi], &p);
- if (! rn)
- {
- vty_out (vty, "%% Can't find specified static route configuration.%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
+ rn = bgp_node_lookup(bgp->route[afi][safi], &p);
+ if (!rn) {
+ vty_out(vty,
+ "%% Can't find specified static route configuration.%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- bgp_static = rn->info;
-
- /* Update BGP RIB. */
- if (! bgp_static->backdoor)
- bgp_static_withdraw (bgp, &p, afi, safi);
-
- /* Clear configuration. */
- bgp_static_free (bgp_static);
- rn->info = NULL;
- bgp_unlock_node (rn);
- bgp_unlock_node (rn);
-
- return CMD_SUCCESS;
-}
-
-void
-bgp_static_add (struct bgp *bgp)
-{
- afi_t afi;
- safi_t safi;
- struct bgp_node *rn;
- struct bgp_node *rm;
- struct bgp_table *table;
- struct bgp_static *bgp_static;
-
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
- if (rn->info != NULL)
- {
- if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
- {
- table = rn->info;
-
- for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
- {
- bgp_static = rm->info;
- bgp_static_update_safi (bgp, &rm->p, bgp_static, afi, safi);
- }
- }
- else
- {
- bgp_static_update (bgp, &rn->p, rn->info, afi, safi);
- }
- }
+ bgp_static = rn->info;
+
+ /* Update BGP RIB. */
+ if (!bgp_static->backdoor)
+ bgp_static_withdraw(bgp, &p, afi, safi);
+
+ /* Clear configuration. */
+ bgp_static_free(bgp_static);
+ rn->info = NULL;
+ bgp_unlock_node(rn);
+ bgp_unlock_node(rn);
+
+ return CMD_SUCCESS;
+}
+
+void bgp_static_add(struct bgp *bgp)
+{
+ afi_t afi;
+ safi_t safi;
+ struct bgp_node *rn;
+ struct bgp_node *rm;
+ struct bgp_table *table;
+ struct bgp_static *bgp_static;
+
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
+ rn = bgp_route_next(rn))
+ if (rn->info != NULL) {
+ if ((safi == SAFI_MPLS_VPN)
+ || (safi == SAFI_ENCAP)
+ || (safi == SAFI_EVPN)) {
+ table = rn->info;
+
+ for (rm = bgp_table_top(table);
+ rm;
+ rm = bgp_route_next(rm)) {
+ bgp_static = rm->info;
+ bgp_static_update_safi(
+ bgp, &rm->p,
+ bgp_static, afi,
+ safi);
+ }
+ } else {
+ bgp_static_update(bgp, &rn->p,
+ rn->info, afi,
+ safi);
+ }
+ }
}
/* Called from bgp_delete(). Delete all static routes from the BGP
instance. */
-void
-bgp_static_delete (struct bgp *bgp)
-{
- afi_t afi;
- safi_t safi;
- struct bgp_node *rn;
- struct bgp_node *rm;
- struct bgp_table *table;
- struct bgp_static *bgp_static;
-
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
- if (rn->info != NULL)
- {
- if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
- {
- table = rn->info;
-
- for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
- {
- bgp_static = rm->info;
- bgp_static_withdraw_safi (bgp, &rm->p,
- AFI_IP, safi,
- (struct prefix_rd *)&rn->p,
- bgp_static->tag);
- bgp_static_free (bgp_static);
- rn->info = NULL;
- bgp_unlock_node (rn);
- }
- }
- else
- {
- bgp_static = rn->info;
- bgp_static_withdraw (bgp, &rn->p, afi, safi);
- bgp_static_free (bgp_static);
- rn->info = NULL;
- bgp_unlock_node (rn);
- }
- }
-}
-
-void
-bgp_static_redo_import_check (struct bgp *bgp)
-{
- afi_t afi;
- safi_t safi;
- struct bgp_node *rn;
- struct bgp_node *rm;
- struct bgp_table *table;
- struct bgp_static *bgp_static;
-
- /* Use this flag to force reprocessing of the route */
- bgp_flag_set(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
- if (rn->info != NULL)
- {
- if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
- {
- table = rn->info;
-
- for (rm = bgp_table_top (table); rm; rm = bgp_route_next (rm))
- {
- bgp_static = rm->info;
- bgp_static_update_safi (bgp, &rm->p, bgp_static, afi, safi);
- }
- }
- else
- {
- bgp_static = rn->info;
- bgp_static_update (bgp, &rn->p, bgp_static, afi, safi);
- }
- }
- bgp_flag_unset(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
-}
-
-static void
-bgp_purge_af_static_redist_routes (struct bgp *bgp, afi_t afi, safi_t safi)
-{
- struct bgp_table *table;
- struct bgp_node *rn;
- struct bgp_info *ri;
-
- table = bgp->rib[afi][safi];
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- {
- for (ri = rn->info; ri; ri = ri->next)
- {
- if (ri->peer == bgp->peer_self &&
- ((ri->type == ZEBRA_ROUTE_BGP &&
- ri->sub_type == BGP_ROUTE_STATIC) ||
- (ri->type != ZEBRA_ROUTE_BGP &&
- ri->sub_type == BGP_ROUTE_REDISTRIBUTE)))
- {
- bgp_aggregate_decrement (bgp, &rn->p, ri, afi, safi);
- bgp_unlink_nexthop(ri);
- bgp_info_delete (rn, ri);
- bgp_process (bgp, rn, afi, safi);
- }
- }
- }
+void bgp_static_delete(struct bgp *bgp)
+{
+ afi_t afi;
+ safi_t safi;
+ struct bgp_node *rn;
+ struct bgp_node *rm;
+ struct bgp_table *table;
+ struct bgp_static *bgp_static;
+
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
+ rn = bgp_route_next(rn))
+ if (rn->info != NULL) {
+ if ((safi == SAFI_MPLS_VPN)
+ || (safi == SAFI_ENCAP)
+ || (safi == SAFI_EVPN)) {
+ table = rn->info;
+
+ for (rm = bgp_table_top(table);
+ rm;
+ rm = bgp_route_next(rm)) {
+ bgp_static = rm->info;
+ bgp_static_withdraw_safi(
+ bgp, &rm->p,
+ AFI_IP, safi,
+ (struct
+ prefix_rd *)&rn
+ ->p,
+ bgp_static
+ ->tag);
+ bgp_static_free(
+ bgp_static);
+ rn->info = NULL;
+ bgp_unlock_node(rn);
+ }
+ } else {
+ bgp_static = rn->info;
+ bgp_static_withdraw(bgp, &rn->p,
+ afi, safi);
+ bgp_static_free(bgp_static);
+ rn->info = NULL;
+ bgp_unlock_node(rn);
+ }
+ }
+}
+
+void bgp_static_redo_import_check(struct bgp *bgp)
+{
+ afi_t afi;
+ safi_t safi;
+ struct bgp_node *rn;
+ struct bgp_node *rm;
+ struct bgp_table *table;
+ struct bgp_static *bgp_static;
+
+ /* Use this flag to force reprocessing of the route */
+ bgp_flag_set(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
+ rn = bgp_route_next(rn))
+ if (rn->info != NULL) {
+ if ((safi == SAFI_MPLS_VPN)
+ || (safi == SAFI_ENCAP)
+ || (safi == SAFI_EVPN)) {
+ table = rn->info;
+
+ for (rm = bgp_table_top(table);
+ rm;
+ rm = bgp_route_next(rm)) {
+ bgp_static = rm->info;
+ bgp_static_update_safi(
+ bgp, &rm->p,
+ bgp_static, afi,
+ safi);
+ }
+ } else {
+ bgp_static = rn->info;
+ bgp_static_update(bgp, &rn->p,
+ bgp_static,
+ afi, safi);
+ }
+ }
+ bgp_flag_unset(bgp, BGP_FLAG_FORCE_STATIC_PROCESS);
+}
+
+static void bgp_purge_af_static_redist_routes(struct bgp *bgp, afi_t afi,
+ safi_t safi)
+{
+ struct bgp_table *table;
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+
+ table = bgp->rib[afi][safi];
+ for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
+ for (ri = rn->info; ri; ri = ri->next) {
+ if (ri->peer == bgp->peer_self
+ && ((ri->type == ZEBRA_ROUTE_BGP
+ && ri->sub_type == BGP_ROUTE_STATIC)
+ || (ri->type != ZEBRA_ROUTE_BGP
+ && ri->sub_type
+ == BGP_ROUTE_REDISTRIBUTE))) {
+ bgp_aggregate_decrement(bgp, &rn->p, ri, afi,
+ safi);
+ bgp_unlink_nexthop(ri);
+ bgp_info_delete(rn, ri);
+ bgp_process(bgp, rn, afi, safi);
+ }
+ }
+ }
}
/*
* Purge all networks and redistributed routes from routing table.
* Invoked upon the instance going down.
*/
-void
-bgp_purge_static_redist_routes (struct bgp *bgp)
+void bgp_purge_static_redist_routes(struct bgp *bgp)
{
- afi_t afi;
- safi_t safi;
+ afi_t afi;
+ safi_t safi;
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- bgp_purge_af_static_redist_routes (bgp, afi, safi);
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ bgp_purge_af_static_redist_routes(bgp, afi, safi);
}
/*
@@ -4451,274 +4413,257 @@ bgp_purge_static_redist_routes (struct bgp *bgp)
* Currently this is used to set static routes for VPN and ENCAP.
* I think it can probably be factored with bgp_static_set.
*/
-int
-bgp_static_set_safi (afi_t afi, safi_t safi, struct vty *vty, const char *ip_str,
- const char *rd_str, const char *label_str,
- const char *rmap_str, int evpn_type, const char *esi, const char *gwip,
- const char *ethtag, const char *routermac)
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- int ret;
- struct prefix p;
- struct prefix_rd prd;
- struct bgp_node *prn;
- struct bgp_node *rn;
- struct bgp_table *table;
- struct bgp_static *bgp_static;
- u_char tag[3];
- struct prefix gw_ip;
-
- /* validate ip prefix */
- ret = str2prefix (ip_str, &p);
- if (! ret)
- {
- vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- apply_mask (&p);
- if ( (afi == AFI_L2VPN) &&
- (bgp_build_evpn_prefix ( evpn_type, ethtag!=NULL?atol(ethtag):0, &p)))
- {
- vty_out (vty, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
+ const char *ip_str, const char *rd_str,
+ const char *label_str, const char *rmap_str,
+ int evpn_type, const char *esi, const char *gwip,
+ const char *ethtag, const char *routermac)
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int ret;
+ struct prefix p;
+ struct prefix_rd prd;
+ struct bgp_node *prn;
+ struct bgp_node *rn;
+ struct bgp_table *table;
+ struct bgp_static *bgp_static;
+ u_char tag[3];
+ struct prefix gw_ip;
+
+ /* validate ip prefix */
+ ret = str2prefix(ip_str, &p);
+ if (!ret) {
+ vty_out(vty, "%% Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ apply_mask(&p);
+ if ((afi == AFI_L2VPN)
+ && (bgp_build_evpn_prefix(evpn_type,
+ ethtag != NULL ? atol(ethtag) : 0, &p))) {
+ vty_out(vty, "%% L2VPN prefix could not be forged%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- ret = str2prefix_rd (rd_str, &prd);
- if (! ret)
- {
- vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ ret = str2prefix_rd(rd_str, &prd);
+ if (!ret) {
+ vty_out(vty, "%% Malformed rd%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- if (label_str)
- {
- unsigned long label_val;
- VTY_GET_INTEGER_RANGE("Label/tag", label_val, label_str, 0, 16777215);
- encode_label (label_val, tag);
- }
- else
- {
- memset (tag, 0, sizeof(tag)); /* empty, not even BoS */
- }
- if (safi == SAFI_EVPN)
- {
- if( esi && str2esi (esi, NULL) == 0)
- {
- vty_out (vty, "%% Malformed ESI%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if( routermac && prefix_str2mac (routermac, NULL) == 0)
- {
- vty_out (vty, "%% Malformed Router MAC%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if (gwip)
- {
- memset (&gw_ip, 0, sizeof (struct prefix));
- ret = str2prefix (gwip, &gw_ip);
- if (! ret)
- {
- vty_out (vty, "%% Malformed GatewayIp%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if((gw_ip.family == AF_INET && (p.u.prefix_evpn.flags & IP_PREFIX_V6))
- || (gw_ip.family == AF_INET6 && (p.u.prefix_evpn.flags & IP_PREFIX_V4)))
- {
- vty_out (vty, "%% GatewayIp family differs with IP prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- }
- prn = bgp_node_get (bgp->route[afi][safi],
- (struct prefix *)&prd);
- if (prn->info == NULL)
- prn->info = bgp_table_init (afi, safi);
- else
- bgp_unlock_node (prn);
- table = prn->info;
+ if (label_str) {
+ unsigned long label_val;
+ VTY_GET_INTEGER_RANGE("Label/tag", label_val, label_str, 0,
+ 16777215);
+ encode_label(label_val, tag);
+ } else {
+ memset(tag, 0, sizeof(tag)); /* empty, not even BoS */
+ }
+ if (safi == SAFI_EVPN) {
+ if (esi && str2esi(esi, NULL) == 0) {
+ vty_out(vty, "%% Malformed ESI%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (routermac && prefix_str2mac(routermac, NULL) == 0) {
+ vty_out(vty, "%% Malformed Router MAC%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if (gwip) {
+ memset(&gw_ip, 0, sizeof(struct prefix));
+ ret = str2prefix(gwip, &gw_ip);
+ if (!ret) {
+ vty_out(vty, "%% Malformed GatewayIp%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if ((gw_ip.family == AF_INET
+ && (p.u.prefix_evpn.flags & IP_PREFIX_V6))
+ || (gw_ip.family == AF_INET6
+ && (p.u.prefix_evpn.flags & IP_PREFIX_V4))) {
+ vty_out(vty,
+ "%% GatewayIp family differs with IP prefix%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
+ }
+ prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
+ if (prn->info == NULL)
+ prn->info = bgp_table_init(afi, safi);
+ else
+ bgp_unlock_node(prn);
+ table = prn->info;
+
+ rn = bgp_node_get(table, &p);
+
+ if (rn->info) {
+ vty_out(vty, "%% Same network configuration exists%s",
+ VTY_NEWLINE);
+ bgp_unlock_node(rn);
+ } else {
+ /* New configuration. */
+ bgp_static = bgp_static_new();
+ bgp_static->backdoor = 0;
+ bgp_static->valid = 0;
+ bgp_static->igpmetric = 0;
+ bgp_static->igpnexthop.s_addr = 0;
+ memcpy(bgp_static->tag, tag, 3);
+ bgp_static->prd = prd;
+
+ if (rmap_str) {
+ if (bgp_static->rmap.name)
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp_static->rmap.name);
+ bgp_static->rmap.name =
+ XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
+ bgp_static->rmap.map =
+ route_map_lookup_by_name(rmap_str);
+ }
- rn = bgp_node_get (table, &p);
+ if (safi == SAFI_EVPN) {
+ if (esi) {
+ bgp_static->eth_s_id =
+ XCALLOC(MTYPE_ATTR,
+ sizeof(struct eth_segment_id));
+ str2esi(esi, bgp_static->eth_s_id);
+ }
+ if (routermac) {
+ bgp_static->router_mac =
+ XCALLOC(MTYPE_ATTR, ETHER_ADDR_LEN + 1);
+ prefix_str2mac(routermac,
+ bgp_static->router_mac);
+ }
+ if (gwip)
+ prefix_copy(&bgp_static->gatewayIp, &gw_ip);
+ }
+ rn->info = bgp_static;
- if (rn->info)
- {
- vty_out (vty, "%% Same network configuration exists%s", VTY_NEWLINE);
- bgp_unlock_node (rn);
- }
- else
- {
- /* New configuration. */
- bgp_static = bgp_static_new ();
- bgp_static->backdoor = 0;
- bgp_static->valid = 0;
- bgp_static->igpmetric = 0;
- bgp_static->igpnexthop.s_addr = 0;
- memcpy(bgp_static->tag, tag, 3);
- bgp_static->prd = prd;
-
- if (rmap_str)
- {
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
- bgp_static->rmap.name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
- bgp_static->rmap.map = route_map_lookup_by_name (rmap_str);
- }
-
- if (safi == SAFI_EVPN)
- {
- if(esi)
- {
- bgp_static->eth_s_id = XCALLOC (MTYPE_ATTR, sizeof(struct eth_segment_id));
- str2esi (esi, bgp_static->eth_s_id);
- }
- if( routermac)
- {
- bgp_static->router_mac = XCALLOC (MTYPE_ATTR, ETHER_ADDR_LEN+1);
- prefix_str2mac (routermac, bgp_static->router_mac);
- }
- if (gwip)
- prefix_copy (&bgp_static->gatewayIp, &gw_ip);
- }
- rn->info = bgp_static;
-
- bgp_static->valid = 1;
- bgp_static_update_safi (bgp, &p, bgp_static, afi, safi);
- }
+ bgp_static->valid = 1;
+ bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
/* Configure static BGP network. */
-int
-bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty, const char *ip_str,
- const char *rd_str, const char *label_str,
- int evpn_type, const char *esi, const char *gwip, const char *ethtag)
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- int ret;
- struct prefix p;
- struct prefix_rd prd;
- struct bgp_node *prn;
- struct bgp_node *rn;
- struct bgp_table *table;
- struct bgp_static *bgp_static;
- u_char tag[3];
-
- /* Convert IP prefix string to struct prefix. */
- ret = str2prefix (ip_str, &p);
- if (! ret)
- {
- vty_out (vty, "%% Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- apply_mask (&p);
- if ( (afi == AFI_L2VPN) &&
- (bgp_build_evpn_prefix ( evpn_type, ethtag!=NULL?atol(ethtag):0, &p)))
- {
- vty_out (vty, "%% L2VPN prefix could not be forged%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- ret = str2prefix_rd (rd_str, &prd);
- if (! ret)
- {
- vty_out (vty, "%% Malformed rd%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (label_str)
- {
- unsigned long label_val;
- VTY_GET_INTEGER_RANGE("Label/tag", label_val, label_str, 0, MPLS_LABEL_MAX);
- encode_label (label_val, tag);
- }
- else
- {
- memset (tag, 0, sizeof(tag)); /* empty, not even BoS */
- }
-
- prn = bgp_node_get (bgp->route[afi][safi],
- (struct prefix *)&prd);
- if (prn->info == NULL)
- prn->info = bgp_table_init (afi, safi);
- else
- bgp_unlock_node (prn);
- table = prn->info;
-
- rn = bgp_node_lookup (table, &p);
+int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
+ const char *ip_str, const char *rd_str,
+ const char *label_str, int evpn_type, const char *esi,
+ const char *gwip, const char *ethtag)
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int ret;
+ struct prefix p;
+ struct prefix_rd prd;
+ struct bgp_node *prn;
+ struct bgp_node *rn;
+ struct bgp_table *table;
+ struct bgp_static *bgp_static;
+ u_char tag[3];
+
+ /* Convert IP prefix string to struct prefix. */
+ ret = str2prefix(ip_str, &p);
+ if (!ret) {
+ vty_out(vty, "%% Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ apply_mask(&p);
+ if ((afi == AFI_L2VPN)
+ && (bgp_build_evpn_prefix(evpn_type,
+ ethtag != NULL ? atol(ethtag) : 0, &p))) {
+ vty_out(vty, "%% L2VPN prefix could not be forged%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ ret = str2prefix_rd(rd_str, &prd);
+ if (!ret) {
+ vty_out(vty, "%% Malformed rd%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- if (rn)
- {
- bgp_static_withdraw_safi (bgp, &p, afi, safi, &prd, tag);
+ if (label_str) {
+ unsigned long label_val;
+ VTY_GET_INTEGER_RANGE("Label/tag", label_val, label_str, 0,
+ MPLS_LABEL_MAX);
+ encode_label(label_val, tag);
+ } else {
+ memset(tag, 0, sizeof(tag)); /* empty, not even BoS */
+ }
- bgp_static = rn->info;
- bgp_static_free (bgp_static);
- rn->info = NULL;
- bgp_unlock_node (rn);
- bgp_unlock_node (rn);
- }
- else
- vty_out (vty, "%% Can't find the route%s", VTY_NEWLINE);
+ prn = bgp_node_get(bgp->route[afi][safi], (struct prefix *)&prd);
+ if (prn->info == NULL)
+ prn->info = bgp_table_init(afi, safi);
+ else
+ bgp_unlock_node(prn);
+ table = prn->info;
- return CMD_SUCCESS;
-}
+ rn = bgp_node_lookup(table, &p);
-static int
-bgp_table_map_set (struct vty *vty, afi_t afi, safi_t safi,
- const char *rmap_name)
-{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- struct bgp_rmap *rmap;
+ if (rn) {
+ bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd, tag);
- rmap = &bgp->table_map[afi][safi];
- if (rmap_name)
- {
- if (rmap->name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
- rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
- rmap->map = route_map_lookup_by_name (rmap_name);
- }
- else
- {
- if (rmap->name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
- rmap->name = NULL;
- rmap->map = NULL;
- }
+ bgp_static = rn->info;
+ bgp_static_free(bgp_static);
+ rn->info = NULL;
+ bgp_unlock_node(rn);
+ bgp_unlock_node(rn);
+ } else
+ vty_out(vty, "%% Can't find the route%s", VTY_NEWLINE);
+
+ return CMD_SUCCESS;
+}
+
+static int bgp_table_map_set(struct vty *vty, afi_t afi, safi_t safi,
+ const char *rmap_name)
+{
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ struct bgp_rmap *rmap;
+
+ rmap = &bgp->table_map[afi][safi];
+ if (rmap_name) {
+ if (rmap->name)
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
+ rmap->map = route_map_lookup_by_name(rmap_name);
+ } else {
+ if (rmap->name)
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ rmap->name = NULL;
+ rmap->map = NULL;
+ }
- bgp_zebra_announce_table(bgp, afi, safi);
+ bgp_zebra_announce_table(bgp, afi, safi);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
-static int
-bgp_table_map_unset (struct vty *vty, afi_t afi, safi_t safi,
- const char *rmap_name)
+static int bgp_table_map_unset(struct vty *vty, afi_t afi, safi_t safi,
+ const char *rmap_name)
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- struct bgp_rmap *rmap;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ struct bgp_rmap *rmap;
- rmap = &bgp->table_map[afi][safi];
- if (rmap->name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
- rmap->name = NULL;
- rmap->map = NULL;
+ rmap = &bgp->table_map[afi][safi];
+ if (rmap->name)
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ rmap->name = NULL;
+ rmap->map = NULL;
- bgp_zebra_announce_table(bgp, afi, safi);
+ bgp_zebra_announce_table(bgp, afi, safi);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
-int
-bgp_config_write_table_map (struct vty *vty, struct bgp *bgp, afi_t afi,
- safi_t safi, int *write)
+int bgp_config_write_table_map(struct vty *vty, struct bgp *bgp, afi_t afi,
+ safi_t safi, int *write)
{
- if (bgp->table_map[afi][safi].name)
- {
- bgp_config_write_family_header (vty, afi, safi, write);
- vty_out (vty, " table-map %s%s",
- bgp->table_map[afi][safi].name, VTY_NEWLINE);
- }
+ if (bgp->table_map[afi][safi].name) {
+ bgp_config_write_family_header(vty, afi, safi, write);
+ vty_out(vty, " table-map %s%s", bgp->table_map[afi][safi].name,
+ VTY_NEWLINE);
+ }
- return 0;
+ return 0;
}
DEFUN (bgp_table_map,
@@ -4727,9 +4672,9 @@ DEFUN (bgp_table_map,
"BGP table to RIB route download filter\n"
"Name of the route map\n")
{
- int idx_word = 1;
- return bgp_table_map_set (vty,
- bgp_node_afi (vty), bgp_node_safi (vty), argv[idx_word]->arg);
+ int idx_word = 1;
+ return bgp_table_map_set(vty, bgp_node_afi(vty), bgp_node_safi(vty),
+ argv[idx_word]->arg);
}
DEFUN (no_bgp_table_map,
no_bgp_table_map_cmd,
@@ -4738,9 +4683,9 @@ DEFUN (no_bgp_table_map,
"BGP table to RIB route download filter\n"
"Name of the route map\n")
{
- int idx_word = 2;
- return bgp_table_map_unset (vty,
- bgp_node_afi (vty), bgp_node_safi (vty), argv[idx_word]->arg);
+ int idx_word = 2;
+ return bgp_table_map_unset(vty, bgp_node_afi(vty), bgp_node_safi(vty),
+ argv[idx_word]->arg);
}
DEFUN (bgp_network,
@@ -4749,9 +4694,9 @@ DEFUN (bgp_network,
"Specify a network to announce via BGP\n"
"IPv4 prefix\n")
{
- int idx_ipv4_prefixlen = 1;
- return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg,
- AFI_IP, bgp_node_safi (vty), NULL, 0);
+ int idx_ipv4_prefixlen = 1;
+ return bgp_static_set(vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
+ bgp_node_safi(vty), NULL, 0);
}
DEFUN (bgp_network_route_map,
@@ -4762,10 +4707,10 @@ DEFUN (bgp_network_route_map,
"Route-map to modify the attributes\n"
"Name of the route map\n")
{
- int idx_ipv4_prefixlen = 1;
- int idx_word = 3;
- return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg,
- AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
+ int idx_ipv4_prefixlen = 1;
+ int idx_word = 3;
+ return bgp_static_set(vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
+ bgp_node_safi(vty), argv[idx_word]->arg, 0);
}
DEFUN (bgp_network_backdoor,
@@ -4775,9 +4720,9 @@ DEFUN (bgp_network_backdoor,
"IPv4 prefix\n"
"Specify a BGP backdoor route\n")
{
- int idx_ipv4_prefixlen = 1;
- return bgp_static_set (vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP, SAFI_UNICAST,
- NULL, 1);
+ int idx_ipv4_prefixlen = 1;
+ return bgp_static_set(vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
+ SAFI_UNICAST, NULL, 1);
}
DEFUN (bgp_network_mask,
@@ -4788,20 +4733,20 @@ DEFUN (bgp_network_mask,
"Network mask\n"
"Network mask\n")
{
- int idx_ipv4 = 1;
- int idx_ipv4_2 = 3;
- int ret;
- char prefix_str[BUFSIZ];
-
- ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ int idx_ipv4 = 1;
+ int idx_ipv4_2 = 3;
+ int ret;
+ char prefix_str[BUFSIZ];
- return bgp_static_set (vty, prefix_str,
- AFI_IP, bgp_node_safi (vty), NULL, 0);
+ ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
+ prefix_str);
+ if (!ret) {
+ vty_out(vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_static_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty), NULL,
+ 0);
}
DEFUN (bgp_network_mask_route_map,
@@ -4814,21 +4759,21 @@ DEFUN (bgp_network_mask_route_map,
"Route-map to modify the attributes\n"
"Name of the route map\n")
{
- int idx_ipv4 = 1;
- int idx_ipv4_2 = 3;
- int idx_word = 5;
- int ret;
- char prefix_str[BUFSIZ];
-
- ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ int idx_ipv4 = 1;
+ int idx_ipv4_2 = 3;
+ int idx_word = 5;
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
+ prefix_str);
+ if (!ret) {
+ vty_out(vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_static_set (vty, prefix_str,
- AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
+ return bgp_static_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
+ argv[idx_word]->arg, 0);
}
DEFUN (bgp_network_mask_backdoor,
@@ -4840,20 +4785,19 @@ DEFUN (bgp_network_mask_backdoor,
"Network mask\n"
"Specify a BGP backdoor route\n")
{
- int idx_ipv4 = 1;
- int idx_ipv4_2 = 3;
- int ret;
- char prefix_str[BUFSIZ];
-
- ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ int idx_ipv4 = 1;
+ int idx_ipv4_2 = 3;
+ int ret;
+ char prefix_str[BUFSIZ];
+
+ ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
+ prefix_str);
+ if (!ret) {
+ vty_out(vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
- NULL, 1);
+ return bgp_static_set(vty, prefix_str, AFI_IP, SAFI_UNICAST, NULL, 1);
}
DEFUN (bgp_network_mask_natural,
@@ -4862,19 +4806,18 @@ DEFUN (bgp_network_mask_natural,
"Specify a network to announce via BGP\n"
"Network number\n")
{
- int idx_ipv4 = 1;
- int ret;
- char prefix_str[BUFSIZ];
+ int idx_ipv4 = 1;
+ int ret;
+ char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, NULL, prefix_str);
+ if (!ret) {
+ vty_out(vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_static_set (vty, prefix_str,
- AFI_IP, bgp_node_safi (vty), NULL, 0);
+ return bgp_static_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty), NULL,
+ 0);
}
DEFUN (bgp_network_mask_natural_route_map,
@@ -4885,20 +4828,19 @@ DEFUN (bgp_network_mask_natural_route_map,
"Route-map to modify the attributes\n"
"Name of the route map\n")
{
- int idx_ipv4 = 1;
- int idx_word = 3;
- int ret;
- char prefix_str[BUFSIZ];
+ int idx_ipv4 = 1;
+ int idx_word = 3;
+ int ret;
+ char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, NULL, prefix_str);
+ if (!ret) {
+ vty_out(vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_static_set (vty, prefix_str,
- AFI_IP, bgp_node_safi (vty), argv[idx_word]->arg, 0);
+ return bgp_static_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
+ argv[idx_word]->arg, 0);
}
DEFUN (bgp_network_mask_natural_backdoor,
@@ -4908,19 +4850,17 @@ DEFUN (bgp_network_mask_natural_backdoor,
"Network number\n"
"Specify a BGP backdoor route\n")
{
- int idx_ipv4 = 1;
- int ret;
- char prefix_str[BUFSIZ];
+ int idx_ipv4 = 1;
+ int ret;
+ char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, NULL, prefix_str);
+ if (!ret) {
+ vty_out(vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_static_set (vty, prefix_str, AFI_IP, SAFI_UNICAST,
- NULL, 1);
+ return bgp_static_set(vty, prefix_str, AFI_IP, SAFI_UNICAST, NULL, 1);
}
DEFUN (no_bgp_network,
@@ -4933,9 +4873,9 @@ DEFUN (no_bgp_network,
"Route-map to modify the attributes\n"
"Name of the route map\n")
{
- int idx_ipv4_prefixlen = 2;
- return bgp_static_unset (vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
- bgp_node_safi (vty));
+ int idx_ipv4_prefixlen = 2;
+ return bgp_static_unset(vty, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
+ bgp_node_safi(vty));
}
DEFUN (no_bgp_network_mask,
@@ -4950,20 +4890,19 @@ DEFUN (no_bgp_network_mask,
"Route-map to modify the attributes\n"
"Name of the route map\n")
{
- int idx_ipv4 = 2;
- int idx_ipv4_2 = 4;
- int ret;
- char prefix_str[BUFSIZ];
+ int idx_ipv4 = 2;
+ int idx_ipv4_2 = 4;
+ int ret;
+ char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
+ prefix_str);
+ if (!ret) {
+ vty_out(vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_static_unset (vty, prefix_str, AFI_IP,
- bgp_node_safi (vty));
+ return bgp_static_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
}
DEFUN (no_bgp_network_mask_natural,
@@ -4976,19 +4915,17 @@ DEFUN (no_bgp_network_mask_natural,
"Route-map to modify the attributes\n"
"Name of the route map\n")
{
- int idx_ipv4 = 2;
- int ret;
- char prefix_str[BUFSIZ];
+ int idx_ipv4 = 2;
+ int ret;
+ char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, NULL, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, NULL, prefix_str);
+ if (!ret) {
+ vty_out(vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_static_unset (vty, prefix_str, AFI_IP,
- bgp_node_safi (vty));
+ return bgp_static_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
}
DEFUN (ipv6_bgp_network,
@@ -4997,9 +4934,9 @@ DEFUN (ipv6_bgp_network,
"Specify a network to announce via BGP\n"
"IPv6 prefix\n")
{
- int idx_ipv6_prefixlen = 1;
- return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty),
- NULL, 0);
+ int idx_ipv6_prefixlen = 1;
+ return bgp_static_set(vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
+ bgp_node_safi(vty), NULL, 0);
}
DEFUN (ipv6_bgp_network_route_map,
@@ -5010,10 +4947,10 @@ DEFUN (ipv6_bgp_network_route_map,
"Route-map to modify the attributes\n"
"Name of the route map\n")
{
- int idx_ipv6_prefixlen = 1;
- int idx_word = 3;
- return bgp_static_set (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
- bgp_node_safi (vty), argv[idx_word]->arg, 0);
+ int idx_ipv6_prefixlen = 1;
+ int idx_word = 3;
+ return bgp_static_set(vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
+ bgp_node_safi(vty), argv[idx_word]->arg, 0);
}
DEFUN (no_ipv6_bgp_network,
@@ -5025,8 +4962,9 @@ DEFUN (no_ipv6_bgp_network,
"Route-map to modify the attributes\n"
"Name of the route map\n")
{
- int idx_ipv6_prefixlen = 2;
- return bgp_static_unset (vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6, bgp_node_safi(vty));
+ int idx_ipv6_prefixlen = 2;
+ return bgp_static_unset(vty, argv[idx_ipv6_prefixlen]->arg, AFI_IP6,
+ bgp_node_safi(vty));
}
/* Aggreagete address:
@@ -5039,589 +4977,583 @@ DEFUN (no_ipv6_bgp_network,
suppress-map Conditionally filter more specific routes from updates
<cr>
*/
-struct bgp_aggregate
-{
- /* Summary-only flag. */
- u_char summary_only;
+struct bgp_aggregate {
+ /* Summary-only flag. */
+ u_char summary_only;
- /* AS set generation. */
- u_char as_set;
+ /* AS set generation. */
+ u_char as_set;
- /* Route-map for aggregated route. */
- struct route_map *map;
+ /* Route-map for aggregated route. */
+ struct route_map *map;
- /* Suppress-count. */
- unsigned long count;
+ /* Suppress-count. */
+ unsigned long count;
- /* SAFI configuration. */
- safi_t safi;
+ /* SAFI configuration. */
+ safi_t safi;
};
-static struct bgp_aggregate *
-bgp_aggregate_new (void)
+static struct bgp_aggregate *bgp_aggregate_new(void)
{
- return XCALLOC (MTYPE_BGP_AGGREGATE, sizeof (struct bgp_aggregate));
+ return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
}
-static void
-bgp_aggregate_free (struct bgp_aggregate *aggregate)
+static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
{
- XFREE (MTYPE_BGP_AGGREGATE, aggregate);
-}
+ XFREE(MTYPE_BGP_AGGREGATE, aggregate);
+}
/* Update an aggregate as routes are added/removed from the BGP table */
-static void
-bgp_aggregate_route (struct bgp *bgp, struct prefix *p, struct bgp_info *rinew,
- afi_t afi, safi_t safi, struct bgp_info *del,
- struct bgp_aggregate *aggregate)
-{
- struct bgp_table *table;
- struct bgp_node *top;
- struct bgp_node *rn;
- u_char origin;
- struct aspath *aspath = NULL;
- struct aspath *asmerge = NULL;
- struct community *community = NULL;
- struct community *commerge = NULL;
+static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
+ struct bgp_info *rinew, afi_t afi, safi_t safi,
+ struct bgp_info *del,
+ struct bgp_aggregate *aggregate)
+{
+ struct bgp_table *table;
+ struct bgp_node *top;
+ struct bgp_node *rn;
+ u_char origin;
+ struct aspath *aspath = NULL;
+ struct aspath *asmerge = NULL;
+ struct community *community = NULL;
+ struct community *commerge = NULL;
#if defined(AGGREGATE_NEXTHOP_CHECK)
- struct in_addr nexthop;
- u_int32_t med = 0;
+ struct in_addr nexthop;
+ u_int32_t med = 0;
#endif
- struct bgp_info *ri;
- struct bgp_info *new;
- int first = 1;
- unsigned long match = 0;
- u_char atomic_aggregate = 0;
-
- /* Record adding route's nexthop and med. */
- if (rinew)
- {
+ struct bgp_info *ri;
+ struct bgp_info *new;
+ int first = 1;
+ unsigned long match = 0;
+ u_char atomic_aggregate = 0;
+
+ /* Record adding route's nexthop and med. */
+ if (rinew) {
#if defined(AGGREGATE_NEXTHOP_CHECK)
- nexthop = rinew->attr->nexthop;
- med = rinew->attr->med;
+ nexthop = rinew->attr->nexthop;
+ med = rinew->attr->med;
#endif
- }
-
- /* ORIGIN attribute: If at least one route among routes that are
- aggregated has ORIGIN with the value INCOMPLETE, then the
- aggregated route must have the ORIGIN attribute with the value
- INCOMPLETE. Otherwise, if at least one route among routes that
- are aggregated has ORIGIN with the value EGP, then the aggregated
- route must have the origin attribute with the value EGP. In all
- other case the value of the ORIGIN attribute of the aggregated
- route is INTERNAL. */
- origin = BGP_ORIGIN_IGP;
-
- table = bgp->rib[afi][safi];
-
- top = bgp_node_get (table, p);
- for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
- if (rn->p.prefixlen > p->prefixlen)
- {
- match = 0;
+ }
- for (ri = rn->info; ri; ri = ri->next)
- {
- if (BGP_INFO_HOLDDOWN (ri))
- continue;
+ /* ORIGIN attribute: If at least one route among routes that are
+ aggregated has ORIGIN with the value INCOMPLETE, then the
+ aggregated route must have the ORIGIN attribute with the value
+ INCOMPLETE. Otherwise, if at least one route among routes that
+ are aggregated has ORIGIN with the value EGP, then the aggregated
+ route must have the origin attribute with the value EGP. In all
+ other case the value of the ORIGIN attribute of the aggregated
+ route is INTERNAL. */
+ origin = BGP_ORIGIN_IGP;
+
+ table = bgp->rib[afi][safi];
- if (del && ri == del)
- continue;
+ top = bgp_node_get(table, p);
+ for (rn = bgp_node_get(table, p); rn;
+ rn = bgp_route_next_until(rn, top))
+ if (rn->p.prefixlen > p->prefixlen) {
+ match = 0;
- if (! rinew && first)
- {
+ for (ri = rn->info; ri; ri = ri->next) {
+ if (BGP_INFO_HOLDDOWN(ri))
+ continue;
+
+ if (del && ri == del)
+ continue;
+
+ if (!rinew && first) {
#if defined(AGGREGATE_NEXTHOP_CHECK)
- nexthop = ri->attr->nexthop;
- med = ri->attr->med;
+ nexthop = ri->attr->nexthop;
+ med = ri->attr->med;
#endif
- first = 0;
- }
+ first = 0;
+ }
#ifdef AGGREGATE_NEXTHOP_CHECK
- if (! IPV4_ADDR_SAME (&ri->attr->nexthop, &nexthop)
- || ri->attr->med != med)
- {
- if (aspath)
- aspath_free (aspath);
- if (community)
- community_free (community);
- bgp_unlock_node (rn);
- bgp_unlock_node (top);
- return;
- }
+ if (!IPV4_ADDR_SAME(&ri->attr->nexthop,
+ &nexthop)
+ || ri->attr->med != med) {
+ if (aspath)
+ aspath_free(aspath);
+ if (community)
+ community_free(community);
+ bgp_unlock_node(rn);
+ bgp_unlock_node(top);
+ return;
+ }
#endif /* AGGREGATE_NEXTHOP_CHECK */
- if (ri->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
- atomic_aggregate = 1;
-
- if (ri->sub_type != BGP_ROUTE_AGGREGATE)
- {
- if (aggregate->summary_only)
- {
- (bgp_info_extra_get (ri))->suppress++;
- bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
- match++;
- }
+ if (ri->attr->flag
+ & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
+ atomic_aggregate = 1;
+
+ if (ri->sub_type != BGP_ROUTE_AGGREGATE) {
+ if (aggregate->summary_only) {
+ (bgp_info_extra_get(ri))
+ ->suppress++;
+ bgp_info_set_flag(
+ rn, ri,
+ BGP_INFO_ATTR_CHANGED);
+ match++;
+ }
+
+ aggregate->count++;
+
+ if (origin < ri->attr->origin)
+ origin = ri->attr->origin;
+
+ if (aggregate->as_set) {
+ if (aspath) {
+ asmerge = aspath_aggregate(
+ aspath,
+ ri->attr->aspath);
+ aspath_free(aspath);
+ aspath = asmerge;
+ } else
+ aspath = aspath_dup(
+ ri->attr->aspath);
+
+ if (ri->attr->community) {
+ if (community) {
+ commerge = community_merge(
+ community,
+ ri->attr->community);
+ community = community_uniq_sort(
+ commerge);
+ community_free(
+ commerge);
+ } else
+ community = community_dup(
+ ri->attr->community);
+ }
+ }
+ }
+ }
+ if (match)
+ bgp_process(bgp, rn, afi, safi);
+ }
+ bgp_unlock_node(top);
+ if (rinew) {
aggregate->count++;
- if (origin < ri->attr->origin)
- origin = ri->attr->origin;
-
- if (aggregate->as_set)
- {
- if (aspath)
- {
- asmerge = aspath_aggregate (aspath, ri->attr->aspath);
- aspath_free (aspath);
- aspath = asmerge;
- }
- else
- aspath = aspath_dup (ri->attr->aspath);
-
- if (ri->attr->community)
- {
- if (community)
- {
- commerge = community_merge (community,
- ri->attr->community);
- community = community_uniq_sort (commerge);
- community_free (commerge);
- }
- else
- community = community_dup (ri->attr->community);
- }
- }
- }
- }
- if (match)
- bgp_process (bgp, rn, afi, safi);
- }
- bgp_unlock_node (top);
-
- if (rinew)
- {
- aggregate->count++;
-
- if (aggregate->summary_only)
- (bgp_info_extra_get (rinew))->suppress++;
-
- if (origin < rinew->attr->origin)
- origin = rinew->attr->origin;
-
- if (aggregate->as_set)
- {
- if (aspath)
- {
- asmerge = aspath_aggregate (aspath, rinew->attr->aspath);
- aspath_free (aspath);
- aspath = asmerge;
- }
- else
- aspath = aspath_dup (rinew->attr->aspath);
-
- if (rinew->attr->community)
- {
- if (community)
- {
- commerge = community_merge (community,
- rinew->attr->community);
- community = community_uniq_sort (commerge);
- community_free (commerge);
+ if (aggregate->summary_only)
+ (bgp_info_extra_get(rinew))->suppress++;
+
+ if (origin < rinew->attr->origin)
+ origin = rinew->attr->origin;
+
+ if (aggregate->as_set) {
+ if (aspath) {
+ asmerge = aspath_aggregate(aspath,
+ rinew->attr->aspath);
+ aspath_free(aspath);
+ aspath = asmerge;
+ } else
+ aspath = aspath_dup(rinew->attr->aspath);
+
+ if (rinew->attr->community) {
+ if (community) {
+ commerge = community_merge(
+ community,
+ rinew->attr->community);
+ community =
+ community_uniq_sort(commerge);
+ community_free(commerge);
+ } else
+ community = community_dup(
+ rinew->attr->community);
+ }
}
- else
- community = community_dup (rinew->attr->community);
- }
}
- }
- if (aggregate->count > 0)
- {
- rn = bgp_node_get (table, p);
- new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
- bgp_attr_aggregate_intern(bgp, origin, aspath, community,
- aggregate->as_set,
- atomic_aggregate), rn);
- SET_FLAG (new->flags, BGP_INFO_VALID);
-
- bgp_info_add (rn, new);
- bgp_unlock_node (rn);
- bgp_process (bgp, rn, afi, safi);
- }
- else
- {
- if (aspath)
- aspath_free (aspath);
- if (community)
- community_free (community);
- }
+ if (aggregate->count > 0) {
+ rn = bgp_node_get(table, p);
+ new = info_make(
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
+ bgp_attr_aggregate_intern(bgp, origin, aspath,
+ community, aggregate->as_set,
+ atomic_aggregate),
+ rn);
+ SET_FLAG(new->flags, BGP_INFO_VALID);
+
+ bgp_info_add(rn, new);
+ bgp_unlock_node(rn);
+ bgp_process(bgp, rn, afi, safi);
+ } else {
+ if (aspath)
+ aspath_free(aspath);
+ if (community)
+ community_free(community);
+ }
}
-void bgp_aggregate_delete (struct bgp *, struct prefix *, afi_t, safi_t,
- struct bgp_aggregate *);
+void bgp_aggregate_delete(struct bgp *, struct prefix *, afi_t, safi_t,
+ struct bgp_aggregate *);
-void
-bgp_aggregate_increment (struct bgp *bgp, struct prefix *p,
- struct bgp_info *ri, afi_t afi, safi_t safi)
+void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
+ struct bgp_info *ri, afi_t afi, safi_t safi)
{
- struct bgp_node *child;
- struct bgp_node *rn;
- struct bgp_aggregate *aggregate;
- struct bgp_table *table;
+ struct bgp_node *child;
+ struct bgp_node *rn;
+ struct bgp_aggregate *aggregate;
+ struct bgp_table *table;
- /* MPLS-VPN aggregation is not yet supported. */
- if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
- return;
+ /* MPLS-VPN aggregation is not yet supported. */
+ if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
+ || (safi == SAFI_EVPN))
+ return;
- table = bgp->aggregate[afi][safi];
+ table = bgp->aggregate[afi][safi];
- /* No aggregates configured. */
- if (bgp_table_top_nolock (table) == NULL)
- return;
+ /* No aggregates configured. */
+ if (bgp_table_top_nolock(table) == NULL)
+ return;
- if (p->prefixlen == 0)
- return;
+ if (p->prefixlen == 0)
+ return;
- if (BGP_INFO_HOLDDOWN (ri))
- return;
+ if (BGP_INFO_HOLDDOWN(ri))
+ return;
- child = bgp_node_get (table, p);
+ child = bgp_node_get(table, p);
- /* Aggregate address configuration check. */
- for (rn = child; rn; rn = bgp_node_parent_nolock (rn))
- if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen)
- {
- bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate);
- bgp_aggregate_route (bgp, &rn->p, ri, afi, safi, NULL, aggregate);
- }
- bgp_unlock_node (child);
+ /* Aggregate address configuration check. */
+ for (rn = child; rn; rn = bgp_node_parent_nolock(rn))
+ if ((aggregate = rn->info) != NULL
+ && rn->p.prefixlen < p->prefixlen) {
+ bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
+ bgp_aggregate_route(bgp, &rn->p, ri, afi, safi, NULL,
+ aggregate);
+ }
+ bgp_unlock_node(child);
}
-void
-bgp_aggregate_decrement (struct bgp *bgp, struct prefix *p,
- struct bgp_info *del, afi_t afi, safi_t safi)
+void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
+ struct bgp_info *del, afi_t afi, safi_t safi)
{
- struct bgp_node *child;
- struct bgp_node *rn;
- struct bgp_aggregate *aggregate;
- struct bgp_table *table;
+ struct bgp_node *child;
+ struct bgp_node *rn;
+ struct bgp_aggregate *aggregate;
+ struct bgp_table *table;
- /* MPLS-VPN aggregation is not yet supported. */
- if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
- return;
+ /* MPLS-VPN aggregation is not yet supported. */
+ if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
+ || (safi == SAFI_EVPN))
+ return;
- table = bgp->aggregate[afi][safi];
+ table = bgp->aggregate[afi][safi];
- /* No aggregates configured. */
- if (bgp_table_top_nolock (table) == NULL)
- return;
+ /* No aggregates configured. */
+ if (bgp_table_top_nolock(table) == NULL)
+ return;
- if (p->prefixlen == 0)
- return;
+ if (p->prefixlen == 0)
+ return;
- child = bgp_node_get (table, p);
+ child = bgp_node_get(table, p);
- /* Aggregate address configuration check. */
- for (rn = child; rn; rn = bgp_node_parent_nolock (rn))
- if ((aggregate = rn->info) != NULL && rn->p.prefixlen < p->prefixlen)
- {
- bgp_aggregate_delete (bgp, &rn->p, afi, safi, aggregate);
- bgp_aggregate_route (bgp, &rn->p, NULL, afi, safi, del, aggregate);
- }
- bgp_unlock_node (child);
+ /* Aggregate address configuration check. */
+ for (rn = child; rn; rn = bgp_node_parent_nolock(rn))
+ if ((aggregate = rn->info) != NULL
+ && rn->p.prefixlen < p->prefixlen) {
+ bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
+ bgp_aggregate_route(bgp, &rn->p, NULL, afi, safi, del,
+ aggregate);
+ }
+ bgp_unlock_node(child);
}
/* Called via bgp_aggregate_set when the user configures aggregate-address */
-static void
-bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi,
- struct bgp_aggregate *aggregate)
-{
- struct bgp_table *table;
- struct bgp_node *top;
- struct bgp_node *rn;
- struct bgp_info *new;
- struct bgp_info *ri;
- unsigned long match;
- u_char origin = BGP_ORIGIN_IGP;
- struct aspath *aspath = NULL;
- struct aspath *asmerge = NULL;
- struct community *community = NULL;
- struct community *commerge = NULL;
- u_char atomic_aggregate = 0;
-
- table = bgp->rib[afi][safi];
-
- /* Sanity check. */
- if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
- return;
- if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
- return;
-
- /* If routes exists below this node, generate aggregate routes. */
- top = bgp_node_get (table, p);
- for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
- if (rn->p.prefixlen > p->prefixlen)
- {
- match = 0;
-
- for (ri = rn->info; ri; ri = ri->next)
- {
- if (BGP_INFO_HOLDDOWN (ri))
- continue;
-
- if (ri->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
- atomic_aggregate = 1;
+static void bgp_aggregate_add(struct bgp *bgp, struct prefix *p, afi_t afi,
+ safi_t safi, struct bgp_aggregate *aggregate)
+{
+ struct bgp_table *table;
+ struct bgp_node *top;
+ struct bgp_node *rn;
+ struct bgp_info *new;
+ struct bgp_info *ri;
+ unsigned long match;
+ u_char origin = BGP_ORIGIN_IGP;
+ struct aspath *aspath = NULL;
+ struct aspath *asmerge = NULL;
+ struct community *community = NULL;
+ struct community *commerge = NULL;
+ u_char atomic_aggregate = 0;
+
+ table = bgp->rib[afi][safi];
+
+ /* Sanity check. */
+ if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
+ return;
+ if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
+ return;
- if (ri->sub_type != BGP_ROUTE_AGGREGATE)
- {
- /* summary-only aggregate route suppress aggregated
- route announcement. */
- if (aggregate->summary_only)
- {
- (bgp_info_extra_get (ri))->suppress++;
- bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
- match++;
- }
-
- /* If at least one route among routes that are aggregated has
- * ORIGIN with the value INCOMPLETE, then the aggregated route
- * MUST have the ORIGIN attribute with the value INCOMPLETE.
- * Otherwise, if at least one route among routes that are
- * aggregated has ORIGIN with the value EGP, then the aggregated
- * route MUST have the ORIGIN attribute with the value EGP.
- */
- if (origin < ri->attr->origin)
- origin = ri->attr->origin;
-
- /* as-set aggregate route generate origin, as path,
- community aggregation. */
- if (aggregate->as_set)
- {
- if (aspath)
- {
- asmerge = aspath_aggregate (aspath, ri->attr->aspath);
- aspath_free (aspath);
- aspath = asmerge;
- }
- else
- aspath = aspath_dup (ri->attr->aspath);
-
- if (ri->attr->community)
- {
- if (community)
- {
- commerge = community_merge (community,
- ri->attr->community);
- community = community_uniq_sort (commerge);
- community_free (commerge);
- }
- else
- community = community_dup (ri->attr->community);
- }
- }
- aggregate->count++;
- }
- }
-
- /* If this node is suppressed, process the change. */
- if (match)
- bgp_process (bgp, rn, afi, safi);
- }
- bgp_unlock_node (top);
-
- /* Add aggregate route to BGP table. */
- if (aggregate->count)
- {
- rn = bgp_node_get (table, p);
- new = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
- bgp_attr_aggregate_intern(bgp, origin, aspath, community,
- aggregate->as_set,
- atomic_aggregate), rn);
- SET_FLAG (new->flags, BGP_INFO_VALID);
-
- bgp_info_add (rn, new);
- bgp_unlock_node (rn);
-
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
- }
- else
- {
- if (aspath)
- aspath_free (aspath);
- if (community)
- community_free (community);
- }
+ /* If routes exists below this node, generate aggregate routes. */
+ top = bgp_node_get(table, p);
+ for (rn = bgp_node_get(table, p); rn;
+ rn = bgp_route_next_until(rn, top))
+ if (rn->p.prefixlen > p->prefixlen) {
+ match = 0;
+
+ for (ri = rn->info; ri; ri = ri->next) {
+ if (BGP_INFO_HOLDDOWN(ri))
+ continue;
+
+ if (ri->attr->flag
+ & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
+ atomic_aggregate = 1;
+
+ if (ri->sub_type != BGP_ROUTE_AGGREGATE) {
+ /* summary-only aggregate route suppress
+ aggregated
+ route announcement. */
+ if (aggregate->summary_only) {
+ (bgp_info_extra_get(ri))
+ ->suppress++;
+ bgp_info_set_flag(
+ rn, ri,
+ BGP_INFO_ATTR_CHANGED);
+ match++;
+ }
+
+ /* If at least one route among routes
+ * that are aggregated has
+ * ORIGIN with the value INCOMPLETE,
+ * then the aggregated route
+ * MUST have the ORIGIN attribute with
+ * the value INCOMPLETE.
+ * Otherwise, if at least one route
+ * among routes that are
+ * aggregated has ORIGIN with the value
+ * EGP, then the aggregated
+ * route MUST have the ORIGIN attribute
+ * with the value EGP.
+ */
+ if (origin < ri->attr->origin)
+ origin = ri->attr->origin;
+
+ /* as-set aggregate route generate
+ origin, as path,
+ community aggregation. */
+ if (aggregate->as_set) {
+ if (aspath) {
+ asmerge = aspath_aggregate(
+ aspath,
+ ri->attr->aspath);
+ aspath_free(aspath);
+ aspath = asmerge;
+ } else
+ aspath = aspath_dup(
+ ri->attr->aspath);
+
+ if (ri->attr->community) {
+ if (community) {
+ commerge = community_merge(
+ community,
+ ri->attr->community);
+ community = community_uniq_sort(
+ commerge);
+ community_free(
+ commerge);
+ } else
+ community = community_dup(
+ ri->attr->community);
+ }
+ }
+ aggregate->count++;
+ }
+ }
+
+ /* If this node is suppressed, process the change. */
+ if (match)
+ bgp_process(bgp, rn, afi, safi);
+ }
+ bgp_unlock_node(top);
+
+ /* Add aggregate route to BGP table. */
+ if (aggregate->count) {
+ rn = bgp_node_get(table, p);
+ new = info_make(
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_AGGREGATE, 0, bgp->peer_self,
+ bgp_attr_aggregate_intern(bgp, origin, aspath,
+ community, aggregate->as_set,
+ atomic_aggregate),
+ rn);
+ SET_FLAG(new->flags, BGP_INFO_VALID);
+
+ bgp_info_add(rn, new);
+ bgp_unlock_node(rn);
+
+ /* Process change. */
+ bgp_process(bgp, rn, afi, safi);
+ } else {
+ if (aspath)
+ aspath_free(aspath);
+ if (community)
+ community_free(community);
+ }
}
-void
-bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi,
- safi_t safi, struct bgp_aggregate *aggregate)
+void bgp_aggregate_delete(struct bgp *bgp, struct prefix *p, afi_t afi,
+ safi_t safi, struct bgp_aggregate *aggregate)
{
- struct bgp_table *table;
- struct bgp_node *top;
- struct bgp_node *rn;
- struct bgp_info *ri;
- unsigned long match;
+ struct bgp_table *table;
+ struct bgp_node *top;
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+ unsigned long match;
- table = bgp->rib[afi][safi];
+ table = bgp->rib[afi][safi];
- if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
- return;
- if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
- return;
+ if (afi == AFI_IP && p->prefixlen == IPV4_MAX_BITLEN)
+ return;
+ if (afi == AFI_IP6 && p->prefixlen == IPV6_MAX_BITLEN)
+ return;
+
+ /* If routes exists below this node, generate aggregate routes. */
+ top = bgp_node_get(table, p);
+ for (rn = bgp_node_get(table, p); rn;
+ rn = bgp_route_next_until(rn, top))
+ if (rn->p.prefixlen > p->prefixlen) {
+ match = 0;
+
+ for (ri = rn->info; ri; ri = ri->next) {
+ if (BGP_INFO_HOLDDOWN(ri))
+ continue;
+
+ if (ri->sub_type != BGP_ROUTE_AGGREGATE) {
+ if (aggregate->summary_only
+ && ri->extra) {
+ ri->extra->suppress--;
+
+ if (ri->extra->suppress == 0) {
+ bgp_info_set_flag(
+ rn, ri,
+ BGP_INFO_ATTR_CHANGED);
+ match++;
+ }
+ }
+ aggregate->count--;
+ }
+ }
+
+ /* If this node was suppressed, process the change. */
+ if (match)
+ bgp_process(bgp, rn, afi, safi);
+ }
+ bgp_unlock_node(top);
- /* If routes exists below this node, generate aggregate routes. */
- top = bgp_node_get (table, p);
- for (rn = bgp_node_get (table, p); rn; rn = bgp_route_next_until (rn, top))
- if (rn->p.prefixlen > p->prefixlen)
- {
- match = 0;
+ /* Delete aggregate route from BGP table. */
+ rn = bgp_node_get(table, p);
for (ri = rn->info; ri; ri = ri->next)
- {
- if (BGP_INFO_HOLDDOWN (ri))
- continue;
-
- if (ri->sub_type != BGP_ROUTE_AGGREGATE)
- {
- if (aggregate->summary_only && ri->extra)
- {
- ri->extra->suppress--;
-
- if (ri->extra->suppress == 0)
- {
- bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
- match++;
- }
- }
- aggregate->count--;
- }
- }
-
- /* If this node was suppressed, process the change. */
- if (match)
- bgp_process (bgp, rn, afi, safi);
- }
- bgp_unlock_node (top);
-
- /* Delete aggregate route from BGP table. */
- rn = bgp_node_get (table, p);
-
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self
- && ri->type == ZEBRA_ROUTE_BGP
- && ri->sub_type == BGP_ROUTE_AGGREGATE)
- break;
-
- /* Withdraw static BGP route from routing table. */
- if (ri)
- {
- bgp_info_delete (rn, ri);
- bgp_process (bgp, rn, afi, safi);
- }
+ if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
+ && ri->sub_type == BGP_ROUTE_AGGREGATE)
+ break;
+
+ /* Withdraw static BGP route from routing table. */
+ if (ri) {
+ bgp_info_delete(rn, ri);
+ bgp_process(bgp, rn, afi, safi);
+ }
- /* Unlock bgp_node_lookup. */
- bgp_unlock_node (rn);
+ /* Unlock bgp_node_lookup. */
+ bgp_unlock_node(rn);
}
/* Aggregate route attribute. */
#define AGGREGATE_SUMMARY_ONLY 1
#define AGGREGATE_AS_SET 1
-static int
-bgp_aggregate_unset (struct vty *vty, const char *prefix_str,
- afi_t afi, safi_t safi)
+static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
+ afi_t afi, safi_t safi)
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- int ret;
- struct prefix p;
- struct bgp_node *rn;
- struct bgp_aggregate *aggregate;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int ret;
+ struct prefix p;
+ struct bgp_node *rn;
+ struct bgp_aggregate *aggregate;
- /* Convert string to prefix structure. */
- ret = str2prefix (prefix_str, &p);
- if (!ret)
- {
- vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- apply_mask (&p);
-
- /* Old configuration check. */
- rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p);
- if (! rn)
- {
- vty_out (vty, "%% There is no aggregate-address configuration.%s",
- VTY_NEWLINE);
- return CMD_WARNING;
- }
+ /* Convert string to prefix structure. */
+ ret = str2prefix(prefix_str, &p);
+ if (!ret) {
+ vty_out(vty, "Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ apply_mask(&p);
+
+ /* Old configuration check. */
+ rn = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
+ if (!rn) {
+ vty_out(vty,
+ "%% There is no aggregate-address configuration.%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- aggregate = rn->info;
- if (aggregate->safi & SAFI_UNICAST)
- bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate);
- if (aggregate->safi & SAFI_MULTICAST)
- bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate);
+ aggregate = rn->info;
+ if (aggregate->safi & SAFI_UNICAST)
+ bgp_aggregate_delete(bgp, &p, afi, SAFI_UNICAST, aggregate);
+ if (aggregate->safi & SAFI_MULTICAST)
+ bgp_aggregate_delete(bgp, &p, afi, SAFI_MULTICAST, aggregate);
- /* Unlock aggregate address configuration. */
- rn->info = NULL;
- bgp_aggregate_free (aggregate);
- bgp_unlock_node (rn);
- bgp_unlock_node (rn);
+ /* Unlock aggregate address configuration. */
+ rn->info = NULL;
+ bgp_aggregate_free(aggregate);
+ bgp_unlock_node(rn);
+ bgp_unlock_node(rn);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
-static int
-bgp_aggregate_set (struct vty *vty, const char *prefix_str,
- afi_t afi, safi_t safi,
- u_char summary_only, u_char as_set)
+static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
+ safi_t safi, u_char summary_only, u_char as_set)
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- int ret;
- struct prefix p;
- struct bgp_node *rn;
- struct bgp_aggregate *aggregate;
-
- /* Convert string to prefix structure. */
- ret = str2prefix (prefix_str, &p);
- if (!ret)
- {
- vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- apply_mask (&p);
-
- /* Old configuration check. */
- rn = bgp_node_get (bgp->aggregate[afi][safi], &p);
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int ret;
+ struct prefix p;
+ struct bgp_node *rn;
+ struct bgp_aggregate *aggregate;
- if (rn->info)
- {
- vty_out (vty, "There is already same aggregate network.%s", VTY_NEWLINE);
- /* try to remove the old entry */
- ret = bgp_aggregate_unset (vty, prefix_str, afi, safi);
- if (ret)
- {
- vty_out (vty, "Error deleting aggregate.%s", VTY_NEWLINE);
- bgp_unlock_node (rn);
- return CMD_WARNING;
- }
- }
+ /* Convert string to prefix structure. */
+ ret = str2prefix(prefix_str, &p);
+ if (!ret) {
+ vty_out(vty, "Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ apply_mask(&p);
+
+ /* Old configuration check. */
+ rn = bgp_node_get(bgp->aggregate[afi][safi], &p);
+
+ if (rn->info) {
+ vty_out(vty, "There is already same aggregate network.%s",
+ VTY_NEWLINE);
+ /* try to remove the old entry */
+ ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
+ if (ret) {
+ vty_out(vty, "Error deleting aggregate.%s",
+ VTY_NEWLINE);
+ bgp_unlock_node(rn);
+ return CMD_WARNING;
+ }
+ }
- /* Make aggregate address structure. */
- aggregate = bgp_aggregate_new ();
- aggregate->summary_only = summary_only;
- aggregate->as_set = as_set;
- aggregate->safi = safi;
- rn->info = aggregate;
+ /* Make aggregate address structure. */
+ aggregate = bgp_aggregate_new();
+ aggregate->summary_only = summary_only;
+ aggregate->as_set = as_set;
+ aggregate->safi = safi;
+ rn->info = aggregate;
- /* Aggregate address insert into BGP routing table. */
- if (safi & SAFI_UNICAST)
- bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate);
- if (safi & SAFI_MULTICAST)
- bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate);
+ /* Aggregate address insert into BGP routing table. */
+ if (safi & SAFI_UNICAST)
+ bgp_aggregate_add(bgp, &p, afi, SAFI_UNICAST, aggregate);
+ if (safi & SAFI_MULTICAST)
+ bgp_aggregate_add(bgp, &p, afi, SAFI_MULTICAST, aggregate);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (aggregate_address,
@@ -5634,14 +5566,18 @@ DEFUN (aggregate_address,
"Filter more specific routes from updates\n"
"Generate AS set path information\n")
{
- int idx = 0;
- argv_find (argv, argc, "A.B.C.D/M", &idx);
- char *prefix = argv[idx]->arg;
- int as_set = argv_find (argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
- idx = 0;
- int summary_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
+ int idx = 0;
+ argv_find(argv, argc, "A.B.C.D/M", &idx);
+ char *prefix = argv[idx]->arg;
+ int as_set =
+ argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
+ idx = 0;
+ int summary_only = argv_find(argv, argc, "summary-only", &idx)
+ ? AGGREGATE_SUMMARY_ONLY
+ : 0;
- return bgp_aggregate_set (vty, prefix, AFI_IP, bgp_node_safi (vty), summary_only, as_set);
+ return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty),
+ summary_only, as_set);
}
DEFUN (aggregate_address_mask,
@@ -5655,25 +5591,28 @@ DEFUN (aggregate_address_mask,
"Filter more specific routes from updates\n"
"Generate AS set path information\n")
{
- int idx = 0;
- argv_find (argv, argc, "A.B.C.D", &idx);
- char *prefix = argv[idx++]->arg;
- argv_find (argv, argc, "A.B.C.D", &idx);
- char *mask = argv[idx]->arg;
- int as_set = argv_find (argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
- idx = 0;
- int summary_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
-
- char prefix_str[BUFSIZ];
- int ret = netmask_str2prefix_str (prefix, mask, prefix_str);
-
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ int idx = 0;
+ argv_find(argv, argc, "A.B.C.D", &idx);
+ char *prefix = argv[idx++]->arg;
+ argv_find(argv, argc, "A.B.C.D", &idx);
+ char *mask = argv[idx]->arg;
+ int as_set =
+ argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET : 0;
+ idx = 0;
+ int summary_only = argv_find(argv, argc, "summary-only", &idx)
+ ? AGGREGATE_SUMMARY_ONLY
+ : 0;
+
+ char prefix_str[BUFSIZ];
+ int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
+
+ if (!ret) {
+ vty_out(vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_aggregate_set (vty, prefix_str, AFI_IP, bgp_node_safi (vty), summary_only, as_set);
+ return bgp_aggregate_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
+ summary_only, as_set);
}
DEFUN (no_aggregate_address,
@@ -5687,10 +5626,10 @@ DEFUN (no_aggregate_address,
"Filter more specific routes from updates\n"
"Generate AS set path information\n")
{
- int idx = 0;
- argv_find (argv, argc, "A.B.C.D/M", &idx);
- char *prefix = argv[idx]->arg;
- return bgp_aggregate_unset (vty, prefix, AFI_IP, bgp_node_safi (vty));
+ int idx = 0;
+ argv_find(argv, argc, "A.B.C.D/M", &idx);
+ char *prefix = argv[idx]->arg;
+ return bgp_aggregate_unset(vty, prefix, AFI_IP, bgp_node_safi(vty));
}
DEFUN (no_aggregate_address_mask,
@@ -5705,22 +5644,21 @@ DEFUN (no_aggregate_address_mask,
"Filter more specific routes from updates\n"
"Generate AS set path information\n")
{
- int idx = 0;
- argv_find (argv, argc, "A.B.C.D", &idx);
- char *prefix = argv[idx++]->arg;
- argv_find (argv, argc, "A.B.C.D", &idx);
- char *mask = argv[idx]->arg;
+ int idx = 0;
+ argv_find(argv, argc, "A.B.C.D", &idx);
+ char *prefix = argv[idx++]->arg;
+ argv_find(argv, argc, "A.B.C.D", &idx);
+ char *mask = argv[idx]->arg;
- char prefix_str[BUFSIZ];
- int ret = netmask_str2prefix_str (prefix, mask, prefix_str);
+ char prefix_str[BUFSIZ];
+ int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ if (!ret) {
+ vty_out(vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_aggregate_unset (vty, prefix_str, AFI_IP, bgp_node_safi (vty));
+ return bgp_aggregate_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
}
DEFUN (ipv6_aggregate_address,
@@ -5730,11 +5668,14 @@ DEFUN (ipv6_aggregate_address,
"Aggregate prefix\n"
"Filter more specific routes from updates\n")
{
- int idx = 0;
- argv_find (argv, argc, "X:X::X:X/M", &idx);
- char *prefix = argv[idx]->arg;
- int sum_only = argv_find (argv, argc, "summary-only", &idx) ? AGGREGATE_SUMMARY_ONLY : 0;
- return bgp_aggregate_set (vty, prefix, AFI_IP6, SAFI_UNICAST, sum_only, 0);
+ int idx = 0;
+ argv_find(argv, argc, "X:X::X:X/M", &idx);
+ char *prefix = argv[idx]->arg;
+ int sum_only = argv_find(argv, argc, "summary-only", &idx)
+ ? AGGREGATE_SUMMARY_ONLY
+ : 0;
+ return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, sum_only,
+ 0);
}
DEFUN (no_ipv6_aggregate_address,
@@ -5745,2464 +5686,2639 @@ DEFUN (no_ipv6_aggregate_address,
"Aggregate prefix\n"
"Filter more specific routes from updates\n")
{
- int idx = 0;
- argv_find (argv, argc, "X:X::X:X/M", &idx);
- char *prefix = argv[idx]->arg;
- return bgp_aggregate_unset (vty, prefix, AFI_IP6, SAFI_UNICAST);
+ int idx = 0;
+ argv_find(argv, argc, "X:X::X:X/M", &idx);
+ char *prefix = argv[idx]->arg;
+ return bgp_aggregate_unset(vty, prefix, AFI_IP6, SAFI_UNICAST);
}
/* Redistribute route treatment. */
-void
-bgp_redistribute_add (struct bgp *bgp, struct prefix *p, const struct in_addr *nexthop,
- const struct in6_addr *nexthop6, unsigned int ifindex,
- u_int32_t metric, u_char type, u_short instance, route_tag_t tag)
-{
- struct bgp_info *new;
- struct bgp_info *bi;
- struct bgp_info info;
- struct bgp_node *bn;
- struct attr attr;
- struct attr *new_attr;
- afi_t afi;
- int ret;
- struct bgp_redist *red;
-
- /* Make default attribute. */
- bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
- if (nexthop)
- attr.nexthop = *nexthop;
- attr.nh_ifindex = ifindex;
-
- if (nexthop6)
- {
- struct attr_extra *extra = bgp_attr_extra_get(&attr);
- extra->mp_nexthop_global = *nexthop6;
- extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
- }
+void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
+ const struct in_addr *nexthop,
+ const struct in6_addr *nexthop6, unsigned int ifindex,
+ u_int32_t metric, u_char type, u_short instance,
+ route_tag_t tag)
+{
+ struct bgp_info *new;
+ struct bgp_info *bi;
+ struct bgp_info info;
+ struct bgp_node *bn;
+ struct attr attr;
+ struct attr *new_attr;
+ afi_t afi;
+ int ret;
+ struct bgp_redist *red;
+
+ /* Make default attribute. */
+ bgp_attr_default_set(&attr, BGP_ORIGIN_INCOMPLETE);
+ if (nexthop)
+ attr.nexthop = *nexthop;
+ attr.nh_ifindex = ifindex;
+
+ if (nexthop6) {
+ struct attr_extra *extra = bgp_attr_extra_get(&attr);
+ extra->mp_nexthop_global = *nexthop6;
+ extra->mp_nexthop_len = BGP_ATTR_NHLEN_IPV6_GLOBAL;
+ }
- attr.med = metric;
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
- attr.extra->tag = tag;
+ attr.med = metric;
+ attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC);
+ attr.extra->tag = tag;
- afi = family2afi (p->family);
+ afi = family2afi(p->family);
- red = bgp_redist_lookup(bgp, afi, type, instance);
- if (red)
- {
- struct attr attr_new;
- struct attr_extra extra_new;
-
- /* Copy attribute for modification. */
- attr_new.extra = &extra_new;
- bgp_attr_dup (&attr_new, &attr);
-
- if (red->redist_metric_flag)
- attr_new.med = red->redist_metric;
-
- /* Apply route-map. */
- if (red->rmap.name)
- {
- info.peer = bgp->peer_self;
- info.attr = &attr_new;
-
- SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE);
-
- ret = route_map_apply (red->rmap.map, p, RMAP_BGP, &info);
-
- bgp->peer_self->rmap_type = 0;
-
- if (ret == RMAP_DENYMATCH)
- {
- /* Free uninterned attribute. */
- bgp_attr_flush (&attr_new);
-
- /* Unintern original. */
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
- bgp_redistribute_delete (bgp, p, type, instance);
- return;
- }
- }
-
- bn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST],
- afi, SAFI_UNICAST, p, NULL);
-
- new_attr = bgp_attr_intern (&attr_new);
-
- for (bi = bn->info; bi; bi = bi->next)
- if (bi->peer == bgp->peer_self
- && bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
- break;
-
- if (bi)
- {
- /* Ensure the (source route) type is updated. */
- bi->type = type;
- if (attrhash_cmp (bi->attr, new_attr) &&
- !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED))
- {
- bgp_attr_unintern (&new_attr);
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
- bgp_unlock_node (bn);
- return;
- }
- else
- {
- /* The attribute is changed. */
- bgp_info_set_flag (bn, bi, BGP_INFO_ATTR_CHANGED);
-
- /* Rewrite BGP route information. */
- 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 = bgp_clock ();
-
- /* Process change. */
- bgp_aggregate_increment (bgp, p, bi, afi, SAFI_UNICAST);
- bgp_process (bgp, bn, afi, SAFI_UNICAST);
- bgp_unlock_node (bn);
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
- return;
- }
- }
-
- new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance, bgp->peer_self,
- new_attr, bn);
- SET_FLAG (new->flags, BGP_INFO_VALID);
-
- bgp_aggregate_increment (bgp, p, new, afi, SAFI_UNICAST);
- bgp_info_add (bn, new);
- bgp_unlock_node (bn);
- bgp_process (bgp, bn, afi, SAFI_UNICAST);
- }
+ red = bgp_redist_lookup(bgp, afi, type, instance);
+ if (red) {
+ struct attr attr_new;
+ struct attr_extra extra_new;
- /* Unintern original. */
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
-}
+ /* Copy attribute for modification. */
+ attr_new.extra = &extra_new;
+ bgp_attr_dup(&attr_new, &attr);
-void
-bgp_redistribute_delete (struct bgp *bgp, struct prefix *p, u_char type, u_short instance)
-{
- afi_t afi;
- struct bgp_node *rn;
- struct bgp_info *ri;
- struct bgp_redist *red;
+ if (red->redist_metric_flag)
+ attr_new.med = red->redist_metric;
- afi = family2afi (p->family);
+ /* Apply route-map. */
+ if (red->rmap.name) {
+ info.peer = bgp->peer_self;
+ info.attr = &attr_new;
- red = bgp_redist_lookup(bgp, afi, type, instance);
- if (red)
- {
- rn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, p, NULL);
-
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self
- && ri->type == type)
- break;
-
- if (ri)
- {
- bgp_aggregate_decrement (bgp, p, ri, afi, SAFI_UNICAST);
- bgp_info_delete (rn, ri);
- bgp_process (bgp, rn, afi, SAFI_UNICAST);
- }
- bgp_unlock_node (rn);
- }
+ SET_FLAG(bgp->peer_self->rmap_type,
+ PEER_RMAP_TYPE_REDISTRIBUTE);
+
+ ret = route_map_apply(red->rmap.map, p, RMAP_BGP,
+ &info);
+
+ bgp->peer_self->rmap_type = 0;
+
+ if (ret == RMAP_DENYMATCH) {
+ /* Free uninterned attribute. */
+ bgp_attr_flush(&attr_new);
+
+ /* Unintern original. */
+ aspath_unintern(&attr.aspath);
+ bgp_attr_extra_free(&attr);
+ bgp_redistribute_delete(bgp, p, type, instance);
+ return;
+ }
+ }
+
+ bn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
+ SAFI_UNICAST, p, NULL);
+
+ new_attr = bgp_attr_intern(&attr_new);
+
+ for (bi = bn->info; bi; bi = bi->next)
+ if (bi->peer == bgp->peer_self
+ && bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
+ break;
+
+ if (bi) {
+ /* Ensure the (source route) type is updated. */
+ bi->type = type;
+ if (attrhash_cmp(bi->attr, new_attr)
+ && !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) {
+ bgp_attr_unintern(&new_attr);
+ aspath_unintern(&attr.aspath);
+ bgp_attr_extra_free(&attr);
+ bgp_unlock_node(bn);
+ return;
+ } else {
+ /* The attribute is changed. */
+ bgp_info_set_flag(bn, bi,
+ BGP_INFO_ATTR_CHANGED);
+
+ /* Rewrite BGP route information. */
+ 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 = bgp_clock();
+
+ /* Process change. */
+ bgp_aggregate_increment(bgp, p, bi, afi,
+ SAFI_UNICAST);
+ bgp_process(bgp, bn, afi, SAFI_UNICAST);
+ bgp_unlock_node(bn);
+ aspath_unintern(&attr.aspath);
+ bgp_attr_extra_free(&attr);
+ return;
+ }
+ }
+
+ new = info_make(type, BGP_ROUTE_REDISTRIBUTE, instance,
+ bgp->peer_self, new_attr, bn);
+ SET_FLAG(new->flags, BGP_INFO_VALID);
+
+ bgp_aggregate_increment(bgp, p, new, afi, SAFI_UNICAST);
+ bgp_info_add(bn, new);
+ bgp_unlock_node(bn);
+ bgp_process(bgp, bn, afi, SAFI_UNICAST);
+ }
+
+ /* Unintern original. */
+ aspath_unintern(&attr.aspath);
+ bgp_attr_extra_free(&attr);
}
-/* Withdraw specified route type's route. */
-void
-bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type, u_short instance)
+void bgp_redistribute_delete(struct bgp *bgp, struct prefix *p, u_char type,
+ u_short instance)
{
- struct bgp_node *rn;
- struct bgp_info *ri;
- struct bgp_table *table;
+ afi_t afi;
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+ struct bgp_redist *red;
- table = bgp->rib[afi][SAFI_UNICAST];
+ afi = family2afi(p->family);
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- {
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self
- && ri->type == type
- && ri->instance == instance)
- break;
-
- if (ri)
- {
- bgp_aggregate_decrement (bgp, &rn->p, ri, afi, SAFI_UNICAST);
- bgp_info_delete (rn, ri);
- bgp_process (bgp, rn, afi, SAFI_UNICAST);
+ red = bgp_redist_lookup(bgp, afi, type, instance);
+ if (red) {
+ rn = bgp_afi_node_get(bgp->rib[afi][SAFI_UNICAST], afi,
+ SAFI_UNICAST, p, NULL);
+
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == bgp->peer_self && ri->type == type)
+ break;
+
+ if (ri) {
+ bgp_aggregate_decrement(bgp, p, ri, afi, SAFI_UNICAST);
+ bgp_info_delete(rn, ri);
+ bgp_process(bgp, rn, afi, SAFI_UNICAST);
+ }
+ bgp_unlock_node(rn);
+ }
+}
+
+/* Withdraw specified route type's route. */
+void bgp_redistribute_withdraw(struct bgp *bgp, afi_t afi, int type,
+ u_short instance)
+{
+ struct bgp_node *rn;
+ struct bgp_info *ri;
+ struct bgp_table *table;
+
+ table = bgp->rib[afi][SAFI_UNICAST];
+
+ for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
+ for (ri = rn->info; ri; ri = ri->next)
+ if (ri->peer == bgp->peer_self && ri->type == type
+ && ri->instance == instance)
+ break;
+
+ if (ri) {
+ bgp_aggregate_decrement(bgp, &rn->p, ri, afi,
+ SAFI_UNICAST);
+ bgp_info_delete(rn, ri);
+ bgp_process(bgp, rn, afi, SAFI_UNICAST);
+ }
}
- }
}
/* Static function to display route. */
-static void
-route_vty_out_route (struct prefix *p, struct vty *vty)
+static void route_vty_out_route(struct prefix *p, struct vty *vty)
{
- int len;
- u_int32_t destination;
- char buf[BUFSIZ];
-
- if (p->family == AF_INET)
- {
- len = vty_out (vty, "%s", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ));
- destination = ntohl (p->u.prefix4.s_addr);
-
- if ((IN_CLASSC (destination) && p->prefixlen == 24)
- || (IN_CLASSB (destination) && p->prefixlen == 16)
- || (IN_CLASSA (destination) && p->prefixlen == 8)
- || p->u.prefix4.s_addr == 0)
- {
- /* When mask is natural, mask is not displayed. */
- }
- else
- len += vty_out (vty, "/%d", p->prefixlen);
- }
- else if (p->family == AF_ETHERNET)
- {
- prefix2str(p, buf, PREFIX_STRLEN);
- len = vty_out (vty, "%s", buf);
- }
- else
- len = vty_out (vty, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ),
- p->prefixlen);
+ int len;
+ u_int32_t destination;
+ char buf[BUFSIZ];
- len = 17 - len;
- if (len < 1)
- vty_out (vty, "%s%*s", VTY_NEWLINE, 20, " ");
- else
- vty_out (vty, "%*s", len, " ");
+ if (p->family == AF_INET) {
+ len = vty_out(vty, "%s",
+ inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ));
+ destination = ntohl(p->u.prefix4.s_addr);
+
+ if ((IN_CLASSC(destination) && p->prefixlen == 24)
+ || (IN_CLASSB(destination) && p->prefixlen == 16)
+ || (IN_CLASSA(destination) && p->prefixlen == 8)
+ || p->u.prefix4.s_addr == 0) {
+ /* When mask is natural, mask is not displayed. */
+ } else
+ len += vty_out(vty, "/%d", p->prefixlen);
+ } else if (p->family == AF_ETHERNET) {
+ prefix2str(p, buf, PREFIX_STRLEN);
+ len = vty_out(vty, "%s", buf);
+ } else
+ len = vty_out(vty, "%s/%d",
+ inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
+ p->prefixlen);
+
+ len = 17 - len;
+ if (len < 1)
+ vty_out(vty, "%s%*s", VTY_NEWLINE, 20, " ");
+ else
+ vty_out(vty, "%*s", len, " ");
}
-enum bgp_display_type
-{
- normal_list,
+enum bgp_display_type {
+ normal_list,
};
/* Print the short form route status for a bgp_info */
-static void
-route_vty_short_status_out (struct vty *vty, struct bgp_info *binfo,
- json_object *json_path)
+static void route_vty_short_status_out(struct vty *vty, struct bgp_info *binfo,
+ json_object *json_path)
{
- if (json_path)
- {
+ if (json_path) {
- /* Route status display. */
- if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
- json_object_boolean_true_add(json_path, "removed");
+ /* Route status display. */
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_REMOVED))
+ json_object_boolean_true_add(json_path, "removed");
- if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
- json_object_boolean_true_add(json_path, "stale");
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_STALE))
+ json_object_boolean_true_add(json_path, "stale");
- if (binfo->extra && binfo->extra->suppress)
- json_object_boolean_true_add(json_path, "suppressed");
+ if (binfo->extra && binfo->extra->suppress)
+ json_object_boolean_true_add(json_path, "suppressed");
- if (CHECK_FLAG (binfo->flags, BGP_INFO_VALID) &&
- ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
- json_object_boolean_true_add(json_path, "valid");
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_VALID)
+ && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
+ json_object_boolean_true_add(json_path, "valid");
- /* Selected */
- if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
- json_object_boolean_true_add(json_path, "history");
+ /* Selected */
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
+ json_object_boolean_true_add(json_path, "history");
- if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
- json_object_boolean_true_add(json_path, "damped");
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED))
+ json_object_boolean_true_add(json_path, "damped");
- if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
- json_object_boolean_true_add(json_path, "bestpath");
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED))
+ json_object_boolean_true_add(json_path, "bestpath");
- if (CHECK_FLAG (binfo->flags, BGP_INFO_MULTIPATH))
- json_object_boolean_true_add(json_path, "multipath");
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_MULTIPATH))
+ json_object_boolean_true_add(json_path, "multipath");
- /* Internal route. */
- if ((binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
- json_object_string_add(json_path, "pathFrom", "internal");
- else
- json_object_string_add(json_path, "pathFrom", "external");
+ /* Internal route. */
+ if ((binfo->peer->as)
+ && (binfo->peer->as == binfo->peer->local_as))
+ json_object_string_add(json_path, "pathFrom",
+ "internal");
+ else
+ json_object_string_add(json_path, "pathFrom",
+ "external");
- return;
- }
+ return;
+ }
- /* Route status display. */
- if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
- vty_out (vty, "R");
- else if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
- vty_out (vty, "S");
- else if (binfo->extra && binfo->extra->suppress)
- vty_out (vty, "s");
- else if (CHECK_FLAG (binfo->flags, BGP_INFO_VALID) &&
- ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
- vty_out (vty, "*");
- else
- vty_out (vty, " ");
-
- /* Selected */
- if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
- vty_out (vty, "h");
- else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
- vty_out (vty, "d");
- else if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
- vty_out (vty, ">");
- else if (CHECK_FLAG (binfo->flags, BGP_INFO_MULTIPATH))
- vty_out (vty, "=");
- else
- vty_out (vty, " ");
+ /* Route status display. */
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_REMOVED))
+ vty_out(vty, "R");
+ else if (CHECK_FLAG(binfo->flags, BGP_INFO_STALE))
+ vty_out(vty, "S");
+ else if (binfo->extra && binfo->extra->suppress)
+ vty_out(vty, "s");
+ else if (CHECK_FLAG(binfo->flags, BGP_INFO_VALID)
+ && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
+ vty_out(vty, "*");
+ else
+ vty_out(vty, " ");
+
+ /* Selected */
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY))
+ vty_out(vty, "h");
+ else if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED))
+ vty_out(vty, "d");
+ else if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED))
+ vty_out(vty, ">");
+ else if (CHECK_FLAG(binfo->flags, BGP_INFO_MULTIPATH))
+ vty_out(vty, "=");
+ else
+ vty_out(vty, " ");
- /* Internal route. */
- if (binfo->peer &&
- (binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
- vty_out (vty, "i");
- else
- vty_out (vty, " ");
+ /* Internal route. */
+ if (binfo->peer && (binfo->peer->as)
+ && (binfo->peer->as == binfo->peer->local_as))
+ vty_out(vty, "i");
+ else
+ vty_out(vty, " ");
}
/* called from terminal list command */
-void
-route_vty_out (struct vty *vty, struct prefix *p,
- struct bgp_info *binfo, int display, safi_t safi,
- json_object *json_paths)
-{
- struct attr *attr;
- json_object *json_path = NULL;
- json_object *json_nexthops = NULL;
- json_object *json_nexthop_global = NULL;
- json_object *json_nexthop_ll = NULL;
-
- if (json_paths)
- json_path = json_object_new_object();
-
- /* short status lead text */
- route_vty_short_status_out (vty, binfo, json_path);
+void route_vty_out(struct vty *vty, struct prefix *p, struct bgp_info *binfo,
+ int display, safi_t safi, json_object *json_paths)
+{
+ struct attr *attr;
+ json_object *json_path = NULL;
+ json_object *json_nexthops = NULL;
+ json_object *json_nexthop_global = NULL;
+ json_object *json_nexthop_ll = NULL;
+
+ if (json_paths)
+ json_path = json_object_new_object();
+
+ /* short status lead text */
+ route_vty_short_status_out(vty, binfo, json_path);
+
+ if (!json_paths) {
+ /* print prefix and mask */
+ if (!display)
+ route_vty_out_route(p, vty);
+ else
+ vty_out(vty, "%*s", 17, " ");
+ }
- if (!json_paths)
- {
- /* print prefix and mask */
- if (! display)
- route_vty_out_route (p, vty);
- else
- vty_out (vty, "%*s", 17, " ");
- }
+ /* Print attribute */
+ attr = binfo->attr;
+ if (attr) {
+ /*
+ * For ENCAP routes, nexthop address family is not
+ * neccessarily the same as the prefix address family.
+ * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
+ */
+ if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN)
+ || (safi == SAFI_EVPN)) {
+ if (attr->extra) {
+ char buf[BUFSIZ];
+ int af = NEXTHOP_FAMILY(
+ attr->extra->mp_nexthop_len);
+
+ switch (af) {
+ case AF_INET:
+ vty_out(vty, "%s",
+ inet_ntop(
+ af,
+ &attr->extra
+ ->mp_nexthop_global_in,
+ buf, BUFSIZ));
+ break;
+ case AF_INET6:
+ vty_out(vty, "%s",
+ inet_ntop(
+ af,
+ &attr->extra
+ ->mp_nexthop_global,
+ buf, BUFSIZ));
+ break;
+ default:
+ vty_out(vty, "?");
+ break;
+ }
+ } else
+ vty_out(vty, "?");
+ }
+ /* IPv4 Next Hop */
+ else if (p->family == AF_INET
+ && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+ if (json_paths) {
+ json_nexthop_global = json_object_new_object();
+
+ if ((safi == SAFI_MPLS_VPN)
+ || (safi == SAFI_EVPN))
+ json_object_string_add(
+ json_nexthop_global, "ip",
+ inet_ntoa(
+ attr->extra
+ ->mp_nexthop_global_in));
+ else
+ json_object_string_add(
+ json_nexthop_global, "ip",
+ inet_ntoa(attr->nexthop));
+
+ json_object_string_add(json_nexthop_global,
+ "afi", "ipv4");
+ json_object_boolean_true_add(
+ json_nexthop_global, "used");
+ } else {
+ if ((safi == SAFI_MPLS_VPN)
+ || (safi == SAFI_EVPN))
+ vty_out(vty, "%-16s",
+ inet_ntoa(
+ attr->extra
+ ->mp_nexthop_global_in));
+ else
+ vty_out(vty, "%-16s",
+ inet_ntoa(attr->nexthop));
+ }
+ }
- /* Print attribute */
- attr = binfo->attr;
- if (attr)
- {
- /*
- * For ENCAP routes, nexthop address family is not
- * neccessarily the same as the prefix address family.
- * Both SAFI_MPLS_VPN and SAFI_ENCAP use the MP nexthop field
- */
- if ((safi == SAFI_ENCAP) || (safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
- {
- if (attr->extra)
- {
- char buf[BUFSIZ];
- int af = NEXTHOP_FAMILY(attr->extra->mp_nexthop_len);
-
- switch (af)
- {
- case AF_INET:
- vty_out (vty, "%s", inet_ntop(af,
- &attr->extra->mp_nexthop_global_in, buf, BUFSIZ));
- break;
- case AF_INET6:
- vty_out (vty, "%s", inet_ntop(af,
- &attr->extra->mp_nexthop_global, buf, BUFSIZ));
- break;
- default:
- vty_out(vty, "?");
- break;
- }
- }
- else
- vty_out(vty, "?");
- }
- /* IPv4 Next Hop */
- else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
- {
- if (json_paths)
- {
- json_nexthop_global = json_object_new_object();
-
- if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
- json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->extra->mp_nexthop_global_in));
- else
- json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->nexthop));
-
- json_object_string_add(json_nexthop_global, "afi", "ipv4");
- json_object_boolean_true_add(json_nexthop_global, "used");
- }
- else
- {
- if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN))
- vty_out (vty, "%-16s",
- inet_ntoa (attr->extra->mp_nexthop_global_in));
- else
- vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
- }
- }
-
- /* IPv6 Next Hop */
- else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
- {
- int len;
- char buf[BUFSIZ];
-
- if (json_paths)
- {
- json_nexthop_global = json_object_new_object();
- json_object_string_add(json_nexthop_global, "ip",
- inet_ntop (AF_INET6,
- &attr->extra->mp_nexthop_global,
- buf, BUFSIZ));
- json_object_string_add(json_nexthop_global, "afi", "ipv6");
- json_object_string_add(json_nexthop_global, "scope", "global");
-
- /* We display both LL & GL if both have been received */
- if ((attr->extra->mp_nexthop_len == 32) || (binfo->peer->conf_if))
- {
- json_nexthop_ll = json_object_new_object();
- json_object_string_add(json_nexthop_ll, "ip",
- inet_ntop (AF_INET6,
- &attr->extra->mp_nexthop_local,
- buf, BUFSIZ));
- json_object_string_add(json_nexthop_ll, "afi", "ipv6");
- json_object_string_add(json_nexthop_ll, "scope", "link-local");
-
- if ((IPV6_ADDR_CMP (&attr->extra->mp_nexthop_global,
- &attr->extra->mp_nexthop_local) != 0) &&
- !attr->extra->mp_nexthop_prefer_global)
- json_object_boolean_true_add(json_nexthop_ll, "used");
- else
- json_object_boolean_true_add(json_nexthop_global, "used");
- }
- else
- json_object_boolean_true_add(json_nexthop_global, "used");
- }
- else
- {
- /* Display LL if LL/Global both in table unless prefer-global is set */
- if (((attr->extra->mp_nexthop_len == 32) &&
- !attr->extra->mp_nexthop_prefer_global) ||
- (binfo->peer->conf_if))
- {
- if (binfo->peer->conf_if)
- {
- len = vty_out (vty, "%s",
- binfo->peer->conf_if);
- len = 7 - len; /* len of IPv6 addr + max len of def ifname */
-
- if (len < 1)
- vty_out (vty, "%s%*s", VTY_NEWLINE, 45, " ");
- else
- vty_out (vty, "%*s", len, " ");
- }
- else
- {
- len = vty_out (vty, "%s",
- inet_ntop (AF_INET6,
- &attr->extra->mp_nexthop_local,
+ /* IPv6 Next Hop */
+ else if (p->family == AF_INET6
+ || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+ int len;
+ char buf[BUFSIZ];
+
+ if (json_paths) {
+ json_nexthop_global = json_object_new_object();
+ json_object_string_add(
+ json_nexthop_global, "ip",
+ inet_ntop(
+ AF_INET6,
+ &attr->extra->mp_nexthop_global,
buf, BUFSIZ));
- len = 16 - len;
+ json_object_string_add(json_nexthop_global,
+ "afi", "ipv6");
+ json_object_string_add(json_nexthop_global,
+ "scope", "global");
+
+ /* We display both LL & GL if both have been
+ * received */
+ if ((attr->extra->mp_nexthop_len == 32)
+ || (binfo->peer->conf_if)) {
+ json_nexthop_ll =
+ json_object_new_object();
+ json_object_string_add(
+ json_nexthop_ll, "ip",
+ inet_ntop(
+ AF_INET6,
+ &attr->extra
+ ->mp_nexthop_local,
+ buf, BUFSIZ));
+ json_object_string_add(json_nexthop_ll,
+ "afi", "ipv6");
+ json_object_string_add(json_nexthop_ll,
+ "scope",
+ "link-local");
+
+ if ((IPV6_ADDR_CMP(
+ &attr->extra
+ ->mp_nexthop_global,
+ &attr->extra
+ ->mp_nexthop_local)
+ != 0)
+ && !attr->extra
+ ->mp_nexthop_prefer_global)
+ json_object_boolean_true_add(
+ json_nexthop_ll,
+ "used");
+ else
+ json_object_boolean_true_add(
+ json_nexthop_global,
+ "used");
+ } else
+ json_object_boolean_true_add(
+ json_nexthop_global, "used");
+ } else {
+ /* Display LL if LL/Global both in table unless
+ * prefer-global is set */
+ if (((attr->extra->mp_nexthop_len == 32)
+ && !attr->extra->mp_nexthop_prefer_global)
+ || (binfo->peer->conf_if)) {
+ if (binfo->peer->conf_if) {
+ len = vty_out(
+ vty, "%s",
+ binfo->peer->conf_if);
+ len =
+ 7 - len; /* len of IPv6
+ addr + max
+ len of def
+ ifname */
+
+ if (len < 1)
+ vty_out(vty, "%s%*s",
+ VTY_NEWLINE, 45,
+ " ");
+ else
+ vty_out(vty, "%*s", len,
+ " ");
+ } else {
+ len = vty_out(
+ vty, "%s",
+ inet_ntop(
+ AF_INET6,
+ &attr->extra
+ ->mp_nexthop_local,
+ buf, BUFSIZ));
+ len = 16 - len;
+
+ if (len < 1)
+ vty_out(vty, "%s%*s",
+ VTY_NEWLINE, 36,
+ " ");
+ else
+ vty_out(vty, "%*s", len,
+ " ");
+ }
+ } else {
+ len = vty_out(
+ vty, "%s",
+ inet_ntop(
+ AF_INET6,
+ &attr->extra
+ ->mp_nexthop_global,
+ buf, BUFSIZ));
+ len = 16 - len;
+
+ if (len < 1)
+ vty_out(vty, "%s%*s",
+ VTY_NEWLINE, 36, " ");
+ else
+ vty_out(vty, "%*s", len, " ");
+ }
+ }
+ }
- if (len < 1)
- vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
- else
- vty_out (vty, "%*s", len, " ");
- }
+ /* MED/Metric */
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
+ if (json_paths)
+ json_object_int_add(json_path, "med",
+ attr->med);
+ else
+ vty_out(vty, "%10u", attr->med);
+ else if (!json_paths)
+ vty_out(vty, " ");
+
+ /* Local Pref */
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
+ if (json_paths)
+ json_object_int_add(json_path, "localpref",
+ attr->local_pref);
+ else
+ vty_out(vty, "%7u", attr->local_pref);
+ else if (!json_paths)
+ vty_out(vty, " ");
+
+ if (json_paths) {
+ if (attr->extra)
+ json_object_int_add(json_path, "weight",
+ attr->extra->weight);
+ else
+ json_object_int_add(json_path, "weight", 0);
+ } else
+ vty_out(vty, "%7u ",
+ (attr->extra ? attr->extra->weight : 0));
+
+ if (json_paths) {
+ char buf[BUFSIZ];
+ json_object_string_add(json_path, "peerId",
+ sockunion2str(&binfo->peer->su,
+ buf,
+ SU_ADDRSTRLEN));
}
- else
- {
- len = vty_out (vty, "%s",
- inet_ntop (AF_INET6,
- &attr->extra->mp_nexthop_global,
- buf, BUFSIZ));
- len = 16 - len;
-
- if (len < 1)
- vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
- else
- vty_out (vty, "%*s", len, " ");
- }
- }
- }
-
- /* MED/Metric */
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
- if (json_paths)
- json_object_int_add(json_path, "med", attr->med);
- else
- vty_out (vty, "%10u", attr->med);
- else
- if (!json_paths)
- vty_out (vty, " ");
-
- /* Local Pref */
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
- if (json_paths)
- json_object_int_add(json_path, "localpref", attr->local_pref);
- else
- vty_out (vty, "%7u", attr->local_pref);
- else
- if (!json_paths)
- vty_out (vty, " ");
-
- if (json_paths)
- {
- if (attr->extra)
- json_object_int_add(json_path, "weight", attr->extra->weight);
- else
- json_object_int_add(json_path, "weight", 0);
- }
- else
- vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
-
- if (json_paths) {
- char buf[BUFSIZ];
- json_object_string_add(json_path, "peerId", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
- }
-
- /* Print aspath */
- if (attr->aspath)
- {
- if (json_paths)
- json_object_string_add(json_path, "aspath", attr->aspath->str);
- else
- aspath_print_vty (vty, "%s", attr->aspath, " ");
- }
-
- /* Print origin */
- if (json_paths)
- json_object_string_add(json_path, "origin", bgp_origin_long_str[attr->origin]);
- else
- vty_out (vty, "%s", bgp_origin_str[attr->origin]);
- }
- else
- {
- if (json_paths)
- json_object_string_add(json_path, "alert", "No attributes");
- else
- vty_out (vty, "No attributes to print%s", VTY_NEWLINE);
- }
- if (json_paths)
- {
- if (json_nexthop_global || json_nexthop_ll)
- {
- json_nexthops = json_object_new_array();
+ /* Print aspath */
+ if (attr->aspath) {
+ if (json_paths)
+ json_object_string_add(json_path, "aspath",
+ attr->aspath->str);
+ else
+ aspath_print_vty(vty, "%s", attr->aspath, " ");
+ }
- if (json_nexthop_global)
- json_object_array_add(json_nexthops, json_nexthop_global);
+ /* Print origin */
+ if (json_paths)
+ json_object_string_add(
+ json_path, "origin",
+ bgp_origin_long_str[attr->origin]);
+ else
+ vty_out(vty, "%s", bgp_origin_str[attr->origin]);
+ } else {
+ if (json_paths)
+ json_object_string_add(json_path, "alert",
+ "No attributes");
+ else
+ vty_out(vty, "No attributes to print%s", VTY_NEWLINE);
+ }
- if (json_nexthop_ll)
- json_object_array_add(json_nexthops, json_nexthop_ll);
+ if (json_paths) {
+ if (json_nexthop_global || json_nexthop_ll) {
+ json_nexthops = json_object_new_array();
- json_object_object_add(json_path, "nexthops", json_nexthops);
- }
+ if (json_nexthop_global)
+ json_object_array_add(json_nexthops,
+ json_nexthop_global);
- json_object_array_add(json_paths, json_path);
- }
- else
- {
- vty_out (vty, "%s", VTY_NEWLINE);
+ if (json_nexthop_ll)
+ json_object_array_add(json_nexthops,
+ json_nexthop_ll);
+
+ json_object_object_add(json_path, "nexthops",
+ json_nexthops);
+ }
+
+ json_object_array_add(json_paths, json_path);
+ } else {
+ vty_out(vty, "%s", VTY_NEWLINE);
#if ENABLE_BGP_VNC
- /* prints an additional line, indented, with VNC info, if present */
- if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
- rfapi_vty_out_vncinfo(vty, p, binfo, safi);
+ /* prints an additional line, indented, with VNC info, if
+ * present */
+ if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
+ rfapi_vty_out_vncinfo(vty, p, binfo, safi);
#endif
- }
-}
+ }
+}
/* called from terminal list command */
-void
-route_vty_out_tmp (struct vty *vty, struct prefix *p, struct attr *attr, safi_t safi,
- u_char use_json, json_object *json_ar)
-{
- json_object *json_status = NULL;
- json_object *json_net = NULL;
- char buff[BUFSIZ];
- /* Route status display. */
- if (use_json)
- {
- json_status = json_object_new_object();
- json_net = json_object_new_object();
- }
- else
- {
- vty_out (vty, "*");
- vty_out (vty, ">");
- vty_out (vty, " ");
- }
+void route_vty_out_tmp(struct vty *vty, struct prefix *p, struct attr *attr,
+ safi_t safi, u_char use_json, json_object *json_ar)
+{
+ json_object *json_status = NULL;
+ json_object *json_net = NULL;
+ char buff[BUFSIZ];
+ /* Route status display. */
+ if (use_json) {
+ json_status = json_object_new_object();
+ json_net = json_object_new_object();
+ } else {
+ vty_out(vty, "*");
+ vty_out(vty, ">");
+ vty_out(vty, " ");
+ }
- /* print prefix and mask */
- if (use_json)
- json_object_string_add(json_net, "addrPrefix", inet_ntop (p->family, &p->u.prefix, buff, BUFSIZ));
- else
- route_vty_out_route (p, vty);
+ /* print prefix and mask */
+ if (use_json)
+ json_object_string_add(
+ json_net, "addrPrefix",
+ inet_ntop(p->family, &p->u.prefix, buff, BUFSIZ));
+ else
+ route_vty_out_route(p, vty);
+
+ /* Print attribute */
+ if (attr) {
+ if (use_json) {
+ if (p->family == AF_INET
+ && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
+ || safi == SAFI_EVPN
+ || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
+ || safi == SAFI_EVPN)
+ json_object_string_add(
+ json_net, "nextHop",
+ inet_ntoa(
+ attr->extra
+ ->mp_nexthop_global_in));
+ else
+ json_object_string_add(
+ json_net, "nextHop",
+ inet_ntoa(attr->nexthop));
+ } else if (p->family == AF_INET6
+ || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+ char buf[BUFSIZ];
+
+ json_object_string_add(
+ json_net, "netHopGloabal",
+ inet_ntop(
+ AF_INET6,
+ &attr->extra->mp_nexthop_global,
+ buf, BUFSIZ));
+ }
- /* Print attribute */
- if (attr)
- {
- if (use_json)
- {
- if (p->family == AF_INET &&
- (safi == SAFI_MPLS_VPN ||
- safi == SAFI_ENCAP ||
- safi == SAFI_EVPN ||
- !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
- {
- if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
- json_object_string_add(json_net, "nextHop", inet_ntoa (attr->extra->mp_nexthop_global_in));
- else
- json_object_string_add(json_net, "nextHop", inet_ntoa (attr->nexthop));
- }
- else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
- {
- char buf[BUFSIZ];
-
- json_object_string_add(json_net, "netHopGloabal", inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
- buf, BUFSIZ));
- }
-
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
- json_object_int_add(json_net, "metric", attr->med);
-
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
- json_object_int_add(json_net, "localPref", attr->local_pref);
-
- if (attr->extra)
- json_object_int_add(json_net, "weight", attr->extra->weight);
- else
- json_object_int_add(json_net, "weight", 0);
-
- /* Print aspath */
- if (attr->aspath)
- json_object_string_add(json_net, "asPath", attr->aspath->str);
-
- /* Print origin */
- json_object_string_add(json_net, "bgpOriginCode", bgp_origin_str[attr->origin]);
- }
- else
- {
- if (p->family == AF_INET &&
- (safi == SAFI_MPLS_VPN ||
- safi == SAFI_ENCAP ||
- safi == SAFI_EVPN ||
- !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
- {
- if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
- vty_out (vty, "%-16s",
- inet_ntoa (attr->extra->mp_nexthop_global_in));
- else
- vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
- }
- else if (p->family == AF_INET6 || BGP_ATTR_NEXTHOP_AFI_IP6(attr))
- {
- int len;
- char buf[BUFSIZ];
-
- assert (attr->extra);
-
- len = vty_out (vty, "%s",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
- buf, BUFSIZ));
- len = 16 - len;
- if (len < 1)
- vty_out (vty, "%s%*s", VTY_NEWLINE, 36, " ");
- else
- vty_out (vty, "%*s", len, " ");
- }
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
- vty_out (vty, "%10u", attr->med);
- else
- vty_out (vty, " ");
-
- if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))
- vty_out (vty, "%7u", attr->local_pref);
- else
- vty_out (vty, " ");
-
- vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
-
- /* Print aspath */
- if (attr->aspath)
- aspath_print_vty (vty, "%s", attr->aspath, " ");
-
- /* Print origin */
- vty_out (vty, "%s", bgp_origin_str[attr->origin]);
- }
- }
- if (use_json)
- {
- json_object_boolean_true_add(json_status, "*");
- json_object_boolean_true_add(json_status, ">");
- json_object_object_add(json_net, "appliedStatusSymbols", json_status);
- char buf_cut[BUFSIZ];
- json_object_object_add(json_ar, inet_ntop (p->family, &p->u.prefix, buf_cut, BUFSIZ), json_net);
- }
- else
- vty_out (vty, "%s", VTY_NEWLINE);
-}
+ if (attr->flag
+ & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
+ json_object_int_add(json_net, "metric",
+ attr->med);
-void
-route_vty_out_tag (struct vty *vty, struct prefix *p,
- struct bgp_info *binfo, int display, safi_t safi, json_object *json)
-{
- json_object *json_out = NULL;
- struct attr *attr;
- u_int32_t label = 0;
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
+ json_object_int_add(json_net, "localPref",
+ attr->local_pref);
- if (!binfo->extra)
- return;
+ if (attr->extra)
+ json_object_int_add(json_net, "weight",
+ attr->extra->weight);
+ else
+ json_object_int_add(json_net, "weight", 0);
+
+ /* Print aspath */
+ if (attr->aspath)
+ json_object_string_add(json_net, "asPath",
+ attr->aspath->str);
+
+ /* Print origin */
+ json_object_string_add(json_net, "bgpOriginCode",
+ bgp_origin_str[attr->origin]);
+ } else {
+ if (p->family == AF_INET
+ && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
+ || safi == SAFI_EVPN
+ || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
+ || safi == SAFI_EVPN)
+ vty_out(vty, "%-16s",
+ inet_ntoa(
+ attr->extra
+ ->mp_nexthop_global_in));
+ else
+ vty_out(vty, "%-16s",
+ inet_ntoa(attr->nexthop));
+ } else if (p->family == AF_INET6
+ || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+ int len;
+ char buf[BUFSIZ];
+
+ assert(attr->extra);
+
+ len = vty_out(
+ vty, "%s",
+ inet_ntop(
+ AF_INET6,
+ &attr->extra->mp_nexthop_global,
+ buf, BUFSIZ));
+ len = 16 - len;
+ if (len < 1)
+ vty_out(vty, "%s%*s", VTY_NEWLINE, 36,
+ " ");
+ else
+ vty_out(vty, "%*s", len, " ");
+ }
+ if (attr->flag
+ & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
+ vty_out(vty, "%10u", attr->med);
+ else
+ vty_out(vty, " ");
- if (json)
- json_out = json_object_new_object();
-
- /* short status lead text */
- route_vty_short_status_out (vty, binfo, json_out);
-
- /* print prefix and mask */
- if (json == NULL)
- {
- if (! display)
- route_vty_out_route (p, vty);
- else
- vty_out (vty, "%*s", 17, " ");
- }
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
+ vty_out(vty, "%7u", attr->local_pref);
+ else
+ vty_out(vty, " ");
- /* Print attribute */
- attr = binfo->attr;
- if (attr)
- {
- if (((p->family == AF_INET) && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
- || (safi == SAFI_EVPN && p->family == AF_ETHERNET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
- || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
- {
- if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
- {
- if (json)
- json_object_string_add(json_out, "mpNexthopGlobalIn", inet_ntoa (attr->extra->mp_nexthop_global_in));
- else
- vty_out (vty, "%-16s", inet_ntoa (attr->extra->mp_nexthop_global_in));
- }
- else
- {
- if (json)
- json_object_string_add(json_out, "nexthop", inet_ntoa (attr->nexthop));
- else
- vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
- }
- }
- else if (((p->family == AF_INET6) && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
- || (safi == SAFI_EVPN && p->family == AF_ETHERNET && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
- || (BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
- {
- assert (attr->extra);
- char buf_a[BUFSIZ];
- char buf_b[BUFSIZ];
- char buf_c[BUFSIZ];
- if (attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL)
- {
- if (json)
- json_object_string_add(json_out, "mpNexthopGlobalIn",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global, buf_a, BUFSIZ));
- else
- vty_out (vty, "%s",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
- buf_a, BUFSIZ));
- }
- else if (attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
- {
- if (json)
- {
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
- buf_a, BUFSIZ);
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
- buf_b, BUFSIZ);
- sprintf(buf_c, "%s(%s)", buf_a, buf_b);
- json_object_string_add(json_out, "mpNexthopGlobalLocal", buf_c);
- }
- else
- vty_out (vty, "%s(%s)",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
- buf_a, BUFSIZ),
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
- buf_b, BUFSIZ));
- }
+ vty_out(vty, "%7u ",
+ (attr->extra ? attr->extra->weight : 0));
+
+ /* Print aspath */
+ if (attr->aspath)
+ aspath_print_vty(vty, "%s", attr->aspath, " ");
+ /* Print origin */
+ vty_out(vty, "%s", bgp_origin_str[attr->origin]);
+ }
}
- }
+ if (use_json) {
+ json_object_boolean_true_add(json_status, "*");
+ json_object_boolean_true_add(json_status, ">");
+ json_object_object_add(json_net, "appliedStatusSymbols",
+ json_status);
+ char buf_cut[BUFSIZ];
+ json_object_object_add(
+ json_ar,
+ inet_ntop(p->family, &p->u.prefix, buf_cut, BUFSIZ),
+ json_net);
+ } else
+ vty_out(vty, "%s", VTY_NEWLINE);
+}
+
+void route_vty_out_tag(struct vty *vty, struct prefix *p,
+ struct bgp_info *binfo, int display, safi_t safi,
+ json_object *json)
+{
+ json_object *json_out = NULL;
+ struct attr *attr;
+ u_int32_t label = 0;
+
+ if (!binfo->extra)
+ return;
- label = decode_label (binfo->extra->tag);
+ if (json)
+ json_out = json_object_new_object();
- if (json)
- {
- if (label)
- json_object_int_add(json_out, "notag", label);
- json_object_array_add(json, json_out);
- }
- else
- {
- vty_out (vty, "notag/%d", label);
+ /* short status lead text */
+ route_vty_short_status_out(vty, binfo, json_out);
- vty_out (vty, "%s", VTY_NEWLINE);
- }
-}
+ /* print prefix and mask */
+ if (json == NULL) {
+ if (!display)
+ route_vty_out_route(p, vty);
+ else
+ vty_out(vty, "%*s", 17, " ");
+ }
-void
-route_vty_out_overlay (struct vty *vty, struct prefix *p,
- struct bgp_info *binfo, int display, json_object *json_paths)
-{
- struct attr *attr;
- char buf[BUFSIZ];
- json_object *json_path = NULL;
+ /* Print attribute */
+ attr = binfo->attr;
+ if (attr) {
+ if (((p->family == AF_INET)
+ && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
+ || (safi == SAFI_EVPN && p->family == AF_ETHERNET
+ && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
+ || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
+ || safi == SAFI_EVPN) {
+ if (json)
+ json_object_string_add(
+ json_out, "mpNexthopGlobalIn",
+ inet_ntoa(
+ attr->extra
+ ->mp_nexthop_global_in));
+ else
+ vty_out(vty, "%-16s",
+ inet_ntoa(
+ attr->extra
+ ->mp_nexthop_global_in));
+ } else {
+ if (json)
+ json_object_string_add(
+ json_out, "nexthop",
+ inet_ntoa(attr->nexthop));
+ else
+ vty_out(vty, "%-16s",
+ inet_ntoa(attr->nexthop));
+ }
+ } else if (((p->family == AF_INET6)
+ && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
+ || (safi == SAFI_EVPN && p->family == AF_ETHERNET
+ && BGP_ATTR_NEXTHOP_AFI_IP6(attr))
+ || (BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+ assert(attr->extra);
+ char buf_a[BUFSIZ];
+ char buf_b[BUFSIZ];
+ char buf_c[BUFSIZ];
+ if (attr->extra->mp_nexthop_len
+ == BGP_ATTR_NHLEN_IPV6_GLOBAL) {
+ if (json)
+ json_object_string_add(
+ json_out, "mpNexthopGlobalIn",
+ inet_ntop(
+ AF_INET6,
+ &attr->extra
+ ->mp_nexthop_global,
+ buf_a, BUFSIZ));
+ else
+ vty_out(vty, "%s",
+ inet_ntop(
+ AF_INET6,
+ &attr->extra
+ ->mp_nexthop_global,
+ buf_a, BUFSIZ));
+ } else if (attr->extra->mp_nexthop_len
+ == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
+ if (json) {
+ inet_ntop(
+ AF_INET6,
+ &attr->extra->mp_nexthop_global,
+ buf_a, BUFSIZ);
+ inet_ntop(
+ AF_INET6,
+ &attr->extra->mp_nexthop_local,
+ buf_b, BUFSIZ);
+ sprintf(buf_c, "%s(%s)", buf_a, buf_b);
+ json_object_string_add(
+ json_out,
+ "mpNexthopGlobalLocal", buf_c);
+ } else
+ vty_out(vty, "%s(%s)",
+ inet_ntop(
+ AF_INET6,
+ &attr->extra
+ ->mp_nexthop_global,
+ buf_a, BUFSIZ),
+ inet_ntop(
+ AF_INET6,
+ &attr->extra
+ ->mp_nexthop_local,
+ buf_b, BUFSIZ));
+ }
+ }
+ }
- if (json_paths)
- json_path = json_object_new_object();
+ label = decode_label(binfo->extra->tag);
- if (!binfo->extra)
- return;
+ if (json) {
+ if (label)
+ json_object_int_add(json_out, "notag", label);
+ json_object_array_add(json, json_out);
+ } else {
+ vty_out(vty, "notag/%d", label);
- /* short status lead text */
- route_vty_short_status_out (vty, binfo, json_path);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+}
- /* print prefix and mask */
- if (! display)
- route_vty_out_route (p, vty);
- else
- vty_out (vty, "%*s", 17, " ");
+void route_vty_out_overlay(struct vty *vty, struct prefix *p,
+ struct bgp_info *binfo, int display,
+ json_object *json_paths)
+{
+ struct attr *attr;
+ char buf[BUFSIZ];
+ json_object *json_path = NULL;
- /* Print attribute */
- attr = binfo->attr;
- if (attr)
- {
- if (attr->extra)
- {
- char buf1[BUFSIZ];
- int af = NEXTHOP_FAMILY(attr->extra->mp_nexthop_len);
-
- switch (af) {
- case AF_INET:
- vty_out (vty, "%-16s", inet_ntop(af,
- &attr->extra->mp_nexthop_global_in, buf, BUFSIZ));
- break;
- case AF_INET6:
- vty_out (vty, "%s(%s)",
- inet_ntop (af,
- &attr->extra->mp_nexthop_global, buf, BUFSIZ),
- inet_ntop (af,
- &attr->extra->mp_nexthop_local, buf1, BUFSIZ));
- break;
- default:
- vty_out(vty, "?");
- }
- } else {
- vty_out(vty, "?");
- }
- }
+ if (json_paths)
+ json_path = json_object_new_object();
- if(attr->extra)
- {
- struct eth_segment_id *id = &(attr->extra->evpn_overlay.eth_s_id);
- char *str = esi2str(id);
- vty_out (vty, "%s", str);
- XFREE (MTYPE_TMP, str);
- if (p->u.prefix_evpn.flags & IP_PREFIX_V4)
- {
- vty_out (vty, "/%s", inet_ntoa (attr->extra->evpn_overlay.gw_ip.ipv4));
- }
- else if (p->u.prefix_evpn.flags & IP_PREFIX_V6)
- {
- vty_out (vty, "/%s",
- inet_ntop (AF_INET6, &(attr->extra->evpn_overlay.gw_ip.ipv6),
- buf, BUFSIZ));
- }
- if(attr->extra->ecommunity)
- {
- char *mac = NULL;
- struct ecommunity_val *routermac = ecommunity_lookup (attr->extra->ecommunity,
- ECOMMUNITY_ENCODE_EVPN,
- ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
- if(routermac)
- mac = ecom_mac2str((char *)routermac->val);
- if(mac)
- {
- vty_out (vty, "/%s",(char *)mac);
- XFREE(MTYPE_TMP, mac);
- }
- }
- }
- vty_out (vty, "%s", VTY_NEWLINE);
+ if (!binfo->extra)
+ return;
+
+ /* short status lead text */
+ route_vty_short_status_out(vty, binfo, json_path);
+
+ /* print prefix and mask */
+ if (!display)
+ route_vty_out_route(p, vty);
+ else
+ vty_out(vty, "%*s", 17, " ");
+
+ /* Print attribute */
+ attr = binfo->attr;
+ if (attr) {
+ if (attr->extra) {
+ char buf1[BUFSIZ];
+ int af = NEXTHOP_FAMILY(attr->extra->mp_nexthop_len);
+
+ switch (af) {
+ case AF_INET:
+ vty_out(vty, "%-16s",
+ inet_ntop(
+ af,
+ &attr->extra
+ ->mp_nexthop_global_in,
+ buf, BUFSIZ));
+ break;
+ case AF_INET6:
+ vty_out(vty, "%s(%s)",
+ inet_ntop(
+ af,
+ &attr->extra->mp_nexthop_global,
+ buf, BUFSIZ),
+ inet_ntop(
+ af,
+ &attr->extra->mp_nexthop_local,
+ buf1, BUFSIZ));
+ break;
+ default:
+ vty_out(vty, "?");
+ }
+ } else {
+ vty_out(vty, "?");
+ }
+ }
+
+ if (attr->extra) {
+ struct eth_segment_id *id =
+ &(attr->extra->evpn_overlay.eth_s_id);
+ char *str = esi2str(id);
+ vty_out(vty, "%s", str);
+ XFREE(MTYPE_TMP, str);
+ if (p->u.prefix_evpn.flags & IP_PREFIX_V4) {
+ vty_out(vty, "/%s",
+ inet_ntoa(
+ attr->extra->evpn_overlay.gw_ip.ipv4));
+ } else if (p->u.prefix_evpn.flags & IP_PREFIX_V6) {
+ vty_out(vty, "/%s",
+ inet_ntop(
+ AF_INET6,
+ &(attr->extra->evpn_overlay.gw_ip.ipv6),
+ buf, BUFSIZ));
+ }
+ if (attr->extra->ecommunity) {
+ char *mac = NULL;
+ struct ecommunity_val *routermac = ecommunity_lookup(
+ attr->extra->ecommunity, ECOMMUNITY_ENCODE_EVPN,
+ ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC);
+ if (routermac)
+ mac = ecom_mac2str((char *)routermac->val);
+ if (mac) {
+ vty_out(vty, "/%s", (char *)mac);
+ XFREE(MTYPE_TMP, mac);
+ }
+ }
+ }
+ vty_out(vty, "%s", VTY_NEWLINE);
}
/* dampening route */
-static void
-damp_route_vty_out (struct vty *vty, struct prefix *p, struct bgp_info *binfo,
- int display, safi_t safi, u_char use_json, json_object *json)
-{
- struct attr *attr;
- int len;
- char timebuf[BGP_UPTIME_LEN];
-
- /* short status lead text */
- route_vty_short_status_out (vty, binfo, json);
-
- /* print prefix and mask */
- if (!use_json)
- {
- if (! display)
- route_vty_out_route (p, vty);
- else
- vty_out (vty, "%*s", 17, " ");
- }
+static void damp_route_vty_out(struct vty *vty, struct prefix *p,
+ struct bgp_info *binfo, int display, safi_t safi,
+ u_char use_json, json_object *json)
+{
+ struct attr *attr;
+ int len;
+ char timebuf[BGP_UPTIME_LEN];
+
+ /* short status lead text */
+ route_vty_short_status_out(vty, binfo, json);
+
+ /* print prefix and mask */
+ if (!use_json) {
+ if (!display)
+ route_vty_out_route(p, vty);
+ else
+ vty_out(vty, "%*s", 17, " ");
+ }
- len = vty_out (vty, "%s", binfo->peer->host);
- len = 17 - len;
- if (len < 1)
- {
- if (!use_json)
- vty_out (vty, "%s%*s", VTY_NEWLINE, 34, " ");
- }
- else
- {
- if (use_json)
- json_object_int_add(json, "peerHost", len);
- else
- vty_out (vty, "%*s", len, " ");
- }
+ len = vty_out(vty, "%s", binfo->peer->host);
+ len = 17 - len;
+ if (len < 1) {
+ if (!use_json)
+ vty_out(vty, "%s%*s", VTY_NEWLINE, 34, " ");
+ } else {
+ if (use_json)
+ json_object_int_add(json, "peerHost", len);
+ else
+ vty_out(vty, "%*s", len, " ");
+ }
- if (use_json)
- bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json);
- else
- vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json));
+ if (use_json)
+ bgp_damp_reuse_time_vty(vty, binfo, timebuf, BGP_UPTIME_LEN,
+ use_json, json);
+ else
+ vty_out(vty, "%s ", bgp_damp_reuse_time_vty(vty, binfo, timebuf,
+ BGP_UPTIME_LEN,
+ use_json, json));
+
+ /* Print attribute */
+ attr = binfo->attr;
+ if (attr) {
+ /* Print aspath */
+ if (attr->aspath) {
+ if (use_json)
+ json_object_string_add(json, "asPath",
+ attr->aspath->str);
+ else
+ aspath_print_vty(vty, "%s", attr->aspath, " ");
+ }
- /* Print attribute */
- attr = binfo->attr;
- if (attr)
- {
- /* Print aspath */
- if (attr->aspath)
- {
- if (use_json)
- json_object_string_add(json, "asPath", attr->aspath->str);
- else
- aspath_print_vty (vty, "%s", attr->aspath, " ");
- }
-
- /* Print origin */
- if (use_json)
- json_object_string_add(json, "origin", bgp_origin_str[attr->origin]);
- else
- vty_out (vty, "%s", bgp_origin_str[attr->origin]);
- }
- if (!use_json)
- vty_out (vty, "%s", VTY_NEWLINE);
+ /* Print origin */
+ if (use_json)
+ json_object_string_add(json, "origin",
+ bgp_origin_str[attr->origin]);
+ else
+ vty_out(vty, "%s", bgp_origin_str[attr->origin]);
+ }
+ if (!use_json)
+ vty_out(vty, "%s", VTY_NEWLINE);
}
/* flap route */
-static void
-flap_route_vty_out (struct vty *vty, struct prefix *p, struct bgp_info *binfo,
- int display, safi_t safi, u_char use_json, json_object *json)
-{
- struct attr *attr;
- struct bgp_damp_info *bdi;
- char timebuf[BGP_UPTIME_LEN];
- int len;
-
- if (!binfo->extra)
- return;
-
- bdi = binfo->extra->damp_info;
+static void flap_route_vty_out(struct vty *vty, struct prefix *p,
+ struct bgp_info *binfo, int display, safi_t safi,
+ u_char use_json, json_object *json)
+{
+ struct attr *attr;
+ struct bgp_damp_info *bdi;
+ char timebuf[BGP_UPTIME_LEN];
+ int len;
- /* short status lead text */
- route_vty_short_status_out (vty, binfo, json);
-
- /* print prefix and mask */
- if (!use_json)
- {
- if (! display)
- route_vty_out_route (p, vty);
- else
- vty_out (vty, "%*s", 17, " ");
- }
+ if (!binfo->extra)
+ return;
- len = vty_out (vty, "%s", binfo->peer->host);
- len = 16 - len;
- if (len < 1)
- {
- if (!use_json)
- vty_out (vty, "%s%*s", VTY_NEWLINE, 33, " ");
- }
- else
- {
- if (use_json)
- json_object_int_add(json, "peerHost", len);
- else
- vty_out (vty, "%*s", len, " ");
- }
+ bdi = binfo->extra->damp_info;
- len = vty_out (vty, "%d", bdi->flap);
- len = 5 - len;
- if (len < 1)
- {
- if (!use_json)
- vty_out (vty, " ");
- }
- else
- {
- if (use_json)
- json_object_int_add(json, "bdiFlap", len);
- else
- vty_out (vty, "%*s", len, " ");
- }
+ /* short status lead text */
+ route_vty_short_status_out(vty, binfo, json);
- if (use_json)
- peer_uptime (bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json, json);
- else
- vty_out (vty, "%s ", peer_uptime (bdi->start_time,
- timebuf, BGP_UPTIME_LEN, 0, NULL));
+ /* print prefix and mask */
+ if (!use_json) {
+ if (!display)
+ route_vty_out_route(p, vty);
+ else
+ vty_out(vty, "%*s", 17, " ");
+ }
- if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED)
- && ! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
- {
- if (use_json)
- bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json);
- else
- vty_out (vty, "%s ", bgp_damp_reuse_time_vty (vty, binfo, timebuf, BGP_UPTIME_LEN, use_json, json));
- }
- else
- {
- if (!use_json)
- vty_out (vty, "%*s ", 8, " ");
- }
+ len = vty_out(vty, "%s", binfo->peer->host);
+ len = 16 - len;
+ if (len < 1) {
+ if (!use_json)
+ vty_out(vty, "%s%*s", VTY_NEWLINE, 33, " ");
+ } else {
+ if (use_json)
+ json_object_int_add(json, "peerHost", len);
+ else
+ vty_out(vty, "%*s", len, " ");
+ }
- /* Print attribute */
- attr = binfo->attr;
- if (attr)
- {
- /* Print aspath */
- if (attr->aspath)
- {
- if (use_json)
- json_object_string_add(json, "asPath", attr->aspath->str);
- else
- aspath_print_vty (vty, "%s", attr->aspath, " ");
- }
-
- /* Print origin */
- if (use_json)
- json_object_string_add(json, "origin", bgp_origin_str[attr->origin]);
- else
- vty_out (vty, "%s", bgp_origin_str[attr->origin]);
- }
- if (!use_json)
- vty_out (vty, "%s", VTY_NEWLINE);
-}
+ len = vty_out(vty, "%d", bdi->flap);
+ len = 5 - len;
+ if (len < 1) {
+ if (!use_json)
+ vty_out(vty, " ");
+ } else {
+ if (use_json)
+ json_object_int_add(json, "bdiFlap", len);
+ else
+ vty_out(vty, "%*s", len, " ");
+ }
-static void
-route_vty_out_advertised_to (struct vty *vty, struct peer *peer, int *first,
- const char *header, json_object *json_adv_to)
-{
- char buf1[INET6_ADDRSTRLEN];
- json_object *json_peer = NULL;
+ if (use_json)
+ peer_uptime(bdi->start_time, timebuf, BGP_UPTIME_LEN, use_json,
+ json);
+ else
+ vty_out(vty, "%s ", peer_uptime(bdi->start_time, timebuf,
+ BGP_UPTIME_LEN, 0, NULL));
+
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)
+ && !CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) {
+ if (use_json)
+ bgp_damp_reuse_time_vty(vty, binfo, timebuf,
+ BGP_UPTIME_LEN, use_json, json);
+ else
+ vty_out(vty, "%s ",
+ bgp_damp_reuse_time_vty(vty, binfo, timebuf,
+ BGP_UPTIME_LEN,
+ use_json, json));
+ } else {
+ if (!use_json)
+ vty_out(vty, "%*s ", 8, " ");
+ }
- if (json_adv_to)
- {
- /* 'advertised-to' is a dictionary of peers we have advertised this
- * prefix too. The key is the peer's IP or swpX, the value is the
- * hostname if we know it and "" if not.
- */
- json_peer = json_object_new_object();
-
- if (peer->hostname)
- json_object_string_add(json_peer, "hostname", peer->hostname);
-
- if (peer->conf_if)
- json_object_object_add(json_adv_to, peer->conf_if, json_peer);
- else
- json_object_object_add(json_adv_to,
- sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN),
- json_peer);
- }
- else
- {
- if (*first)
- {
- vty_out (vty, "%s", header);
- *first = 0;
- }
-
- if (peer->hostname && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
- {
- if (peer->conf_if)
- vty_out (vty, " %s(%s)", peer->hostname, peer->conf_if);
- else
- vty_out (vty, " %s(%s)", peer->hostname,
- sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
- }
- else
- {
- if (peer->conf_if)
- vty_out (vty, " %s", peer->conf_if);
- else
- vty_out (vty, " %s", sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
- }
- }
+ /* Print attribute */
+ attr = binfo->attr;
+ if (attr) {
+ /* Print aspath */
+ if (attr->aspath) {
+ if (use_json)
+ json_object_string_add(json, "asPath",
+ attr->aspath->str);
+ else
+ aspath_print_vty(vty, "%s", attr->aspath, " ");
+ }
+
+ /* Print origin */
+ if (use_json)
+ json_object_string_add(json, "origin",
+ bgp_origin_str[attr->origin]);
+ else
+ vty_out(vty, "%s", bgp_origin_str[attr->origin]);
+ }
+ if (!use_json)
+ vty_out(vty, "%s", VTY_NEWLINE);
+}
+
+static void route_vty_out_advertised_to(struct vty *vty, struct peer *peer,
+ int *first, const char *header,
+ json_object *json_adv_to)
+{
+ char buf1[INET6_ADDRSTRLEN];
+ json_object *json_peer = NULL;
+
+ if (json_adv_to) {
+ /* 'advertised-to' is a dictionary of peers we have advertised
+ * this
+ * prefix too. The key is the peer's IP or swpX, the value is
+ * the
+ * hostname if we know it and "" if not.
+ */
+ json_peer = json_object_new_object();
+
+ if (peer->hostname)
+ json_object_string_add(json_peer, "hostname",
+ peer->hostname);
+
+ if (peer->conf_if)
+ json_object_object_add(json_adv_to, peer->conf_if,
+ json_peer);
+ else
+ json_object_object_add(
+ json_adv_to,
+ sockunion2str(&peer->su, buf1, SU_ADDRSTRLEN),
+ json_peer);
+ } else {
+ if (*first) {
+ vty_out(vty, "%s", header);
+ *first = 0;
+ }
+
+ if (peer->hostname
+ && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
+ if (peer->conf_if)
+ vty_out(vty, " %s(%s)", peer->hostname,
+ peer->conf_if);
+ else
+ vty_out(vty, " %s(%s)", peer->hostname,
+ sockunion2str(&peer->su, buf1,
+ SU_ADDRSTRLEN));
+ } else {
+ if (peer->conf_if)
+ vty_out(vty, " %s", peer->conf_if);
+ else
+ vty_out(vty, " %s",
+ sockunion2str(&peer->su, buf1,
+ SU_ADDRSTRLEN));
+ }
+ }
}
-static void
-route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
- struct bgp_info *binfo, afi_t afi, safi_t safi,
- json_object *json_paths)
-{
- char buf[INET6_ADDRSTRLEN];
- char buf1[BUFSIZ];
- struct attr *attr;
- int sockunion_vty_out (struct vty *, union sockunion *);
- time_t tbuf;
- json_object *json_bestpath = NULL;
- json_object *json_cluster_list = NULL;
- json_object *json_cluster_list_list = NULL;
- json_object *json_ext_community = NULL;
- json_object *json_last_update = NULL;
- json_object *json_nexthop_global = NULL;
- json_object *json_nexthop_ll = NULL;
- json_object *json_nexthops = NULL;
- json_object *json_path = NULL;
- json_object *json_peer = NULL;
- json_object *json_string = NULL;
- json_object *json_adv_to = NULL;
- int first = 0;
- struct listnode *node, *nnode;
- struct peer *peer;
- int addpath_capable;
- int has_adj;
- unsigned int first_as;
-
- if (json_paths)
- {
- json_path = json_object_new_object();
- json_peer = json_object_new_object();
- json_nexthop_global = json_object_new_object();
- }
+static void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
+ struct prefix *p, struct bgp_info *binfo,
+ afi_t afi, safi_t safi,
+ json_object *json_paths)
+{
+ char buf[INET6_ADDRSTRLEN];
+ char buf1[BUFSIZ];
+ struct attr *attr;
+ int sockunion_vty_out(struct vty *, union sockunion *);
+ time_t tbuf;
+ json_object *json_bestpath = NULL;
+ json_object *json_cluster_list = NULL;
+ json_object *json_cluster_list_list = NULL;
+ json_object *json_ext_community = NULL;
+ json_object *json_last_update = NULL;
+ json_object *json_nexthop_global = NULL;
+ json_object *json_nexthop_ll = NULL;
+ json_object *json_nexthops = NULL;
+ json_object *json_path = NULL;
+ json_object *json_peer = NULL;
+ json_object *json_string = NULL;
+ json_object *json_adv_to = NULL;
+ int first = 0;
+ struct listnode *node, *nnode;
+ struct peer *peer;
+ int addpath_capable;
+ int has_adj;
+ unsigned int first_as;
+
+ if (json_paths) {
+ json_path = json_object_new_object();
+ json_peer = json_object_new_object();
+ json_nexthop_global = json_object_new_object();
+ }
- attr = binfo->attr;
+ attr = binfo->attr;
+
+ if (attr) {
+ /* Line1 display AS-path, Aggregator */
+ if (attr->aspath) {
+ if (json_paths) {
+ json_object_lock(attr->aspath->json);
+ json_object_object_add(json_path, "aspath",
+ attr->aspath->json);
+ } else {
+ if (attr->aspath->segments)
+ aspath_print_vty(vty, " %s",
+ attr->aspath, "");
+ else
+ vty_out(vty, " Local");
+ }
+ }
- if (attr)
- {
- /* Line1 display AS-path, Aggregator */
- if (attr->aspath)
- {
- if (json_paths)
- {
- json_object_lock(attr->aspath->json);
- json_object_object_add(json_path, "aspath", attr->aspath->json);
- }
- else
- {
- if (attr->aspath->segments)
- aspath_print_vty (vty, " %s", attr->aspath, "");
- else
- vty_out (vty, " Local");
- }
- }
-
- if (CHECK_FLAG (binfo->flags, BGP_INFO_REMOVED))
- {
- if (json_paths)
- json_object_boolean_true_add(json_path, "removed");
- else
- vty_out (vty, ", (removed)");
- }
-
- if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
- {
- if (json_paths)
- json_object_boolean_true_add(json_path, "stale");
- else
- vty_out (vty, ", (stale)");
- }
-
- if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR)))
- {
- if (json_paths)
- {
- json_object_int_add(json_path, "aggregatorAs", attr->extra->aggregator_as);
- json_object_string_add(json_path, "aggregatorId", inet_ntoa (attr->extra->aggregator_addr));
- }
- else
- {
- vty_out (vty, ", (aggregated by %u %s)",
- attr->extra->aggregator_as,
- inet_ntoa (attr->extra->aggregator_addr));
- }
- }
-
- if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_REFLECTOR_CLIENT))
- {
- if (json_paths)
- json_object_boolean_true_add(json_path, "rxedFromRrClient");
- else
- vty_out (vty, ", (Received from a RR-client)");
- }
-
- if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
- {
- if (json_paths)
- json_object_boolean_true_add(json_path, "rxedFromRsClient");
- else
- vty_out (vty, ", (Received from a RS-client)");
- }
-
- if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
- {
- if (json_paths)
- json_object_boolean_true_add(json_path, "dampeningHistoryEntry");
- else
- vty_out (vty, ", (history entry)");
- }
- else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
- {
- if (json_paths)
- json_object_boolean_true_add(json_path, "dampeningSuppressed");
- else
- vty_out (vty, ", (suppressed due to dampening)");
- }
-
- if (!json_paths)
- vty_out (vty, "%s", VTY_NEWLINE);
-
- /* Line2 display Next-hop, Neighbor, Router-id */
- /* Display the nexthop */
- if (p->family == AF_INET &&
- (safi == SAFI_MPLS_VPN ||
- safi == SAFI_ENCAP ||
- safi == SAFI_EVPN ||
- !BGP_ATTR_NEXTHOP_AFI_IP6(attr)))
- {
- if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
- {
- if (json_paths)
- json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->extra->mp_nexthop_global_in));
- else
- vty_out (vty, " %s", inet_ntoa (attr->extra->mp_nexthop_global_in));
- }
- else
- {
- if (json_paths)
- json_object_string_add(json_nexthop_global, "ip", inet_ntoa (attr->nexthop));
- else
- vty_out (vty, " %s", inet_ntoa (attr->nexthop));
- }
-
- if (json_paths)
- json_object_string_add(json_nexthop_global, "afi", "ipv4");
- }
- else
- {
- assert (attr->extra);
- if (json_paths)
- {
- json_object_string_add(json_nexthop_global, "ip",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
- buf, INET6_ADDRSTRLEN));
- json_object_string_add(json_nexthop_global, "afi", "ipv6");
- json_object_string_add(json_nexthop_global, "scope", "global");
- }
- else
- {
- vty_out (vty, " %s",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
- buf, INET6_ADDRSTRLEN));
- }
- }
-
- /* Display the IGP cost or 'inaccessible' */
- if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
- {
- if (json_paths)
- json_object_boolean_false_add(json_nexthop_global, "accessible");
- else
- vty_out (vty, " (inaccessible)");
- }
- else
- {
- if (binfo->extra && binfo->extra->igpmetric)
- {
- if (json_paths)
- json_object_int_add(json_nexthop_global, "metric", binfo->extra->igpmetric);
- else
- vty_out (vty, " (metric %u)", binfo->extra->igpmetric);
- }
-
- /* IGP cost is 0, display this only for json */
- else
- {
- if (json_paths)
- json_object_int_add(json_nexthop_global, "metric", 0);
- }
-
- if (json_paths)
- json_object_boolean_true_add(json_nexthop_global, "accessible");
- }
-
- /* Display peer "from" output */
- /* This path was originated locally */
- if (binfo->peer == bgp->peer_self)
- {
-
- if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
- {
- if (json_paths)
- json_object_string_add(json_peer, "peerId", "0.0.0.0");
- else
- vty_out (vty, " from 0.0.0.0 ");
- }
- else
- {
- if (json_paths)
- json_object_string_add(json_peer, "peerId", "::");
- else
- vty_out (vty, " from :: ");
- }
-
- if (json_paths)
- json_object_string_add(json_peer, "routerId", inet_ntoa(bgp->router_id));
- else
- vty_out (vty, "(%s)", inet_ntoa(bgp->router_id));
- }
-
- /* We RXed this path from one of our peers */
- else
- {
-
- if (json_paths)
- {
- json_object_string_add(json_peer, "peerId", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
- json_object_string_add(json_peer, "routerId", inet_ntop (AF_INET, &binfo->peer->remote_id, buf1, BUFSIZ));
-
- if (binfo->peer->hostname)
- json_object_string_add(json_peer, "hostname", binfo->peer->hostname);
-
- if (binfo->peer->domainname)
- json_object_string_add(json_peer, "domainname", binfo->peer->domainname);
-
- if (binfo->peer->conf_if)
- json_object_string_add(json_peer, "interface", binfo->peer->conf_if);
- }
- else
- {
- if (binfo->peer->conf_if)
- {
- if (binfo->peer->hostname &&
- bgp_flag_check(binfo->peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
- vty_out (vty, " from %s(%s)", binfo->peer->hostname,
- binfo->peer->conf_if);
- else
- vty_out (vty, " from %s", binfo->peer->conf_if);
- }
- else
- {
- if (binfo->peer->hostname &&
- bgp_flag_check(binfo->peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
- vty_out (vty, " from %s(%s)", binfo->peer->hostname,
- binfo->peer->host);
- else
- vty_out (vty, " from %s", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
- }
-
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
- vty_out (vty, " (%s)", inet_ntoa (attr->extra->originator_id));
- else
- vty_out (vty, " (%s)", inet_ntop (AF_INET, &binfo->peer->remote_id, buf1, BUFSIZ));
- }
- }
-
- if (!json_paths)
- vty_out (vty, "%s", VTY_NEWLINE);
-
- /* display the link-local nexthop */
- if (attr->extra && attr->extra->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
- {
- if (json_paths)
- {
- json_nexthop_ll = json_object_new_object();
- json_object_string_add(json_nexthop_ll, "ip",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
- buf, INET6_ADDRSTRLEN));
- json_object_string_add(json_nexthop_ll, "afi", "ipv6");
- json_object_string_add(json_nexthop_ll, "scope", "link-local");
-
- json_object_boolean_true_add(json_nexthop_ll, "accessible");
-
- if (!attr->extra->mp_nexthop_prefer_global)
- json_object_boolean_true_add(json_nexthop_ll, "used");
- else
- json_object_boolean_true_add(json_nexthop_global, "used");
- }
- else
- {
- vty_out (vty, " (%s) %s%s",
- inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
- buf, INET6_ADDRSTRLEN),
- attr->extra->mp_nexthop_prefer_global ?
- "(prefer-global)" : "(used)",
- VTY_NEWLINE);
- }
- }
- /* If we do not have a link-local nexthop then we must flag the global as "used" */
- else
- {
- if (json_paths)
- json_object_boolean_true_add(json_nexthop_global, "used");
- }
-
- /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid, Int/Ext/Local, Atomic, best */
- if (json_paths)
- json_object_string_add(json_path, "origin", bgp_origin_long_str[attr->origin]);
- else
- vty_out (vty, " Origin %s", bgp_origin_long_str[attr->origin]);
-
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
- {
- if (json_paths)
- json_object_int_add(json_path, "med", attr->med);
- else
- vty_out (vty, ", metric %u", attr->med);
- }
-
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
- {
- if (json_paths)
- json_object_int_add(json_path, "localpref", attr->local_pref);
- else
- vty_out (vty, ", localpref %u", attr->local_pref);
- }
- else
- {
- if (json_paths)
- json_object_int_add(json_path, "localpref", bgp->default_local_pref);
- else
- vty_out (vty, ", localpref %u", bgp->default_local_pref);
- }
-
- if (attr->extra && attr->extra->weight != 0)
- {
- if (json_paths)
- json_object_int_add(json_path, "weight", attr->extra->weight);
- else
- vty_out (vty, ", weight %u", attr->extra->weight);
- }
-
- if (attr->extra && attr->extra->tag != 0)
- {
- if (json_paths)
- json_object_int_add(json_path, "tag", attr->extra->tag);
- else
- vty_out (vty, ", tag %"ROUTE_TAG_PRI, attr->extra->tag);
- }
-
- if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
- {
- if (json_paths)
- json_object_boolean_false_add(json_path, "valid");
- else
- vty_out (vty, ", invalid");
- }
- else if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
- {
- if (json_paths)
- json_object_boolean_true_add(json_path, "valid");
- else
- vty_out (vty, ", valid");
- }
-
- if (binfo->peer != bgp->peer_self)
- {
- if (binfo->peer->as == binfo->peer->local_as)
- {
- if (CHECK_FLAG(bgp->config, BGP_CONFIG_CONFEDERATION))
- {
- if (json_paths)
- json_object_string_add(json_peer, "type", "confed-internal");
- else
- vty_out (vty, ", confed-internal");
- }
- else
- {
- if (json_paths)
- json_object_string_add(json_peer, "type", "internal");
- else
- vty_out (vty, ", internal");
- }
- }
- else
- {
- if (bgp_confederation_peers_check(bgp, binfo->peer->as))
- {
- if (json_paths)
- json_object_string_add(json_peer, "type", "confed-external");
- else
- vty_out (vty, ", confed-external");
- }
- else
- {
- if (json_paths)
- json_object_string_add(json_peer, "type", "external");
- else
- vty_out (vty, ", external");
- }
- }
- }
- else if (binfo->sub_type == BGP_ROUTE_AGGREGATE)
- {
- if (json_paths)
- {
- json_object_boolean_true_add(json_path, "aggregated");
- json_object_boolean_true_add(json_path, "local");
- }
- else
- {
- vty_out (vty, ", aggregated, local");
- }
- }
- else if (binfo->type != ZEBRA_ROUTE_BGP)
- {
- if (json_paths)
- json_object_boolean_true_add(json_path, "sourced");
- else
- vty_out (vty, ", sourced");
- }
- else
- {
- if (json_paths)
- {
- json_object_boolean_true_add(json_path, "sourced");
- json_object_boolean_true_add(json_path, "local");
- }
- else
- {
- vty_out (vty, ", sourced, local");
- }
- }
-
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
- {
- if (json_paths)
- json_object_boolean_true_add(json_path, "atomicAggregate");
- else
- vty_out (vty, ", atomic-aggregate");
- }
-
- if (CHECK_FLAG (binfo->flags, BGP_INFO_MULTIPATH) ||
- (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED) &&
- bgp_info_mpath_count (binfo)))
- {
- if (json_paths)
- json_object_boolean_true_add(json_path, "multipath");
- else
- vty_out (vty, ", multipath");
- }
-
- // Mark the bestpath(s)
- if (CHECK_FLAG (binfo->flags, BGP_INFO_DMED_SELECTED))
- {
- first_as = aspath_get_first_as(attr->aspath);
-
- if (json_paths)
- {
- if (!json_bestpath)
- json_bestpath = json_object_new_object();
- json_object_int_add(json_bestpath, "bestpathFromAs", first_as);
- }
- else
- {
- if (first_as)
- vty_out (vty, ", bestpath-from-AS %d", first_as);
- else
- vty_out (vty, ", bestpath-from-AS Local");
- }
- }
-
- if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
- {
- if (json_paths)
- {
- if (!json_bestpath)
- json_bestpath = json_object_new_object();
- json_object_boolean_true_add(json_bestpath, "overall");
- }
- else
- vty_out (vty, ", best");
- }
-
- if (json_bestpath)
- json_object_object_add(json_path, "bestpath", json_bestpath);
-
- if (!json_paths)
- vty_out (vty, "%s", VTY_NEWLINE);
-
- /* Line 4 display Community */
- if (attr->community)
- {
- if (json_paths)
- {
- json_object_lock(attr->community->json);
- json_object_object_add(json_path, "community", attr->community->json);
- }
- else
- {
- vty_out (vty, " Community: %s%s", attr->community->str,
- VTY_NEWLINE);
- }
- }
-
- /* Line 5 display Extended-community */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES))
- {
- if (json_paths)
- {
- json_ext_community = json_object_new_object();
- json_object_string_add(json_ext_community, "string", attr->extra->ecommunity->str);
- json_object_object_add(json_path, "extendedCommunity", json_ext_community);
- }
- else
- {
- vty_out (vty, " Extended Community: %s%s",
- attr->extra->ecommunity->str, VTY_NEWLINE);
- }
- }
-
- /* Line 6 display Large community */
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))
- vty_out (vty, " Large Community: %s%s",
- attr->extra->lcommunity->str, VTY_NEWLINE);
-
- /* Line 7 display Originator, Cluster-id */
- if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) ||
- (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)))
- {
- assert (attr->extra);
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
- {
- if (json_paths)
- json_object_string_add(json_path, "originatorId", inet_ntoa (attr->extra->originator_id));
- else
- vty_out (vty, " Originator: %s",
- inet_ntoa (attr->extra->originator_id));
- }
-
- if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
- {
- int i;
-
- if (json_paths)
- {
- json_cluster_list = json_object_new_object();
- json_cluster_list_list = json_object_new_array();
-
- for (i = 0; i < attr->extra->cluster->length / 4; i++)
- {
- json_string = json_object_new_string(inet_ntoa (attr->extra->cluster->list[i]));
- json_object_array_add(json_cluster_list_list, json_string);
- }
-
- /* struct cluster_list does not have "str" variable like
- * aspath and community do. Add this someday if someone
- * asks for it.
- json_object_string_add(json_cluster_list, "string", attr->extra->cluster->str);
- */
- json_object_object_add(json_cluster_list, "list", json_cluster_list_list);
- json_object_object_add(json_path, "clusterList", json_cluster_list);
- }
- else
- {
- vty_out (vty, ", Cluster list: ");
-
- for (i = 0; i < attr->extra->cluster->length / 4; i++)
- {
- vty_out (vty, "%s ",
- inet_ntoa (attr->extra->cluster->list[i]));
- }
- }
- }
-
- if (!json_paths)
- vty_out (vty, "%s", VTY_NEWLINE);
- }
-
- if (binfo->extra && binfo->extra->damp_info)
- bgp_damp_info_vty (vty, binfo, json_path);
-
- /* Line 8 display Addpath IDs */
- if (binfo->addpath_rx_id || binfo->addpath_tx_id)
- {
- if (json_paths)
- {
- json_object_int_add(json_path, "addpathRxId", binfo->addpath_rx_id);
- json_object_int_add(json_path, "addpathTxId", binfo->addpath_tx_id);
- }
- else
- {
- vty_out (vty, " AddPath ID: RX %u, TX %u%s",
- binfo->addpath_rx_id, binfo->addpath_tx_id,
- VTY_NEWLINE);
- }
- }
-
- /* If we used addpath to TX a non-bestpath we need to display
- * "Advertised to" on a path-by-path basis */
- if (bgp->addpath_tx_used[afi][safi])
- {
- first = 1;
-
- for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
- {
- addpath_capable = bgp_addpath_encode_tx (peer, afi, safi);
- has_adj = bgp_adj_out_lookup (peer, binfo->net, binfo->addpath_tx_id);
-
- if ((addpath_capable && has_adj) ||
- (!addpath_capable && has_adj && CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED)))
- {
- if (json_path && !json_adv_to)
- json_adv_to = json_object_new_object();
-
- route_vty_out_advertised_to(vty, peer, &first,
- " Advertised to:",
- json_adv_to);
- }
- }
-
- if (json_path)
- {
- if (json_adv_to)
- {
- json_object_object_add(json_path, "advertisedTo", json_adv_to);
- }
- }
- else
- {
- if (!first)
- {
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- }
- }
-
- /* Line 9 display Uptime */
- tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
- if (json_paths)
- {
- json_last_update = json_object_new_object();
- json_object_int_add(json_last_update, "epoch", tbuf);
- json_object_string_add(json_last_update, "string", ctime(&tbuf));
- json_object_object_add(json_path, "lastUpdate", json_last_update);
- }
- else
- vty_out (vty, " Last update: %s", ctime(&tbuf));
- }
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_REMOVED)) {
+ if (json_paths)
+ json_object_boolean_true_add(json_path,
+ "removed");
+ else
+ vty_out(vty, ", (removed)");
+ }
- /* We've constructed the json object for this path, add it to the json
- * array of paths
- */
- if (json_paths)
- {
- if (json_nexthop_global || json_nexthop_ll)
- {
- json_nexthops = json_object_new_array();
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_STALE)) {
+ if (json_paths)
+ json_object_boolean_true_add(json_path,
+ "stale");
+ else
+ vty_out(vty, ", (stale)");
+ }
- if (json_nexthop_global)
- json_object_array_add(json_nexthops, json_nexthop_global);
+ if (CHECK_FLAG(attr->flag,
+ ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
+ if (json_paths) {
+ json_object_int_add(json_path, "aggregatorAs",
+ attr->extra->aggregator_as);
+ json_object_string_add(
+ json_path, "aggregatorId",
+ inet_ntoa(
+ attr->extra->aggregator_addr));
+ } else {
+ vty_out(vty, ", (aggregated by %u %s)",
+ attr->extra->aggregator_as,
+ inet_ntoa(
+ attr->extra->aggregator_addr));
+ }
+ }
- if (json_nexthop_ll)
- json_object_array_add(json_nexthops, json_nexthop_ll);
+ if (CHECK_FLAG(binfo->peer->af_flags[afi][safi],
+ PEER_FLAG_REFLECTOR_CLIENT)) {
+ if (json_paths)
+ json_object_boolean_true_add(
+ json_path, "rxedFromRrClient");
+ else
+ vty_out(vty, ", (Received from a RR-client)");
+ }
- json_object_object_add(json_path, "nexthops", json_nexthops);
- }
+ if (CHECK_FLAG(binfo->peer->af_flags[afi][safi],
+ PEER_FLAG_RSERVER_CLIENT)) {
+ if (json_paths)
+ json_object_boolean_true_add(
+ json_path, "rxedFromRsClient");
+ else
+ vty_out(vty, ", (Received from a RS-client)");
+ }
- json_object_object_add(json_path, "peer", json_peer);
- json_object_array_add(json_paths, json_path);
- }
- else
- vty_out (vty, "%s", VTY_NEWLINE);
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) {
+ if (json_paths)
+ json_object_boolean_true_add(
+ json_path, "dampeningHistoryEntry");
+ else
+ vty_out(vty, ", (history entry)");
+ } else if (CHECK_FLAG(binfo->flags, BGP_INFO_DAMPED)) {
+ if (json_paths)
+ json_object_boolean_true_add(
+ json_path, "dampeningSuppressed");
+ else
+ vty_out(vty, ", (suppressed due to dampening)");
+ }
+
+ if (!json_paths)
+ vty_out(vty, "%s", VTY_NEWLINE);
+
+ /* Line2 display Next-hop, Neighbor, Router-id */
+ /* Display the nexthop */
+ if (p->family == AF_INET
+ && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
+ || safi == SAFI_EVPN
+ || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
+ || safi == SAFI_EVPN) {
+ if (json_paths)
+ json_object_string_add(
+ json_nexthop_global, "ip",
+ inet_ntoa(
+ attr->extra
+ ->mp_nexthop_global_in));
+ else
+ vty_out(vty, " %s",
+ inet_ntoa(
+ attr->extra
+ ->mp_nexthop_global_in));
+ } else {
+ if (json_paths)
+ json_object_string_add(
+ json_nexthop_global, "ip",
+ inet_ntoa(attr->nexthop));
+ else
+ vty_out(vty, " %s",
+ inet_ntoa(attr->nexthop));
+ }
+
+ if (json_paths)
+ json_object_string_add(json_nexthop_global,
+ "afi", "ipv4");
+ } else {
+ assert(attr->extra);
+ if (json_paths) {
+ json_object_string_add(
+ json_nexthop_global, "ip",
+ inet_ntop(
+ AF_INET6,
+ &attr->extra->mp_nexthop_global,
+ buf, INET6_ADDRSTRLEN));
+ json_object_string_add(json_nexthop_global,
+ "afi", "ipv6");
+ json_object_string_add(json_nexthop_global,
+ "scope", "global");
+ } else {
+ vty_out(vty, " %s",
+ inet_ntop(
+ AF_INET6,
+ &attr->extra->mp_nexthop_global,
+ buf, INET6_ADDRSTRLEN));
+ }
+ }
+
+ /* Display the IGP cost or 'inaccessible' */
+ if (!CHECK_FLAG(binfo->flags, BGP_INFO_VALID)) {
+ if (json_paths)
+ json_object_boolean_false_add(
+ json_nexthop_global, "accessible");
+ else
+ vty_out(vty, " (inaccessible)");
+ } else {
+ if (binfo->extra && binfo->extra->igpmetric) {
+ if (json_paths)
+ json_object_int_add(
+ json_nexthop_global, "metric",
+ binfo->extra->igpmetric);
+ else
+ vty_out(vty, " (metric %u)",
+ binfo->extra->igpmetric);
+ }
+
+ /* IGP cost is 0, display this only for json */
+ else {
+ if (json_paths)
+ json_object_int_add(json_nexthop_global,
+ "metric", 0);
+ }
+
+ if (json_paths)
+ json_object_boolean_true_add(
+ json_nexthop_global, "accessible");
+ }
+
+ /* Display peer "from" output */
+ /* This path was originated locally */
+ if (binfo->peer == bgp->peer_self) {
+
+ if (p->family == AF_INET
+ && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+ if (json_paths)
+ json_object_string_add(
+ json_peer, "peerId", "0.0.0.0");
+ else
+ vty_out(vty, " from 0.0.0.0 ");
+ } else {
+ if (json_paths)
+ json_object_string_add(json_peer,
+ "peerId", "::");
+ else
+ vty_out(vty, " from :: ");
+ }
+
+ if (json_paths)
+ json_object_string_add(
+ json_peer, "routerId",
+ inet_ntoa(bgp->router_id));
+ else
+ vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
+ }
+
+ /* We RXed this path from one of our peers */
+ else {
+
+ if (json_paths) {
+ json_object_string_add(
+ json_peer, "peerId",
+ sockunion2str(&binfo->peer->su, buf,
+ SU_ADDRSTRLEN));
+ json_object_string_add(
+ json_peer, "routerId",
+ inet_ntop(AF_INET,
+ &binfo->peer->remote_id, buf1,
+ BUFSIZ));
+
+ if (binfo->peer->hostname)
+ json_object_string_add(
+ json_peer, "hostname",
+ binfo->peer->hostname);
+
+ if (binfo->peer->domainname)
+ json_object_string_add(
+ json_peer, "domainname",
+ binfo->peer->domainname);
+
+ if (binfo->peer->conf_if)
+ json_object_string_add(
+ json_peer, "interface",
+ binfo->peer->conf_if);
+ } else {
+ if (binfo->peer->conf_if) {
+ if (binfo->peer->hostname
+ && bgp_flag_check(
+ binfo->peer->bgp,
+ BGP_FLAG_SHOW_HOSTNAME))
+ vty_out(vty, " from %s(%s)",
+ binfo->peer->hostname,
+ binfo->peer->conf_if);
+ else
+ vty_out(vty, " from %s",
+ binfo->peer->conf_if);
+ } else {
+ if (binfo->peer->hostname
+ && bgp_flag_check(
+ binfo->peer->bgp,
+ BGP_FLAG_SHOW_HOSTNAME))
+ vty_out(vty, " from %s(%s)",
+ binfo->peer->hostname,
+ binfo->peer->host);
+ else
+ vty_out(vty, " from %s",
+ sockunion2str(
+ &binfo->peer
+ ->su,
+ buf,
+ SU_ADDRSTRLEN));
+ }
+
+ if (attr->flag
+ & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
+ vty_out(vty, " (%s)",
+ inet_ntoa(
+ attr->extra
+ ->originator_id));
+ else
+ vty_out(vty, " (%s)",
+ inet_ntop(
+ AF_INET,
+ &binfo->peer->remote_id,
+ buf1, BUFSIZ));
+ }
+ }
+
+ if (!json_paths)
+ vty_out(vty, "%s", VTY_NEWLINE);
+
+ /* display the link-local nexthop */
+ if (attr->extra
+ && attr->extra->mp_nexthop_len
+ == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
+ if (json_paths) {
+ json_nexthop_ll = json_object_new_object();
+ json_object_string_add(
+ json_nexthop_ll, "ip",
+ inet_ntop(
+ AF_INET6,
+ &attr->extra->mp_nexthop_local,
+ buf, INET6_ADDRSTRLEN));
+ json_object_string_add(json_nexthop_ll, "afi",
+ "ipv6");
+ json_object_string_add(json_nexthop_ll, "scope",
+ "link-local");
+
+ json_object_boolean_true_add(json_nexthop_ll,
+ "accessible");
+
+ if (!attr->extra->mp_nexthop_prefer_global)
+ json_object_boolean_true_add(
+ json_nexthop_ll, "used");
+ else
+ json_object_boolean_true_add(
+ json_nexthop_global, "used");
+ } else {
+ vty_out(vty, " (%s) %s%s",
+ inet_ntop(
+ AF_INET6,
+ &attr->extra->mp_nexthop_local,
+ buf, INET6_ADDRSTRLEN),
+ attr->extra->mp_nexthop_prefer_global
+ ? "(prefer-global)"
+ : "(used)",
+ VTY_NEWLINE);
+ }
+ }
+ /* If we do not have a link-local nexthop then we must flag the
+ global as "used" */
+ else {
+ if (json_paths)
+ json_object_boolean_true_add(
+ json_nexthop_global, "used");
+ }
+
+ /* Line 3 display Origin, Med, Locpref, Weight, Tag, valid,
+ * Int/Ext/Local, Atomic, best */
+ if (json_paths)
+ json_object_string_add(
+ json_path, "origin",
+ bgp_origin_long_str[attr->origin]);
+ else
+ vty_out(vty, " Origin %s",
+ bgp_origin_long_str[attr->origin]);
+
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) {
+ if (json_paths)
+ json_object_int_add(json_path, "med",
+ attr->med);
+ else
+ vty_out(vty, ", metric %u", attr->med);
+ }
+
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) {
+ if (json_paths)
+ json_object_int_add(json_path, "localpref",
+ attr->local_pref);
+ else
+ vty_out(vty, ", localpref %u",
+ attr->local_pref);
+ } else {
+ if (json_paths)
+ json_object_int_add(json_path, "localpref",
+ bgp->default_local_pref);
+ else
+ vty_out(vty, ", localpref %u",
+ bgp->default_local_pref);
+ }
+
+ if (attr->extra && attr->extra->weight != 0) {
+ if (json_paths)
+ json_object_int_add(json_path, "weight",
+ attr->extra->weight);
+ else
+ vty_out(vty, ", weight %u",
+ attr->extra->weight);
+ }
+
+ if (attr->extra && attr->extra->tag != 0) {
+ if (json_paths)
+ json_object_int_add(json_path, "tag",
+ attr->extra->tag);
+ else
+ vty_out(vty, ", tag %" ROUTE_TAG_PRI,
+ attr->extra->tag);
+ }
+
+ if (!CHECK_FLAG(binfo->flags, BGP_INFO_VALID)) {
+ if (json_paths)
+ json_object_boolean_false_add(json_path,
+ "valid");
+ else
+ vty_out(vty, ", invalid");
+ } else if (!CHECK_FLAG(binfo->flags, BGP_INFO_HISTORY)) {
+ if (json_paths)
+ json_object_boolean_true_add(json_path,
+ "valid");
+ else
+ vty_out(vty, ", valid");
+ }
+
+ if (binfo->peer != bgp->peer_self) {
+ if (binfo->peer->as == binfo->peer->local_as) {
+ if (CHECK_FLAG(bgp->config,
+ BGP_CONFIG_CONFEDERATION)) {
+ if (json_paths)
+ json_object_string_add(
+ json_peer, "type",
+ "confed-internal");
+ else
+ vty_out(vty,
+ ", confed-internal");
+ } else {
+ if (json_paths)
+ json_object_string_add(
+ json_peer, "type",
+ "internal");
+ else
+ vty_out(vty, ", internal");
+ }
+ } else {
+ if (bgp_confederation_peers_check(
+ bgp, binfo->peer->as)) {
+ if (json_paths)
+ json_object_string_add(
+ json_peer, "type",
+ "confed-external");
+ else
+ vty_out(vty,
+ ", confed-external");
+ } else {
+ if (json_paths)
+ json_object_string_add(
+ json_peer, "type",
+ "external");
+ else
+ vty_out(vty, ", external");
+ }
+ }
+ } else if (binfo->sub_type == BGP_ROUTE_AGGREGATE) {
+ if (json_paths) {
+ json_object_boolean_true_add(json_path,
+ "aggregated");
+ json_object_boolean_true_add(json_path,
+ "local");
+ } else {
+ vty_out(vty, ", aggregated, local");
+ }
+ } else if (binfo->type != ZEBRA_ROUTE_BGP) {
+ if (json_paths)
+ json_object_boolean_true_add(json_path,
+ "sourced");
+ else
+ vty_out(vty, ", sourced");
+ } else {
+ if (json_paths) {
+ json_object_boolean_true_add(json_path,
+ "sourced");
+ json_object_boolean_true_add(json_path,
+ "local");
+ } else {
+ vty_out(vty, ", sourced, local");
+ }
+ }
+
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) {
+ if (json_paths)
+ json_object_boolean_true_add(json_path,
+ "atomicAggregate");
+ else
+ vty_out(vty, ", atomic-aggregate");
+ }
+
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_MULTIPATH)
+ || (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED)
+ && bgp_info_mpath_count(binfo))) {
+ if (json_paths)
+ json_object_boolean_true_add(json_path,
+ "multipath");
+ else
+ vty_out(vty, ", multipath");
+ }
+
+ // Mark the bestpath(s)
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_DMED_SELECTED)) {
+ first_as = aspath_get_first_as(attr->aspath);
+
+ if (json_paths) {
+ if (!json_bestpath)
+ json_bestpath =
+ json_object_new_object();
+ json_object_int_add(json_bestpath,
+ "bestpathFromAs", first_as);
+ } else {
+ if (first_as)
+ vty_out(vty, ", bestpath-from-AS %d",
+ first_as);
+ else
+ vty_out(vty,
+ ", bestpath-from-AS Local");
+ }
+ }
+
+ if (CHECK_FLAG(binfo->flags, BGP_INFO_SELECTED)) {
+ if (json_paths) {
+ if (!json_bestpath)
+ json_bestpath =
+ json_object_new_object();
+ json_object_boolean_true_add(json_bestpath,
+ "overall");
+ } else
+ vty_out(vty, ", best");
+ }
+
+ if (json_bestpath)
+ json_object_object_add(json_path, "bestpath",
+ json_bestpath);
+
+ if (!json_paths)
+ vty_out(vty, "%s", VTY_NEWLINE);
+
+ /* Line 4 display Community */
+ if (attr->community) {
+ if (json_paths) {
+ json_object_lock(attr->community->json);
+ json_object_object_add(json_path, "community",
+ attr->community->json);
+ } else {
+ vty_out(vty, " Community: %s%s",
+ attr->community->str, VTY_NEWLINE);
+ }
+ }
+
+ /* Line 5 display Extended-community */
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)) {
+ if (json_paths) {
+ json_ext_community = json_object_new_object();
+ json_object_string_add(
+ json_ext_community, "string",
+ attr->extra->ecommunity->str);
+ json_object_object_add(json_path,
+ "extendedCommunity",
+ json_ext_community);
+ } else {
+ vty_out(vty, " Extended Community: %s%s",
+ attr->extra->ecommunity->str,
+ VTY_NEWLINE);
+ }
+ }
+
+ /* Line 6 display Large community */
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))
+ vty_out(vty, " Large Community: %s%s",
+ attr->extra->lcommunity->str, VTY_NEWLINE);
+
+ /* Line 7 display Originator, Cluster-id */
+ if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
+ || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
+ assert(attr->extra);
+ if (attr->flag
+ & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
+ if (json_paths)
+ json_object_string_add(
+ json_path, "originatorId",
+ inet_ntoa(
+ attr->extra
+ ->originator_id));
+ else
+ vty_out(vty, " Originator: %s",
+ inet_ntoa(
+ attr->extra
+ ->originator_id));
+ }
+
+ if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
+ int i;
+
+ if (json_paths) {
+ json_cluster_list =
+ json_object_new_object();
+ json_cluster_list_list =
+ json_object_new_array();
+
+ for (i = 0;
+ i
+ < attr->extra->cluster->length / 4;
+ i++) {
+ json_string = json_object_new_string(
+ inet_ntoa(
+ attr->extra
+ ->cluster
+ ->list[i]));
+ json_object_array_add(
+ json_cluster_list_list,
+ json_string);
+ }
+
+ /* struct cluster_list does not have
+ "str" variable like
+ * aspath and community do. Add this
+ someday if someone
+ * asks for it.
+ json_object_string_add(json_cluster_list,
+ "string", attr->extra->cluster->str);
+ */
+ json_object_object_add(
+ json_cluster_list, "list",
+ json_cluster_list_list);
+ json_object_object_add(
+ json_path, "clusterList",
+ json_cluster_list);
+ } else {
+ vty_out(vty, ", Cluster list: ");
+
+ for (i = 0;
+ i
+ < attr->extra->cluster->length / 4;
+ i++) {
+ vty_out(vty, "%s ",
+ inet_ntoa(
+ attr->extra
+ ->cluster
+ ->list[i]));
+ }
+ }
+ }
+
+ if (!json_paths)
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+
+ if (binfo->extra && binfo->extra->damp_info)
+ bgp_damp_info_vty(vty, binfo, json_path);
+
+ /* Line 8 display Addpath IDs */
+ if (binfo->addpath_rx_id || binfo->addpath_tx_id) {
+ if (json_paths) {
+ json_object_int_add(json_path, "addpathRxId",
+ binfo->addpath_rx_id);
+ json_object_int_add(json_path, "addpathTxId",
+ binfo->addpath_tx_id);
+ } else {
+ vty_out(vty, " AddPath ID: RX %u, TX %u%s",
+ binfo->addpath_rx_id,
+ binfo->addpath_tx_id, VTY_NEWLINE);
+ }
+ }
+
+ /* If we used addpath to TX a non-bestpath we need to display
+ * "Advertised to" on a path-by-path basis */
+ if (bgp->addpath_tx_used[afi][safi]) {
+ first = 1;
+
+ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+ addpath_capable =
+ bgp_addpath_encode_tx(peer, afi, safi);
+ has_adj = bgp_adj_out_lookup(
+ peer, binfo->net, binfo->addpath_tx_id);
+
+ if ((addpath_capable && has_adj)
+ || (!addpath_capable && has_adj
+ && CHECK_FLAG(binfo->flags,
+ BGP_INFO_SELECTED))) {
+ if (json_path && !json_adv_to)
+ json_adv_to =
+ json_object_new_object();
+
+ route_vty_out_advertised_to(
+ vty, peer, &first,
+ " Advertised to:",
+ json_adv_to);
+ }
+ }
+
+ if (json_path) {
+ if (json_adv_to) {
+ json_object_object_add(json_path,
+ "advertisedTo",
+ json_adv_to);
+ }
+ } else {
+ if (!first) {
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+ }
+ }
+
+ /* Line 9 display Uptime */
+ tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
+ if (json_paths) {
+ json_last_update = json_object_new_object();
+ json_object_int_add(json_last_update, "epoch", tbuf);
+ json_object_string_add(json_last_update, "string",
+ ctime(&tbuf));
+ json_object_object_add(json_path, "lastUpdate",
+ json_last_update);
+ } else
+ vty_out(vty, " Last update: %s", ctime(&tbuf));
+ }
+
+ /* We've constructed the json object for this path, add it to the json
+ * array of paths
+ */
+ if (json_paths) {
+ if (json_nexthop_global || json_nexthop_ll) {
+ json_nexthops = json_object_new_array();
+
+ if (json_nexthop_global)
+ json_object_array_add(json_nexthops,
+ json_nexthop_global);
+
+ if (json_nexthop_ll)
+ json_object_array_add(json_nexthops,
+ json_nexthop_ll);
+
+ json_object_object_add(json_path, "nexthops",
+ json_nexthops);
+ }
+
+ json_object_object_add(json_path, "peer", json_peer);
+ json_object_array_add(json_paths, json_path);
+ } else
+ vty_out(vty, "%s", VTY_NEWLINE);
}
#define BGP_SHOW_HEADER_CSV "Flags, Network, Next Hop, Metric, LocPrf, Weight, Path%s"
#define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s"
#define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s"
-static int
-bgp_show_prefix_list (struct vty *vty, struct bgp *bgp,
- const char *prefix_list_str, afi_t afi,
- safi_t safi, enum bgp_show_type type);
-static int
-bgp_show_filter_list (struct vty *vty, struct bgp *bgp,
- const char *filter, afi_t afi,
- safi_t safi, enum bgp_show_type type);
-static int
-bgp_show_route_map (struct vty *vty, struct bgp *bgp,
- const char *rmap_str, afi_t afi,
- safi_t safi, enum bgp_show_type type);
-static int
-bgp_show_community_list (struct vty *vty, struct bgp *bgp,
- const char *com, int exact,
- afi_t afi, safi_t safi);
-static int
-bgp_show_prefix_longer (struct vty *vty, struct bgp *bgp,
- const char *prefix, afi_t afi,
- safi_t safi, enum bgp_show_type type);
-static int
-bgp_show_regexp (struct vty *vty, const char *regstr, afi_t afi,
- safi_t safi, enum bgp_show_type type);
-static int
-bgp_show_community (struct vty *vty, struct bgp *bgp, int argc,
- struct cmd_token **argv, int exact, afi_t afi, safi_t safi);
-
-static int
-bgp_show_table (struct vty *vty, struct bgp *bgp, struct bgp_table *table,
- enum bgp_show_type type, void *output_arg, u_char use_json)
-{
- struct bgp_info *ri;
- struct bgp_node *rn;
- int header = 1;
- int display;
- unsigned long output_count;
- unsigned long total_count;
- struct prefix *p;
- char buf[BUFSIZ];
- char buf2[BUFSIZ];
- json_object *json_paths = NULL;
- int first = 1;
-
- if (use_json)
- {
- vty_out (vty, "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64 ", \"routerId\": \"%s\", \"routes\": { ",
- bgp->vrf_id == VRF_UNKNOWN ? -1 : bgp->vrf_id,
- bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default" : bgp->name,
- table->version, inet_ntoa (bgp->router_id));
- json_paths = json_object_new_object();
- }
+static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
+ const char *prefix_list_str, afi_t afi,
+ safi_t safi, enum bgp_show_type type);
+static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
+ const char *filter, afi_t afi, safi_t safi,
+ enum bgp_show_type type);
+static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
+ const char *rmap_str, afi_t afi, safi_t safi,
+ enum bgp_show_type type);
+static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
+ const char *com, int exact, afi_t afi,
+ safi_t safi);
+static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
+ const char *prefix, afi_t afi, safi_t safi,
+ enum bgp_show_type type);
+static int bgp_show_regexp(struct vty *vty, const char *regstr, afi_t afi,
+ safi_t safi, enum bgp_show_type type);
+static int bgp_show_community(struct vty *vty, struct bgp *bgp, int argc,
+ struct cmd_token **argv, int exact, afi_t afi,
+ safi_t safi);
+
+static int bgp_show_table(struct vty *vty, struct bgp *bgp,
+ struct bgp_table *table, enum bgp_show_type type,
+ void *output_arg, u_char use_json)
+{
+ struct bgp_info *ri;
+ struct bgp_node *rn;
+ int header = 1;
+ int display;
+ unsigned long output_count;
+ unsigned long total_count;
+ struct prefix *p;
+ char buf[BUFSIZ];
+ char buf2[BUFSIZ];
+ json_object *json_paths = NULL;
+ int first = 1;
+
+ if (use_json) {
+ vty_out(vty,
+ "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64
+ ", \"routerId\": \"%s\", \"routes\": { ",
+ bgp->vrf_id == VRF_UNKNOWN ? -1 : bgp->vrf_id,
+ bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default"
+ : bgp->name,
+ table->version, inet_ntoa(bgp->router_id));
+ json_paths = json_object_new_object();
+ }
- /* This is first entry point, so reset total line. */
- output_count = 0;
- total_count = 0;
-
- /* Start processing of routes. */
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- if (rn->info != NULL)
- {
- display = 0;
- if (!first && use_json)
- {
- vty_out (vty, ",");
- }
- if (use_json)
- json_paths = json_object_new_array();
- else
- json_paths = NULL;
-
- for (ri = rn->info; ri; ri = ri->next)
- {
- total_count++;
- if (type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_neighbor
- || type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor)
- {
- if (!(ri->extra && ri->extra->damp_info))
- continue;
- }
- if (type == bgp_show_type_regexp)
- {
- regex_t *regex = output_arg;
-
- if (bgp_regexec (regex, ri->attr->aspath) == REG_NOMATCH)
- continue;
- }
- if (type == bgp_show_type_prefix_list)
- {
- struct prefix_list *plist = output_arg;
-
- if (prefix_list_apply (plist, &rn->p) != PREFIX_PERMIT)
- continue;
- }
- if (type == bgp_show_type_filter_list)
- {
- struct as_list *as_list = output_arg;
-
- if (as_list_apply (as_list, ri->attr->aspath) != AS_FILTER_PERMIT)
- continue;
- }
- if (type == bgp_show_type_route_map)
- {
- struct route_map *rmap = output_arg;
- struct bgp_info binfo;
- struct attr dummy_attr;
- struct attr_extra dummy_extra;
- int ret;
-
- dummy_attr.extra = &dummy_extra;
- bgp_attr_dup (&dummy_attr, ri->attr);
-
- binfo.peer = ri->peer;
- binfo.attr = &dummy_attr;
-
- ret = route_map_apply (rmap, &rn->p, RMAP_BGP, &binfo);
- if (ret == RMAP_DENYMATCH)
- continue;
- }
- if (type == bgp_show_type_neighbor
- || type == bgp_show_type_flap_neighbor
- || type == bgp_show_type_damp_neighbor)
- {
- union sockunion *su = output_arg;
-
- if (ri->peer == NULL ||
- ri->peer->su_remote == NULL || ! sockunion_same(ri->peer->su_remote, su))
- continue;
- }
- if (type == bgp_show_type_cidr_only)
- {
- u_int32_t destination;
-
- destination = ntohl (rn->p.u.prefix4.s_addr);
- if (IN_CLASSC (destination) && rn->p.prefixlen == 24)
- continue;
- if (IN_CLASSB (destination) && rn->p.prefixlen == 16)
- continue;
- if (IN_CLASSA (destination) && rn->p.prefixlen == 8)
- continue;
- }
- if (type == bgp_show_type_prefix_longer)
- {
- struct prefix *p = output_arg;
-
- if (! prefix_match (p, &rn->p))
- continue;
- }
- if (type == bgp_show_type_community_all)
- {
- if (! ri->attr->community)
- continue;
- }
- if (type == bgp_show_type_community)
- {
- struct community *com = output_arg;
-
- if (! ri->attr->community ||
- ! community_match (ri->attr->community, com))
- continue;
- }
- if (type == bgp_show_type_community_exact)
- {
- struct community *com = output_arg;
-
- if (! ri->attr->community ||
- ! community_cmp (ri->attr->community, com))
- continue;
- }
- if (type == bgp_show_type_community_list)
- {
- struct community_list *list = output_arg;
-
- if (! community_list_match (ri->attr->community, list))
- continue;
- }
- if (type == bgp_show_type_community_list_exact)
- {
- struct community_list *list = output_arg;
-
- if (! community_list_exact_match (ri->attr->community, list))
- continue;
- }
- if (type == bgp_show_type_lcommunity)
- {
- struct lcommunity *lcom = output_arg;
-
- if (! ri->attr->extra || ! ri->attr->extra->lcommunity ||
- ! lcommunity_match (ri->attr->extra->lcommunity, lcom))
- continue;
- }
- if (type == bgp_show_type_lcommunity_list)
- {
- struct community_list *list = output_arg;
-
- if (! ri->attr->extra ||
- ! lcommunity_list_match (ri->attr->extra->lcommunity, list))
- continue;
- }
- if (type == bgp_show_type_lcommunity_all)
- {
- if (! ri->attr->extra || ! ri->attr->extra->lcommunity)
- continue;
- }
- if (type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor)
- {
- if (! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED)
- || CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
- continue;
- }
-
- if (!use_json && header)
- {
- vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (bgp->router_id), VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- if (type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor)
- vty_out (vty, BGP_SHOW_DAMP_HEADER, VTY_NEWLINE);
- else if (type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_neighbor)
- vty_out (vty, BGP_SHOW_FLAP_HEADER, VTY_NEWLINE);
- else
- vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
- header = 0;
- }
-
- if (type == bgp_show_type_dampend_paths
- || type == bgp_show_type_damp_neighbor)
- damp_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, use_json, json_paths);
- else if (type == bgp_show_type_flap_statistics
- || type == bgp_show_type_flap_neighbor)
- flap_route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, use_json, json_paths);
- else
- route_vty_out (vty, &rn->p, ri, display, SAFI_UNICAST, json_paths);
- display++;
- }
-
- if (display)
- {
- output_count++;
- if (use_json)
- {
- p = &rn->p;
- sprintf(buf2, "%s/%d", inet_ntop (p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen);
- vty_out (vty, "\"%s\": ", buf2);
- vty_out (vty, "%s", json_object_to_json_string (json_paths));
- json_object_free (json_paths);
- first = 0;
-
- }
- }
- }
-
- if (use_json)
- {
- json_object_free (json_paths);
- vty_out (vty, " } }%s", VTY_NEWLINE);
- }
- else
- {
- /* No route is displayed */
- if (output_count == 0)
- {
- if (type == bgp_show_type_normal)
- vty_out (vty, "No BGP prefixes displayed, %ld exist%s", total_count, VTY_NEWLINE);
- }
- else
- vty_out (vty, "%sDisplayed %ld routes and %ld total paths%s",
- VTY_NEWLINE, output_count, total_count, VTY_NEWLINE);
- }
+ /* This is first entry point, so reset total line. */
+ output_count = 0;
+ total_count = 0;
+
+ /* Start processing of routes. */
+ for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn))
+ if (rn->info != NULL) {
+ display = 0;
+ if (!first && use_json) {
+ vty_out(vty, ",");
+ }
+ if (use_json)
+ json_paths = json_object_new_array();
+ else
+ json_paths = NULL;
+
+ for (ri = rn->info; ri; ri = ri->next) {
+ total_count++;
+ if (type == bgp_show_type_flap_statistics
+ || type == bgp_show_type_flap_neighbor
+ || type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor) {
+ if (!(ri->extra
+ && ri->extra->damp_info))
+ continue;
+ }
+ if (type == bgp_show_type_regexp) {
+ regex_t *regex = output_arg;
+
+ if (bgp_regexec(regex, ri->attr->aspath)
+ == REG_NOMATCH)
+ continue;
+ }
+ if (type == bgp_show_type_prefix_list) {
+ struct prefix_list *plist = output_arg;
+
+ if (prefix_list_apply(plist, &rn->p)
+ != PREFIX_PERMIT)
+ continue;
+ }
+ if (type == bgp_show_type_filter_list) {
+ struct as_list *as_list = output_arg;
+
+ if (as_list_apply(as_list,
+ ri->attr->aspath)
+ != AS_FILTER_PERMIT)
+ continue;
+ }
+ if (type == bgp_show_type_route_map) {
+ struct route_map *rmap = output_arg;
+ struct bgp_info binfo;
+ struct attr dummy_attr;
+ struct attr_extra dummy_extra;
+ int ret;
+
+ dummy_attr.extra = &dummy_extra;
+ bgp_attr_dup(&dummy_attr, ri->attr);
+
+ binfo.peer = ri->peer;
+ binfo.attr = &dummy_attr;
+
+ ret = route_map_apply(rmap, &rn->p,
+ RMAP_BGP, &binfo);
+ if (ret == RMAP_DENYMATCH)
+ continue;
+ }
+ if (type == bgp_show_type_neighbor
+ || type == bgp_show_type_flap_neighbor
+ || type == bgp_show_type_damp_neighbor) {
+ union sockunion *su = output_arg;
+
+ if (ri->peer == NULL
+ || ri->peer->su_remote == NULL
+ || !sockunion_same(
+ ri->peer->su_remote, su))
+ continue;
+ }
+ if (type == bgp_show_type_cidr_only) {
+ u_int32_t destination;
+
+ destination =
+ ntohl(rn->p.u.prefix4.s_addr);
+ if (IN_CLASSC(destination)
+ && rn->p.prefixlen == 24)
+ continue;
+ if (IN_CLASSB(destination)
+ && rn->p.prefixlen == 16)
+ continue;
+ if (IN_CLASSA(destination)
+ && rn->p.prefixlen == 8)
+ continue;
+ }
+ if (type == bgp_show_type_prefix_longer) {
+ struct prefix *p = output_arg;
+
+ if (!prefix_match(p, &rn->p))
+ continue;
+ }
+ if (type == bgp_show_type_community_all) {
+ if (!ri->attr->community)
+ continue;
+ }
+ if (type == bgp_show_type_community) {
+ struct community *com = output_arg;
+
+ if (!ri->attr->community
+ || !community_match(
+ ri->attr->community,
+ com))
+ continue;
+ }
+ if (type == bgp_show_type_community_exact) {
+ struct community *com = output_arg;
+
+ if (!ri->attr->community
+ || !community_cmp(
+ ri->attr->community,
+ com))
+ continue;
+ }
+ if (type == bgp_show_type_community_list) {
+ struct community_list *list =
+ output_arg;
+
+ if (!community_list_match(
+ ri->attr->community, list))
+ continue;
+ }
+ if (type
+ == bgp_show_type_community_list_exact) {
+ struct community_list *list =
+ output_arg;
+
+ if (!community_list_exact_match(
+ ri->attr->community, list))
+ continue;
+ }
+ if (type == bgp_show_type_lcommunity) {
+ struct lcommunity *lcom = output_arg;
+
+ if (!ri->attr->extra
+ || !ri->attr->extra->lcommunity
+ || !lcommunity_match(
+ ri->attr->extra
+ ->lcommunity,
+ lcom))
+ continue;
+ }
+ if (type == bgp_show_type_lcommunity_list) {
+ struct community_list *list =
+ output_arg;
+
+ if (!ri->attr->extra
+ || !lcommunity_list_match(
+ ri->attr->extra
+ ->lcommunity,
+ list))
+ continue;
+ }
+ if (type == bgp_show_type_lcommunity_all) {
+ if (!ri->attr->extra
+ || !ri->attr->extra->lcommunity)
+ continue;
+ }
+ if (type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor) {
+ if (!CHECK_FLAG(ri->flags,
+ BGP_INFO_DAMPED)
+ || CHECK_FLAG(ri->flags,
+ BGP_INFO_HISTORY))
+ continue;
+ }
+
+ if (!use_json && header) {
+ vty_out(vty,
+ "BGP table version is %" PRIu64
+ ", local router ID is %s%s",
+ table->version,
+ inet_ntoa(bgp->router_id),
+ VTY_NEWLINE);
+ vty_out(vty, BGP_SHOW_SCODE_HEADER,
+ VTY_NEWLINE, VTY_NEWLINE);
+ vty_out(vty, BGP_SHOW_OCODE_HEADER,
+ VTY_NEWLINE, VTY_NEWLINE);
+ if (type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor)
+ vty_out(vty,
+ BGP_SHOW_DAMP_HEADER,
+ VTY_NEWLINE);
+ else if (
+ type == bgp_show_type_flap_statistics
+ || type == bgp_show_type_flap_neighbor)
+ vty_out(vty,
+ BGP_SHOW_FLAP_HEADER,
+ VTY_NEWLINE);
+ else
+ vty_out(vty, BGP_SHOW_HEADER,
+ VTY_NEWLINE);
+ header = 0;
+ }
+
+ if (type == bgp_show_type_dampend_paths
+ || type == bgp_show_type_damp_neighbor)
+ damp_route_vty_out(
+ vty, &rn->p, ri, display,
+ SAFI_UNICAST, use_json,
+ json_paths);
+ else if (type == bgp_show_type_flap_statistics
+ || type == bgp_show_type_flap_neighbor)
+ flap_route_vty_out(
+ vty, &rn->p, ri, display,
+ SAFI_UNICAST, use_json,
+ json_paths);
+ else
+ route_vty_out(vty, &rn->p, ri, display,
+ SAFI_UNICAST, json_paths);
+ display++;
+ }
+
+ if (display) {
+ output_count++;
+ if (use_json) {
+ p = &rn->p;
+ sprintf(buf2, "%s/%d",
+ inet_ntop(p->family,
+ &p->u.prefix, buf,
+ BUFSIZ),
+ p->prefixlen);
+ vty_out(vty, "\"%s\": ", buf2);
+ vty_out(vty, "%s",
+ json_object_to_json_string(
+ json_paths));
+ json_object_free(json_paths);
+ first = 0;
+ }
+ }
+ }
+
+ if (use_json) {
+ json_object_free(json_paths);
+ vty_out(vty, " } }%s", VTY_NEWLINE);
+ } else {
+ /* No route is displayed */
+ if (output_count == 0) {
+ if (type == bgp_show_type_normal)
+ vty_out(vty,
+ "No BGP prefixes displayed, %ld exist%s",
+ total_count, VTY_NEWLINE);
+ } else
+ vty_out(vty,
+ "%sDisplayed %ld routes and %ld total paths%s",
+ VTY_NEWLINE, output_count, total_count,
+ VTY_NEWLINE);
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
-static int
-bgp_show (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
- enum bgp_show_type type, void *output_arg, u_char use_json)
+static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
+ enum bgp_show_type type, void *output_arg, u_char use_json)
{
- struct bgp_table *table;
+ struct bgp_table *table;
- if (bgp == NULL)
- {
- bgp = bgp_get_default ();
- }
+ if (bgp == NULL) {
+ bgp = bgp_get_default();
+ }
- if (bgp == NULL)
- {
- if (!use_json)
- vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- /* use MPLS and ENCAP specific shows until they are merged */
- if (safi == SAFI_MPLS_VPN)
- {
- return bgp_show_mpls_vpn(vty, afi, NULL, type, output_arg,
- 0, use_json);
- }
+ if (bgp == NULL) {
+ if (!use_json)
+ vty_out(vty, "No BGP process is configured%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ /* use MPLS and ENCAP specific shows until they are merged */
+ if (safi == SAFI_MPLS_VPN) {
+ return bgp_show_mpls_vpn(vty, afi, NULL, type, output_arg, 0,
+ use_json);
+ }
- table = bgp->rib[afi][safi];
+ table = bgp->rib[afi][safi];
- return bgp_show_table (vty, bgp, table, type, output_arg,
- use_json);
+ return bgp_show_table(vty, bgp, table, type, output_arg, use_json);
}
-static void
-bgp_show_all_instances_routes_vty (struct vty *vty, afi_t afi, safi_t safi,
- u_char use_json)
+static void bgp_show_all_instances_routes_vty(struct vty *vty, afi_t afi,
+ safi_t safi, u_char use_json)
{
- struct listnode *node, *nnode;
- struct bgp *bgp;
- int is_first = 1;
+ struct listnode *node, *nnode;
+ struct bgp *bgp;
+ int is_first = 1;
- if (use_json)
- vty_out (vty, "{%s", VTY_NEWLINE);
+ if (use_json)
+ vty_out(vty, "{%s", VTY_NEWLINE);
- for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp))
- {
- if (use_json)
- {
- if (! is_first)
- vty_out (vty, ",%s", VTY_NEWLINE);
- else
- is_first = 0;
-
- vty_out(vty, "\"%s\":", (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default" : bgp->name);
- }
- else
- {
- vty_out (vty, "%sInstance %s:%s",
- VTY_NEWLINE,
- (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default" : bgp->name,
- VTY_NEWLINE);
- }
- bgp_show (vty, bgp, afi, safi, bgp_show_type_normal, NULL, use_json);
-
- }
+ for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+ if (use_json) {
+ if (!is_first)
+ vty_out(vty, ",%s", VTY_NEWLINE);
+ else
+ is_first = 0;
+
+ vty_out(vty, "\"%s\":",
+ (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+ ? "Default"
+ : bgp->name);
+ } else {
+ vty_out(vty, "%sInstance %s:%s", VTY_NEWLINE,
+ (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+ ? "Default"
+ : bgp->name,
+ VTY_NEWLINE);
+ }
+ bgp_show(vty, bgp, afi, safi, bgp_show_type_normal, NULL,
+ use_json);
+ }
- if (use_json)
- vty_out (vty, "}%s", VTY_NEWLINE);
+ if (use_json)
+ vty_out(vty, "}%s", VTY_NEWLINE);
}
/* Header of detailed BGP route information */
-static void
-route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
- struct bgp_node *rn,
- struct prefix_rd *prd, afi_t afi, safi_t safi,
- json_object *json)
-{
- struct bgp_info *ri;
- struct prefix *p;
- struct peer *peer;
- struct listnode *node, *nnode;
- char buf1[INET6_ADDRSTRLEN];
- char buf2[INET6_ADDRSTRLEN];
- int count = 0;
- int best = 0;
- int suppress = 0;
- int no_export = 0;
- int no_advertise = 0;
- int local_as = 0;
- int first = 1;
- json_object *json_adv_to = NULL;
-
- p = &rn->p;
-
- if (json)
- {
- json_object_string_add(json, "prefix", inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN));
- json_object_int_add(json, "prefixlen", p->prefixlen);
- }
- else
- {
- if (p->family == AF_ETHERNET)
- prefix2str (p, buf2, INET6_ADDRSTRLEN);
- else
- inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN);
- vty_out (vty, "BGP routing table entry for %s%s%s/%d%s",
- ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) ?
- prefix_rd2str (prd, buf1, RD_ADDRSTRLEN) : ""),
- ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) ? ":" : "",
- buf2,
- p->prefixlen, VTY_NEWLINE);
- }
+static void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
+ struct bgp_node *rn,
+ struct prefix_rd *prd, afi_t afi,
+ safi_t safi, json_object *json)
+{
+ struct bgp_info *ri;
+ struct prefix *p;
+ struct peer *peer;
+ struct listnode *node, *nnode;
+ char buf1[INET6_ADDRSTRLEN];
+ char buf2[INET6_ADDRSTRLEN];
+ int count = 0;
+ int best = 0;
+ int suppress = 0;
+ int no_export = 0;
+ int no_advertise = 0;
+ int local_as = 0;
+ int first = 1;
+ json_object *json_adv_to = NULL;
- for (ri = rn->info; ri; ri = ri->next)
- {
- count++;
- if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
- {
- best = count;
- if (ri->extra && ri->extra->suppress)
- suppress = 1;
- if (ri->attr->community != NULL)
- {
- if (community_include (ri->attr->community, COMMUNITY_NO_ADVERTISE))
- no_advertise = 1;
- if (community_include (ri->attr->community, COMMUNITY_NO_EXPORT))
- no_export = 1;
- if (community_include (ri->attr->community, COMMUNITY_LOCAL_AS))
- local_as = 1;
- }
+ p = &rn->p;
+
+ if (json) {
+ json_object_string_add(json, "prefix",
+ inet_ntop(p->family, &p->u.prefix, buf2,
+ INET6_ADDRSTRLEN));
+ json_object_int_add(json, "prefixlen", p->prefixlen);
+ } else {
+ if (p->family == AF_ETHERNET)
+ prefix2str(p, buf2, INET6_ADDRSTRLEN);
+ else
+ inet_ntop(p->family, &p->u.prefix, buf2,
+ INET6_ADDRSTRLEN);
+ vty_out(vty, "BGP routing table entry for %s%s%s/%d%s",
+ ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
+ || safi == SAFI_EVPN)
+ ? prefix_rd2str(prd, buf1, RD_ADDRSTRLEN)
+ : ""),
+ ((safi == SAFI_MPLS_VPN) || (safi == SAFI_EVPN)) ? ":"
+ : "",
+ buf2, p->prefixlen, VTY_NEWLINE);
}
- }
- if (!json)
- {
- vty_out (vty, "Paths: (%d available", count);
- if (best)
- {
- vty_out (vty, ", best #%d", best);
- if (safi == SAFI_UNICAST)
- vty_out (vty, ", table %s",
- (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
- ? "Default-IP-Routing-Table" : bgp->name);
- }
- else
- vty_out (vty, ", no best path");
-
- if (no_advertise)
- vty_out (vty, ", not advertised to any peer");
- else if (no_export)
- vty_out (vty, ", not advertised to EBGP peer");
- else if (local_as)
- vty_out (vty, ", not advertised outside local AS");
-
- if (suppress)
- vty_out (vty, ", Advertisements suppressed by an aggregate.");
- vty_out (vty, ")%s", VTY_NEWLINE);
- }
+ for (ri = rn->info; ri; ri = ri->next) {
+ count++;
+ if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
+ best = count;
+ if (ri->extra && ri->extra->suppress)
+ suppress = 1;
+ if (ri->attr->community != NULL) {
+ if (community_include(ri->attr->community,
+ COMMUNITY_NO_ADVERTISE))
+ no_advertise = 1;
+ if (community_include(ri->attr->community,
+ COMMUNITY_NO_EXPORT))
+ no_export = 1;
+ if (community_include(ri->attr->community,
+ COMMUNITY_LOCAL_AS))
+ local_as = 1;
+ }
+ }
+ }
- /* If we are not using addpath then we can display Advertised to and that will
- * show what peers we advertised the bestpath to. If we are using addpath
- * though then we must display Advertised to on a path-by-path basis. */
- if (!bgp->addpath_tx_used[afi][safi])
- {
- for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer))
- {
- if (bgp_adj_out_lookup (peer, rn, 0))
- {
- if (json && !json_adv_to)
- json_adv_to = json_object_new_object();
-
- route_vty_out_advertised_to(vty, peer, &first,
- " Advertised to non peer-group peers:\n ",
- json_adv_to);
- }
- }
-
- if (json)
- {
- if (json_adv_to)
- {
- json_object_object_add(json, "advertisedTo", json_adv_to);
- }
- }
- else
- {
- if (first)
- vty_out (vty, " Not advertised to any peer");
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- }
+ if (!json) {
+ vty_out(vty, "Paths: (%d available", count);
+ if (best) {
+ vty_out(vty, ", best #%d", best);
+ if (safi == SAFI_UNICAST)
+ vty_out(vty, ", table %s",
+ (bgp->inst_type
+ == BGP_INSTANCE_TYPE_DEFAULT)
+ ? "Default-IP-Routing-Table"
+ : bgp->name);
+ } else
+ vty_out(vty, ", no best path");
+
+ if (no_advertise)
+ vty_out(vty, ", not advertised to any peer");
+ else if (no_export)
+ vty_out(vty, ", not advertised to EBGP peer");
+ else if (local_as)
+ vty_out(vty, ", not advertised outside local AS");
+
+ if (suppress)
+ vty_out(vty,
+ ", Advertisements suppressed by an aggregate.");
+ vty_out(vty, ")%s", VTY_NEWLINE);
+ }
+
+ /* If we are not using addpath then we can display Advertised to and
+ * that will
+ * show what peers we advertised the bestpath to. If we are using
+ * addpath
+ * though then we must display Advertised to on a path-by-path basis. */
+ if (!bgp->addpath_tx_used[afi][safi]) {
+ for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+ if (bgp_adj_out_lookup(peer, rn, 0)) {
+ if (json && !json_adv_to)
+ json_adv_to = json_object_new_object();
+
+ route_vty_out_advertised_to(
+ vty, peer, &first,
+ " Advertised to non peer-group peers:\n ",
+ json_adv_to);
+ }
+ }
+
+ if (json) {
+ if (json_adv_to) {
+ json_object_object_add(json, "advertisedTo",
+ json_adv_to);
+ }
+ } else {
+ if (first)
+ vty_out(vty, " Not advertised to any peer");
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+ }
}
/* Display specified route of BGP table. */
-static int
-bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
- struct bgp_table *rib, const char *ip_str,
- afi_t afi, safi_t safi, struct prefix_rd *prd,
- int prefix_check, enum bgp_path_type pathtype,
- u_char use_json)
-{
- int ret;
- int header;
- int display = 0;
- struct prefix match;
- struct bgp_node *rn;
- struct bgp_node *rm;
- struct bgp_info *ri;
- struct bgp_table *table;
- json_object *json = NULL;
- json_object *json_paths = NULL;
-
- /* Check IP address argument. */
- ret = str2prefix (ip_str, &match);
- if (! ret)
- {
- vty_out (vty, "address is malformed%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- match.family = afi2family (afi);
+static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp,
+ struct bgp_table *rib, const char *ip_str,
+ afi_t afi, safi_t safi,
+ struct prefix_rd *prd, int prefix_check,
+ enum bgp_path_type pathtype, u_char use_json)
+{
+ int ret;
+ int header;
+ int display = 0;
+ struct prefix match;
+ struct bgp_node *rn;
+ struct bgp_node *rm;
+ struct bgp_info *ri;
+ struct bgp_table *table;
+ json_object *json = NULL;
+ json_object *json_paths = NULL;
+
+ /* Check IP address argument. */
+ ret = str2prefix(ip_str, &match);
+ if (!ret) {
+ vty_out(vty, "address is malformed%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- if (use_json)
- {
- json = json_object_new_object();
- json_paths = json_object_new_array();
- }
+ match.family = afi2family(afi);
- if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN)
- {
- for (rn = bgp_table_top (rib); rn; rn = bgp_route_next (rn))
- {
- if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
- continue;
-
- if ((table = rn->info) != NULL)
- {
- header = 1;
-
- if ((rm = bgp_node_match (table, &match)) != NULL)
- {
- if (prefix_check && rm->p.prefixlen != match.prefixlen)
- {
- bgp_unlock_node (rm);
- continue;
- }
-
- for (ri = rm->info; ri; ri = ri->next)
- {
- if (header)
- {
- route_vty_out_detail_header (vty, bgp, rm, (struct prefix_rd *)&rn->p,
- AFI_IP, safi, json);
- header = 0;
- }
- display++;
-
- if (pathtype == BGP_PATH_ALL ||
- (pathtype == BGP_PATH_BESTPATH && CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) ||
- (pathtype == BGP_PATH_MULTIPATH &&
- (CHECK_FLAG (ri->flags, BGP_INFO_MULTIPATH) || CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))))
- route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, safi, json_paths);
- }
-
- bgp_unlock_node (rm);
- }
- }
- }
- }
- else
- {
- header = 1;
-
- if ((rn = bgp_node_match (rib, &match)) != NULL)
- {
- if (! prefix_check || rn->p.prefixlen == match.prefixlen)
- {
- for (ri = rn->info; ri; ri = ri->next)
- {
- if (header)
- {
- route_vty_out_detail_header (vty, bgp, rn, NULL, afi, safi, json);
- header = 0;
- }
- display++;
-
- if (pathtype == BGP_PATH_ALL ||
- (pathtype == BGP_PATH_BESTPATH && CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)) ||
- (pathtype == BGP_PATH_MULTIPATH &&
- (CHECK_FLAG (ri->flags, BGP_INFO_MULTIPATH) || CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))))
- route_vty_out_detail (vty, bgp, &rn->p, ri, afi, safi, json_paths);
- }
- }
-
- bgp_unlock_node (rn);
- }
- }
+ if (use_json) {
+ json = json_object_new_object();
+ json_paths = json_object_new_array();
+ }
- if (use_json)
- {
- if (display)
- json_object_object_add(json, "paths", json_paths);
+ if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN) {
+ for (rn = bgp_table_top(rib); rn; rn = bgp_route_next(rn)) {
+ if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
+ continue;
+
+ if ((table = rn->info) != NULL) {
+ header = 1;
+
+ if ((rm = bgp_node_match(table, &match))
+ != NULL) {
+ if (prefix_check
+ && rm->p.prefixlen
+ != match.prefixlen) {
+ bgp_unlock_node(rm);
+ continue;
+ }
+
+ for (ri = rm->info; ri; ri = ri->next) {
+ if (header) {
+ route_vty_out_detail_header(
+ vty, bgp, rm,
+ (struct
+ prefix_rd *)&rn
+ ->p,
+ AFI_IP, safi,
+ json);
+ header = 0;
+ }
+ display++;
+
+ if (pathtype == BGP_PATH_ALL
+ || (pathtype
+ == BGP_PATH_BESTPATH
+ && CHECK_FLAG(
+ ri->flags,
+ BGP_INFO_SELECTED))
+ || (pathtype
+ == BGP_PATH_MULTIPATH
+ && (CHECK_FLAG(
+ ri->flags,
+ BGP_INFO_MULTIPATH)
+ || CHECK_FLAG(
+ ri->flags,
+ BGP_INFO_SELECTED))))
+ route_vty_out_detail(
+ vty, bgp,
+ &rm->p, ri,
+ AFI_IP, safi,
+ json_paths);
+ }
+
+ bgp_unlock_node(rm);
+ }
+ }
+ }
+ } else {
+ header = 1;
+
+ if ((rn = bgp_node_match(rib, &match)) != NULL) {
+ if (!prefix_check
+ || rn->p.prefixlen == match.prefixlen) {
+ for (ri = rn->info; ri; ri = ri->next) {
+ if (header) {
+ route_vty_out_detail_header(
+ vty, bgp, rn, NULL, afi,
+ safi, json);
+ header = 0;
+ }
+ display++;
+
+ if (pathtype == BGP_PATH_ALL
+ || (pathtype == BGP_PATH_BESTPATH
+ && CHECK_FLAG(
+ ri->flags,
+ BGP_INFO_SELECTED))
+ || (pathtype == BGP_PATH_MULTIPATH
+ && (CHECK_FLAG(
+ ri->flags,
+ BGP_INFO_MULTIPATH)
+ || CHECK_FLAG(
+ ri->flags,
+ BGP_INFO_SELECTED))))
+ route_vty_out_detail(
+ vty, bgp, &rn->p, ri,
+ afi, safi, json_paths);
+ }
+ }
+
+ bgp_unlock_node(rn);
+ }
+ }
- vty_out (vty, "%s%s", json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY), VTY_NEWLINE);
- json_object_free(json);
- }
- else
- {
- if (!display)
- {
- vty_out (vty, "%% Network not in table%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
+ if (use_json) {
+ if (display)
+ json_object_object_add(json, "paths", json_paths);
+
+ vty_out(vty, "%s%s", json_object_to_json_string_ext(
+ json, JSON_C_TO_STRING_PRETTY),
+ VTY_NEWLINE);
+ json_object_free(json);
+ } else {
+ if (!display) {
+ vty_out(vty, "%% Network not in table%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
/* Display specified route of Main RIB */
-static int
-bgp_show_route (struct vty *vty, struct bgp *bgp, const char *ip_str,
- afi_t afi, safi_t safi, struct prefix_rd *prd,
- int prefix_check, enum bgp_path_type pathtype,
- u_char use_json)
-{
- if (!bgp)
- bgp = bgp_get_default ();
-
- return bgp_show_route_in_table (vty, bgp, bgp->rib[afi][safi], ip_str,
- afi, safi, prd, prefix_check, pathtype,
- use_json);
-}
-
-static int
-bgp_show_lcommunity (struct vty *vty, struct bgp *bgp, int argc,
- struct cmd_token **argv, afi_t afi, safi_t safi, u_char uj)
-{
- struct lcommunity *lcom;
- struct buffer *b;
- int i;
- char *str;
- int first = 0;
-
- b = buffer_new (1024);
- for (i = 0; i < argc; i++)
- {
- if (first)
- buffer_putc (b, ' ');
- else
- {
- if (strmatch (argv[i]->text, "AA:BB:CC"))
- {
- first = 1;
- buffer_putstr (b, argv[i]->arg);
- }
- }
- }
- buffer_putc (b, '\0');
+static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
+ afi_t afi, safi_t safi, struct prefix_rd *prd,
+ int prefix_check, enum bgp_path_type pathtype,
+ u_char use_json)
+{
+ if (!bgp)
+ bgp = bgp_get_default();
+
+ return bgp_show_route_in_table(vty, bgp, bgp->rib[afi][safi], ip_str,
+ afi, safi, prd, prefix_check, pathtype,
+ use_json);
+}
+
+static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
+ struct cmd_token **argv, afi_t afi, safi_t safi,
+ u_char uj)
+{
+ struct lcommunity *lcom;
+ struct buffer *b;
+ int i;
+ char *str;
+ int first = 0;
+
+ b = buffer_new(1024);
+ for (i = 0; i < argc; i++) {
+ if (first)
+ buffer_putc(b, ' ');
+ else {
+ if (strmatch(argv[i]->text, "AA:BB:CC")) {
+ first = 1;
+ buffer_putstr(b, argv[i]->arg);
+ }
+ }
+ }
+ buffer_putc(b, '\0');
- str = buffer_getstr (b);
- buffer_free (b);
+ str = buffer_getstr(b);
+ buffer_free(b);
- lcom = lcommunity_str2com (str);
- XFREE (MTYPE_TMP, str);
- if (! lcom)
- {
- vty_out (vty, "%% Large-community malformed%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ lcom = lcommunity_str2com(str);
+ XFREE(MTYPE_TMP, str);
+ if (!lcom) {
+ vty_out(vty, "%% Large-community malformed%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity, lcom, uj);
+ return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity, lcom,
+ uj);
}
-static int
-bgp_show_lcommunity_list (struct vty *vty, struct bgp *bgp, const char *lcom,
- afi_t afi, safi_t safi, u_char uj)
+static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
+ const char *lcom, afi_t afi, safi_t safi,
+ u_char uj)
{
- struct community_list *list;
+ struct community_list *list;
- list = community_list_lookup (bgp_clist, lcom, LARGE_COMMUNITY_LIST_MASTER);
- if (list == NULL)
- {
- vty_out (vty, "%% %s is not a valid large-community-list name%s", lcom,
- VTY_NEWLINE);
- return CMD_WARNING;
- }
+ list = community_list_lookup(bgp_clist, lcom,
+ LARGE_COMMUNITY_LIST_MASTER);
+ if (list == NULL) {
+ vty_out(vty, "%% %s is not a valid large-community-list name%s",
+ lcom, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity_list, list, uj);
+ return bgp_show(vty, bgp, afi, safi, bgp_show_type_lcommunity_list,
+ list, uj);
}
DEFUN (show_ip_bgp_large_community_list,
@@ -8222,33 +8338,35 @@ DEFUN (show_ip_bgp_large_community_list,
"large-community-list name\n"
JSON_STR)
{
- char *vrf = NULL;
- afi_t afi = AFI_IP6;
- safi_t safi = SAFI_UNICAST;
- int idx = 0;
-
- if (argv_find (argv, argc, "ip", &idx))
- afi = AFI_IP;
- if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
- vrf = argv[++idx]->arg;
- if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
- {
- afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
- if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
- safi = bgp_vty_safi_from_arg (argv[idx]->text);
- }
-
- int uj = use_json (argc, argv);
-
- struct bgp *bgp = bgp_lookup_by_name (vrf);
- if (bgp == NULL)
- {
- vty_out (vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- argv_find (argv, argc, "large-community-list", &idx);
- return bgp_show_lcommunity_list (vty, bgp, argv[idx+1]->arg, afi, safi, uj);
+ char *vrf = NULL;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ int idx = 0;
+
+ if (argv_find(argv, argc, "ip", &idx))
+ afi = AFI_IP;
+ if (argv_find(argv, argc, "view", &idx)
+ || argv_find(argv, argc, "vrf", &idx))
+ vrf = argv[++idx]->arg;
+ if (argv_find(argv, argc, "ipv4", &idx)
+ || argv_find(argv, argc, "ipv6", &idx)) {
+ afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
+ if (argv_find(argv, argc, "unicast", &idx)
+ || argv_find(argv, argc, "multicast", &idx))
+ safi = bgp_vty_safi_from_arg(argv[idx]->text);
+ }
+
+ int uj = use_json(argc, argv);
+
+ struct bgp *bgp = bgp_lookup_by_name(vrf);
+ if (bgp == NULL) {
+ vty_out(vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ argv_find(argv, argc, "large-community-list", &idx);
+ return bgp_show_lcommunity_list(vty, bgp, argv[idx + 1]->arg, afi, safi,
+ uj);
}
DEFUN (show_ip_bgp_large_community,
show_ip_bgp_large_community_cmd,
@@ -8266,38 +8384,41 @@ DEFUN (show_ip_bgp_large_community,
"List of large-community numbers\n"
JSON_STR)
{
- char *vrf = NULL;
- afi_t afi = AFI_IP6;
- safi_t safi = SAFI_UNICAST;
- int idx = 0;
-
- if (argv_find (argv, argc, "ip", &idx))
- afi = AFI_IP;
- if (argv_find (argv, argc, "view", &idx) || argv_find (argv, argc, "vrf", &idx))
- vrf = argv[++idx]->arg;
- if (argv_find (argv, argc, "ipv4", &idx) || argv_find (argv, argc, "ipv6", &idx))
- {
- afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
- if (argv_find (argv, argc, "unicast", &idx) || argv_find (argv, argc, "multicast", &idx))
- safi = bgp_vty_safi_from_arg (argv[idx]->text);
- }
-
- int uj = use_json (argc, argv);
-
- struct bgp *bgp = bgp_lookup_by_name (vrf);
- if (bgp == NULL)
- {
- vty_out (vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- if (argv_find (argv, argc, "AA:BB:CC", &idx))
- return bgp_show_lcommunity (vty, bgp, argc, argv, afi, safi, uj);
- else
- return bgp_show (vty, bgp, afi, safi, bgp_show_type_lcommunity_all, NULL, uj);
+ char *vrf = NULL;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ int idx = 0;
+
+ if (argv_find(argv, argc, "ip", &idx))
+ afi = AFI_IP;
+ if (argv_find(argv, argc, "view", &idx)
+ || argv_find(argv, argc, "vrf", &idx))
+ vrf = argv[++idx]->arg;
+ if (argv_find(argv, argc, "ipv4", &idx)
+ || argv_find(argv, argc, "ipv6", &idx)) {
+ afi = strmatch(argv[idx]->text, "ipv6") ? AFI_IP6 : AFI_IP;
+ if (argv_find(argv, argc, "unicast", &idx)
+ || argv_find(argv, argc, "multicast", &idx))
+ safi = bgp_vty_safi_from_arg(argv[idx]->text);
+ }
+
+ int uj = use_json(argc, argv);
+
+ struct bgp *bgp = bgp_lookup_by_name(vrf);
+ if (bgp == NULL) {
+ vty_out(vty, "Can't find BGP instance %s%s", vrf, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ if (argv_find(argv, argc, "AA:BB:CC", &idx))
+ return bgp_show_lcommunity(vty, bgp, argc, argv, afi, safi, uj);
+ else
+ return bgp_show(vty, bgp, afi, safi,
+ bgp_show_type_lcommunity_all, NULL, uj);
}
-static int bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi);
+static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
+ safi_t safi);
/* BGP route print out function. */
DEFUN (show_ip_bgp,
@@ -8349,76 +8470,88 @@ DEFUN (show_ip_bgp,
"Display route and more specific routes\n"
JSON_STR)
{
- afi_t afi = AFI_IP6;
- safi_t safi = SAFI_UNICAST;
- int exact_match = 0;
- enum bgp_show_type sh_type = bgp_show_type_normal;
- struct bgp *bgp = NULL;
- int idx = 0;
-
- bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
- if (!idx)
- return CMD_WARNING;
-
- int uj = use_json (argc, argv);
- if (uj) argc--;
-
- if (argv_find(argv, argc, "cidr-only", &idx))
- return bgp_show (vty, bgp, afi, safi, bgp_show_type_cidr_only, NULL, uj);
-
- if (argv_find(argv, argc, "dampening", &idx))
- {
- if (argv_find (argv, argc, "dampened-paths", &idx))
- return bgp_show (vty, bgp, afi, safi, bgp_show_type_dampend_paths, NULL, uj);
- else if (argv_find (argv, argc, "flap-statistics", &idx))
- return bgp_show (vty, bgp, afi, safi, bgp_show_type_flap_statistics, NULL, uj);
- else if (argv_find (argv, argc, "parameters", &idx))
- return bgp_show_dampening_parameters (vty, afi, safi);
- }
-
- if (argv_find(argv, argc, "prefix-list", &idx))
- return bgp_show_prefix_list (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_prefix_list);
-
- if (argv_find(argv, argc, "filter-list", &idx))
- return bgp_show_filter_list (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_filter_list);
-
- if (argv_find(argv, argc, "statistics", &idx))
- return bgp_table_stats (vty, bgp, afi, safi);
-
- if (argv_find(argv, argc, "route-map", &idx))
- return bgp_show_route_map (vty, bgp, argv[idx + 1]->arg, afi, safi, bgp_show_type_route_map);
-
- if (argv_find(argv, argc, "community", &idx))
- {
- /* show a specific community */
- if (argv_find (argv, argc, "local-AS", &idx) ||
- argv_find (argv, argc, "no-advertise", &idx) ||
- argv_find (argv, argc, "no-export", &idx))
- {
- if (argv_find (argv, argc, "exact_match", &idx))
- exact_match = 1;
- return bgp_show_community (vty, bgp, argc, argv, exact_match, afi, safi);
- }
- /* show all communities */
- else
- return bgp_show (vty, bgp, afi, safi, bgp_show_type_community_all, NULL, uj);
- }
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ int exact_match = 0;
+ enum bgp_show_type sh_type = bgp_show_type_normal;
+ struct bgp *bgp = NULL;
+ int idx = 0;
+
+ bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
+ &bgp);
+ if (!idx)
+ return CMD_WARNING;
+
+ int uj = use_json(argc, argv);
+ if (uj)
+ argc--;
+
+ if (argv_find(argv, argc, "cidr-only", &idx))
+ return bgp_show(vty, bgp, afi, safi, bgp_show_type_cidr_only,
+ NULL, uj);
+
+ if (argv_find(argv, argc, "dampening", &idx)) {
+ if (argv_find(argv, argc, "dampened-paths", &idx))
+ return bgp_show(vty, bgp, afi, safi,
+ bgp_show_type_dampend_paths, NULL, uj);
+ else if (argv_find(argv, argc, "flap-statistics", &idx))
+ return bgp_show(vty, bgp, afi, safi,
+ bgp_show_type_flap_statistics, NULL,
+ uj);
+ else if (argv_find(argv, argc, "parameters", &idx))
+ return bgp_show_dampening_parameters(vty, afi, safi);
+ }
- if (argv_find(argv, argc, "community-list", &idx))
- {
- const char *clist_number_or_name = argv[++idx]->arg;
- if (++idx < argc && strmatch (argv[idx]->text, "exact-match"))
- exact_match = 1;
- return bgp_show_community_list (vty, bgp, clist_number_or_name, exact_match, afi, safi);
- }
- /* prefix-longer */
- if (argv_find(argv, argc, "A.B.C.D/M", &idx) || argv_find(argv, argc, "X:X::X:X/M", &idx))
- return bgp_show_prefix_longer (vty, bgp, argv[idx]->arg, afi, safi, bgp_show_type_prefix_longer);
+ if (argv_find(argv, argc, "prefix-list", &idx))
+ return bgp_show_prefix_list(vty, bgp, argv[idx + 1]->arg, afi,
+ safi, bgp_show_type_prefix_list);
+
+ if (argv_find(argv, argc, "filter-list", &idx))
+ return bgp_show_filter_list(vty, bgp, argv[idx + 1]->arg, afi,
+ safi, bgp_show_type_filter_list);
+
+ if (argv_find(argv, argc, "statistics", &idx))
+ return bgp_table_stats(vty, bgp, afi, safi);
+
+ if (argv_find(argv, argc, "route-map", &idx))
+ return bgp_show_route_map(vty, bgp, argv[idx + 1]->arg, afi,
+ safi, bgp_show_type_route_map);
+
+ if (argv_find(argv, argc, "community", &idx)) {
+ /* show a specific community */
+ if (argv_find(argv, argc, "local-AS", &idx)
+ || argv_find(argv, argc, "no-advertise", &idx)
+ || argv_find(argv, argc, "no-export", &idx)) {
+ if (argv_find(argv, argc, "exact_match", &idx))
+ exact_match = 1;
+ return bgp_show_community(vty, bgp, argc, argv,
+ exact_match, afi, safi);
+ }
+ /* show all communities */
+ else
+ return bgp_show(vty, bgp, afi, safi,
+ bgp_show_type_community_all, NULL, uj);
+ }
- if (safi == SAFI_MPLS_VPN)
- return bgp_show_mpls_vpn (vty, afi, NULL, bgp_show_type_normal, NULL, 0, uj);
- else
- return bgp_show (vty, bgp, afi, safi, sh_type, NULL, uj);
+ if (argv_find(argv, argc, "community-list", &idx)) {
+ const char *clist_number_or_name = argv[++idx]->arg;
+ if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
+ exact_match = 1;
+ return bgp_show_community_list(vty, bgp, clist_number_or_name,
+ exact_match, afi, safi);
+ }
+ /* prefix-longer */
+ if (argv_find(argv, argc, "A.B.C.D/M", &idx)
+ || argv_find(argv, argc, "X:X::X:X/M", &idx))
+ return bgp_show_prefix_longer(vty, bgp, argv[idx]->arg, afi,
+ safi,
+ bgp_show_type_prefix_longer);
+
+ if (safi == SAFI_MPLS_VPN)
+ return bgp_show_mpls_vpn(vty, afi, NULL, bgp_show_type_normal,
+ NULL, 0, uj);
+ else
+ return bgp_show(vty, bgp, afi, safi, sh_type, NULL, uj);
}
DEFUN (show_ip_bgp_route,
@@ -8439,55 +8572,64 @@ DEFUN (show_ip_bgp_route,
"Display only multipaths\n"
JSON_STR)
{
- int prefix_check = 0;
+ int prefix_check = 0;
- afi_t afi = AFI_IP6;
- safi_t safi = SAFI_UNICAST;
- char *prefix = NULL;
- struct bgp *bgp = NULL;
- enum bgp_path_type path_type;
- u_char uj = use_json(argc, argv);
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ char *prefix = NULL;
+ struct bgp *bgp = NULL;
+ enum bgp_path_type path_type;
+ u_char uj = use_json(argc, argv);
- int idx = 0;
+ int idx = 0;
- bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
- if (!idx)
- return CMD_WARNING;
+ bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
+ &bgp);
+ if (!idx)
+ return CMD_WARNING;
- if (!bgp)
- {
- vty_out (vty, "Specified 'all' vrf's but this command currently only works per view/vrf%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ if (!bgp) {
+ vty_out(vty,
+ "Specified 'all' vrf's but this command currently only works per view/vrf%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
- if (argv_find (argv, argc, "A.B.C.D", &idx) || argv_find (argv, argc, "X:X::X:X", &idx))
- prefix_check = 0;
- else if (argv_find (argv, argc, "A.B.C.D/M", &idx) || argv_find (argv, argc, "X:X::X:X/M", &idx))
- prefix_check = 1;
-
- if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN) && afi != AFI_IP6)
- {
- vty_out (vty, "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN) && afi != AFI_IP)
- {
- vty_out (vty, "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- prefix = argv[idx]->arg;
-
- /* [<bestpath|multipath>] */
- if (argv_find (argv, argc, "bestpath", &idx))
- path_type = BGP_PATH_BESTPATH;
- else if (argv_find (argv, argc, "multipath", &idx))
- path_type = BGP_PATH_MULTIPATH;
- else
- path_type = BGP_PATH_ALL;
+ /* <A.B.C.D|A.B.C.D/M|X:X::X:X|X:X::X:X/M> */
+ if (argv_find(argv, argc, "A.B.C.D", &idx)
+ || argv_find(argv, argc, "X:X::X:X", &idx))
+ prefix_check = 0;
+ else if (argv_find(argv, argc, "A.B.C.D/M", &idx)
+ || argv_find(argv, argc, "X:X::X:X/M", &idx))
+ prefix_check = 1;
+
+ if ((argv[idx]->type == IPV6_TKN || argv[idx]->type == IPV6_PREFIX_TKN)
+ && afi != AFI_IP6) {
+ vty_out(vty,
+ "%% Cannot specify IPv6 address or prefix with IPv4 AFI%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ if ((argv[idx]->type == IPV4_TKN || argv[idx]->type == IPV4_PREFIX_TKN)
+ && afi != AFI_IP) {
+ vty_out(vty,
+ "%% Cannot specify IPv4 address or prefix with IPv6 AFI%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ prefix = argv[idx]->arg;
- return bgp_show_route (vty, bgp, prefix, afi, safi, NULL, prefix_check, path_type, uj);
+ /* [<bestpath|multipath>] */
+ if (argv_find(argv, argc, "bestpath", &idx))
+ path_type = BGP_PATH_BESTPATH;
+ else if (argv_find(argv, argc, "multipath", &idx))
+ path_type = BGP_PATH_MULTIPATH;
+ else
+ path_type = BGP_PATH_ALL;
+
+ return bgp_show_route(vty, bgp, prefix, afi, safi, NULL, prefix_check,
+ path_type, uj);
}
DEFUN (show_ip_bgp_regexp,
@@ -8502,23 +8644,25 @@ DEFUN (show_ip_bgp_regexp,
"Display routes matching the AS path regular expression\n"
"A regular-expression to match the BGP AS paths\n")
{
- afi_t afi = AFI_IP6;
- safi_t safi = SAFI_UNICAST;
- struct bgp *bgp = NULL;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ struct bgp *bgp = NULL;
- int idx = 0;
- bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
- if (!idx)
- return CMD_WARNING;
+ int idx = 0;
+ bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
+ &bgp);
+ if (!idx)
+ return CMD_WARNING;
- // get index of regex
- argv_find (argv, argc, "regexp", &idx);
- idx++;
+ // get index of regex
+ argv_find(argv, argc, "regexp", &idx);
+ idx++;
- char *regstr = argv_concat (argv, argc, idx);
- int rc = bgp_show_regexp (vty, (const char *) regstr, afi, safi, bgp_show_type_regexp);
- XFREE (MTYPE_TMP, regstr);
- return rc;
+ char *regstr = argv_concat(argv, argc, idx);
+ int rc = bgp_show_regexp(vty, (const char *)regstr, afi, safi,
+ bgp_show_type_regexp);
+ XFREE(MTYPE_TMP, regstr);
+ return rc;
}
DEFUN (show_ip_bgp_instance_all,
@@ -8532,274 +8676,265 @@ DEFUN (show_ip_bgp_instance_all,
BGP_SAFI_HELP_STR
JSON_STR)
{
- afi_t afi = AFI_IP;
- safi_t safi = SAFI_UNICAST;
- struct bgp *bgp = NULL;
+ afi_t afi = AFI_IP;
+ safi_t safi = SAFI_UNICAST;
+ struct bgp *bgp = NULL;
- int idx = 0;
- bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
- if (!idx)
- return CMD_WARNING;
+ int idx = 0;
+ bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
+ &bgp);
+ if (!idx)
+ return CMD_WARNING;
- int uj = use_json (argc, argv);
- if (uj) argc--;
+ int uj = use_json(argc, argv);
+ if (uj)
+ argc--;
- bgp_show_all_instances_routes_vty (vty, afi, safi, uj);
- return CMD_SUCCESS;
+ bgp_show_all_instances_routes_vty(vty, afi, safi, uj);
+ return CMD_SUCCESS;
}
-static int
-bgp_show_regexp (struct vty *vty, const char *regstr, afi_t afi,
- safi_t safi, enum bgp_show_type type)
+static int bgp_show_regexp(struct vty *vty, const char *regstr, afi_t afi,
+ safi_t safi, enum bgp_show_type type)
{
- regex_t *regex;
- int rc;
-
- regex = bgp_regcomp (regstr);
- if (! regex)
- {
- vty_out (vty, "Can't compile regexp %s%s", regstr, VTY_NEWLINE);
- return CMD_WARNING;
- }
+ regex_t *regex;
+ int rc;
+
+ regex = bgp_regcomp(regstr);
+ if (!regex) {
+ vty_out(vty, "Can't compile regexp %s%s", regstr, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- rc = bgp_show (vty, NULL, afi, safi, type, regex, 0);
- bgp_regex_free (regex);
- return rc;
+ rc = bgp_show(vty, NULL, afi, safi, type, regex, 0);
+ bgp_regex_free(regex);
+ return rc;
}
-static int
-bgp_show_prefix_list (struct vty *vty, struct bgp *bgp,
- const char *prefix_list_str, afi_t afi,
- safi_t safi, enum bgp_show_type type)
+static int bgp_show_prefix_list(struct vty *vty, struct bgp *bgp,
+ const char *prefix_list_str, afi_t afi,
+ safi_t safi, enum bgp_show_type type)
{
- struct prefix_list *plist;
+ struct prefix_list *plist;
- plist = prefix_list_lookup (afi, prefix_list_str);
- if (plist == NULL)
- {
- vty_out (vty, "%% %s is not a valid prefix-list name%s",
- prefix_list_str, VTY_NEWLINE);
- return CMD_WARNING;
- }
+ plist = prefix_list_lookup(afi, prefix_list_str);
+ if (plist == NULL) {
+ vty_out(vty, "%% %s is not a valid prefix-list name%s",
+ prefix_list_str, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_show (vty, bgp, afi, safi, type, plist, 0);
+ return bgp_show(vty, bgp, afi, safi, type, plist, 0);
}
-static int
-bgp_show_filter_list (struct vty *vty, struct bgp *bgp,
- const char *filter, afi_t afi,
- safi_t safi, enum bgp_show_type type)
+static int bgp_show_filter_list(struct vty *vty, struct bgp *bgp,
+ const char *filter, afi_t afi, safi_t safi,
+ enum bgp_show_type type)
{
- struct as_list *as_list;
+ struct as_list *as_list;
- as_list = as_list_lookup (filter);
- if (as_list == NULL)
- {
- vty_out (vty, "%% %s is not a valid AS-path access-list name%s", filter, VTY_NEWLINE);
- return CMD_WARNING;
- }
+ as_list = as_list_lookup(filter);
+ if (as_list == NULL) {
+ vty_out(vty, "%% %s is not a valid AS-path access-list name%s",
+ filter, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_show (vty, bgp, afi, safi, type, as_list, 0);
+ return bgp_show(vty, bgp, afi, safi, type, as_list, 0);
}
-static int
-bgp_show_route_map (struct vty *vty, struct bgp *bgp,
- const char *rmap_str, afi_t afi,
- safi_t safi, enum bgp_show_type type)
+static int bgp_show_route_map(struct vty *vty, struct bgp *bgp,
+ const char *rmap_str, afi_t afi, safi_t safi,
+ enum bgp_show_type type)
{
- struct route_map *rmap;
+ struct route_map *rmap;
- rmap = route_map_lookup_by_name (rmap_str);
- if (! rmap)
- {
- vty_out (vty, "%% %s is not a valid route-map name%s",
- rmap_str, VTY_NEWLINE);
- return CMD_WARNING;
- }
+ rmap = route_map_lookup_by_name(rmap_str);
+ if (!rmap) {
+ vty_out(vty, "%% %s is not a valid route-map name%s", rmap_str,
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_show (vty, bgp, afi, safi, type, rmap, 0);
+ return bgp_show(vty, bgp, afi, safi, type, rmap, 0);
}
-static int
-bgp_show_community (struct vty *vty, struct bgp *bgp, int argc,
- struct cmd_token **argv, int exact, afi_t afi, safi_t safi)
+static int bgp_show_community(struct vty *vty, struct bgp *bgp, int argc,
+ struct cmd_token **argv, int exact, afi_t afi,
+ safi_t safi)
{
- struct community *com;
- struct buffer *b;
- int i;
- char *str;
- int first = 0;
+ struct community *com;
+ struct buffer *b;
+ int i;
+ char *str;
+ int first = 0;
- b = buffer_new (1024);
- for (i = 0; i < argc; i++)
- {
- if (first)
- buffer_putc (b, ' ');
- else
- {
- if ((strcmp (argv[i]->arg, "unicast") == 0) || (strcmp (argv[i]->arg, "multicast") == 0))
- continue;
- first = 1;
- }
-
- buffer_putstr (b, argv[i]->arg);
- }
- buffer_putc (b, '\0');
+ b = buffer_new(1024);
+ for (i = 0; i < argc; i++) {
+ if (first)
+ buffer_putc(b, ' ');
+ else {
+ if ((strcmp(argv[i]->arg, "unicast") == 0)
+ || (strcmp(argv[i]->arg, "multicast") == 0))
+ continue;
+ first = 1;
+ }
- str = buffer_getstr (b);
- buffer_free (b);
+ buffer_putstr(b, argv[i]->arg);
+ }
+ buffer_putc(b, '\0');
- com = community_str2com (str);
- XFREE (MTYPE_TMP, str);
- if (! com)
- {
- vty_out (vty, "%% Community malformed: %s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ str = buffer_getstr(b);
+ buffer_free(b);
- return bgp_show (vty, bgp, afi, safi,
- (exact ? bgp_show_type_community_exact :
- bgp_show_type_community), com, 0);
+ com = community_str2com(str);
+ XFREE(MTYPE_TMP, str);
+ if (!com) {
+ vty_out(vty, "%% Community malformed: %s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ return bgp_show(vty, bgp, afi, safi,
+ (exact ? bgp_show_type_community_exact
+ : bgp_show_type_community),
+ com, 0);
}
-static int
-bgp_show_community_list (struct vty *vty, struct bgp *bgp,
- const char *com, int exact,
- afi_t afi, safi_t safi)
+static int bgp_show_community_list(struct vty *vty, struct bgp *bgp,
+ const char *com, int exact, afi_t afi,
+ safi_t safi)
{
- struct community_list *list;
+ struct community_list *list;
- list = community_list_lookup (bgp_clist, com, COMMUNITY_LIST_MASTER);
- if (list == NULL)
- {
- vty_out (vty, "%% %s is not a valid community-list name%s", com,
- VTY_NEWLINE);
- return CMD_WARNING;
- }
+ list = community_list_lookup(bgp_clist, com, COMMUNITY_LIST_MASTER);
+ if (list == NULL) {
+ vty_out(vty, "%% %s is not a valid community-list name%s", com,
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_show (vty, bgp, afi, safi,
- (exact ? bgp_show_type_community_list_exact :
- bgp_show_type_community_list), list, 0);
+ return bgp_show(vty, bgp, afi, safi,
+ (exact ? bgp_show_type_community_list_exact
+ : bgp_show_type_community_list),
+ list, 0);
}
-static int
-bgp_show_prefix_longer (struct vty *vty, struct bgp *bgp,
- const char *prefix, afi_t afi,
- safi_t safi, enum bgp_show_type type)
+static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
+ const char *prefix, afi_t afi, safi_t safi,
+ enum bgp_show_type type)
{
- int ret;
- struct prefix *p;
+ int ret;
+ struct prefix *p;
- p = prefix_new();
+ p = prefix_new();
- ret = str2prefix (prefix, p);
- if (! ret)
- {
- vty_out (vty, "%% Malformed Prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- ret = bgp_show (vty, bgp, afi, safi, type, p, 0);
- prefix_free(p);
- return ret;
-}
+ ret = str2prefix(prefix, p);
+ if (!ret) {
+ vty_out(vty, "%% Malformed Prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
-static struct peer *
-peer_lookup_in_view (struct vty *vty, struct bgp *bgp,
- const char *ip_str, u_char use_json)
-{
- int ret;
- struct peer *peer;
- union sockunion su;
+ ret = bgp_show(vty, bgp, afi, safi, type, p, 0);
+ prefix_free(p);
+ return ret;
+}
+
+static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
+ const char *ip_str, u_char use_json)
+{
+ int ret;
+ struct peer *peer;
+ union sockunion su;
+
+ /* Get peer sockunion. */
+ ret = str2sockunion(ip_str, &su);
+ if (ret < 0) {
+ peer = peer_lookup_by_conf_if(bgp, ip_str);
+ if (!peer) {
+ peer = peer_lookup_by_hostname(bgp, ip_str);
+
+ if (!peer) {
+ if (use_json) {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(
+ json_no,
+ "malformedAddressOrName",
+ ip_str);
+ vty_out(vty, "%s%s",
+ json_object_to_json_string(
+ json_no),
+ VTY_NEWLINE);
+ json_object_free(json_no);
+ } else
+ vty_out(vty,
+ "%% Malformed address or name: %s%s",
+ ip_str, VTY_NEWLINE);
+ return NULL;
+ }
+ }
+ return peer;
+ }
- /* Get peer sockunion. */
- ret = str2sockunion (ip_str, &su);
- if (ret < 0)
- {
- peer = peer_lookup_by_conf_if (bgp, ip_str);
- if (!peer)
- {
- peer = peer_lookup_by_hostname(bgp, ip_str);
-
- if (!peer)
- {
- if (use_json)
- {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "malformedAddressOrName", ip_str);
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "%% Malformed address or name: %s%s", ip_str, VTY_NEWLINE);
- return NULL;
- }
- }
- return peer;
- }
+ /* Peer structure lookup. */
+ peer = peer_lookup(bgp, &su);
+ if (!peer) {
+ if (use_json) {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(json_no, "warning",
+ "No such neighbor");
+ vty_out(vty, "%s%s",
+ json_object_to_json_string(json_no),
+ VTY_NEWLINE);
+ json_object_free(json_no);
+ } else
+ vty_out(vty, "No such neighbor%s", VTY_NEWLINE);
+ return NULL;
+ }
- /* Peer structure lookup. */
- peer = peer_lookup (bgp, &su);
- if (! peer)
- {
- if (use_json)
- {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning","No such neighbor");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "No such neighbor%s", VTY_NEWLINE);
- return NULL;
- }
-
- return peer;
-}
-
-enum bgp_stats
-{
- BGP_STATS_MAXBITLEN = 0,
- BGP_STATS_RIB,
- BGP_STATS_PREFIXES,
- BGP_STATS_TOTPLEN,
- BGP_STATS_UNAGGREGATEABLE,
- BGP_STATS_MAX_AGGREGATEABLE,
- BGP_STATS_AGGREGATES,
- BGP_STATS_SPACE,
- BGP_STATS_ASPATH_COUNT,
- BGP_STATS_ASPATH_MAXHOPS,
- BGP_STATS_ASPATH_TOTHOPS,
- BGP_STATS_ASPATH_MAXSIZE,
- BGP_STATS_ASPATH_TOTSIZE,
- BGP_STATS_ASN_HIGHEST,
- BGP_STATS_MAX,
+ return peer;
+}
+
+enum bgp_stats {
+ BGP_STATS_MAXBITLEN = 0,
+ BGP_STATS_RIB,
+ BGP_STATS_PREFIXES,
+ BGP_STATS_TOTPLEN,
+ BGP_STATS_UNAGGREGATEABLE,
+ BGP_STATS_MAX_AGGREGATEABLE,
+ BGP_STATS_AGGREGATES,
+ BGP_STATS_SPACE,
+ BGP_STATS_ASPATH_COUNT,
+ BGP_STATS_ASPATH_MAXHOPS,
+ BGP_STATS_ASPATH_TOTHOPS,
+ BGP_STATS_ASPATH_MAXSIZE,
+ BGP_STATS_ASPATH_TOTSIZE,
+ BGP_STATS_ASN_HIGHEST,
+ BGP_STATS_MAX,
};
-static const char *table_stats_strs[] =
-{
- [BGP_STATS_PREFIXES] = "Total Prefixes",
- [BGP_STATS_TOTPLEN] = "Average prefix length",
- [BGP_STATS_RIB] = "Total Advertisements",
- [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
- [BGP_STATS_MAX_AGGREGATEABLE] = "Maximum aggregateable prefixes",
- [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
- [BGP_STATS_SPACE] = "Address space advertised",
- [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
- [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
- [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
- [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
- [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
- [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
- [BGP_STATS_MAX] = NULL,
+static const char *table_stats_strs[] = {
+ [BGP_STATS_PREFIXES] = "Total Prefixes",
+ [BGP_STATS_TOTPLEN] = "Average prefix length",
+ [BGP_STATS_RIB] = "Total Advertisements",
+ [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes",
+ [BGP_STATS_MAX_AGGREGATEABLE] =
+ "Maximum aggregateable prefixes",
+ [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements",
+ [BGP_STATS_SPACE] = "Address space advertised",
+ [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths",
+ [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)",
+ [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)",
+ [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)",
+ [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)",
+ [BGP_STATS_ASN_HIGHEST] = "Highest public ASN",
+ [BGP_STATS_MAX] = NULL,
};
-struct bgp_table_stats
-{
- struct bgp_table *table;
- unsigned long long counts[BGP_STATS_MAX];
+struct bgp_table_stats {
+ struct bgp_table *table;
+ unsigned long long counts[BGP_STATS_MAX];
};
#if 0
@@ -8818,43 +8953,40 @@ ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
}
#endif
-static int
-bgp_table_stats_walker (struct thread *t)
+static int bgp_table_stats_walker(struct thread *t)
{
- struct bgp_node *rn;
- struct bgp_node *top;
- struct bgp_table_stats *ts = THREAD_ARG (t);
- unsigned int space = 0;
-
- if (!(top = bgp_table_top (ts->table)))
- return 0;
+ struct bgp_node *rn;
+ struct bgp_node *top;
+ struct bgp_table_stats *ts = THREAD_ARG(t);
+ unsigned int space = 0;
- switch (top->p.family)
- {
- case AF_INET:
- space = IPV4_MAX_BITLEN;
- break;
- case AF_INET6:
- space = IPV6_MAX_BITLEN;
- break;
- }
-
- ts->counts[BGP_STATS_MAXBITLEN] = space;
+ if (!(top = bgp_table_top(ts->table)))
+ return 0;
- for (rn = top; rn; rn = bgp_route_next (rn))
- {
- struct bgp_info *ri;
- struct bgp_node *prn = bgp_node_parent_nolock (rn);
- unsigned int rinum = 0;
-
- if (rn == top)
- continue;
-
- if (!rn->info)
- continue;
-
- ts->counts[BGP_STATS_PREFIXES]++;
- ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
+ switch (top->p.family) {
+ case AF_INET:
+ space = IPV4_MAX_BITLEN;
+ break;
+ case AF_INET6:
+ space = IPV6_MAX_BITLEN;
+ break;
+ }
+
+ ts->counts[BGP_STATS_MAXBITLEN] = space;
+
+ for (rn = top; rn; rn = bgp_route_next(rn)) {
+ struct bgp_info *ri;
+ struct bgp_node *prn = bgp_node_parent_nolock(rn);
+ unsigned int rinum = 0;
+
+ if (rn == top)
+ continue;
+
+ if (!rn->info)
+ continue;
+
+ ts->counts[BGP_STATS_PREFIXES]++;
+ ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen;
#if 0
ts->counts[BGP_STATS_AVGPLEN]
@@ -8862,48 +8994,50 @@ bgp_table_stats_walker (struct thread *t)
ts->counts[BGP_STATS_AVGPLEN],
rn->p.prefixlen);
#endif
-
- /* check if the prefix is included by any other announcements */
- while (prn && !prn->info)
- prn = bgp_node_parent_nolock (prn);
-
- if (prn == NULL || prn == top)
- {
- ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
- /* announced address space */
- if (space)
- ts->counts[BGP_STATS_SPACE] += 1 << (space - rn->p.prefixlen);
- }
- else if (prn->info)
- ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
-
- for (ri = rn->info; ri; ri = ri->next)
- {
- rinum++;
- ts->counts[BGP_STATS_RIB]++;
-
- if (ri->attr &&
- (CHECK_FLAG (ri->attr->flag,
- ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE))))
- ts->counts[BGP_STATS_AGGREGATES]++;
-
- /* as-path stats */
- if (ri->attr && ri->attr->aspath)
- {
- unsigned int hops = aspath_count_hops (ri->attr->aspath);
- unsigned int size = aspath_size (ri->attr->aspath);
- as_t highest = aspath_highest (ri->attr->aspath);
-
- ts->counts[BGP_STATS_ASPATH_COUNT]++;
-
- if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
- ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops;
-
- if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
- ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size;
-
- ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
- ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
+
+ /* check if the prefix is included by any other announcements */
+ while (prn && !prn->info)
+ prn = bgp_node_parent_nolock(prn);
+
+ if (prn == NULL || prn == top) {
+ ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
+ /* announced address space */
+ if (space)
+ ts->counts[BGP_STATS_SPACE] +=
+ 1 << (space - rn->p.prefixlen);
+ } else if (prn->info)
+ ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
+
+ for (ri = rn->info; ri; ri = ri->next) {
+ rinum++;
+ ts->counts[BGP_STATS_RIB]++;
+
+ if (ri->attr
+ && (CHECK_FLAG(ri->attr->flag,
+ ATTR_FLAG_BIT(
+ BGP_ATTR_ATOMIC_AGGREGATE))))
+ ts->counts[BGP_STATS_AGGREGATES]++;
+
+ /* as-path stats */
+ if (ri->attr && ri->attr->aspath) {
+ unsigned int hops =
+ aspath_count_hops(ri->attr->aspath);
+ unsigned int size =
+ aspath_size(ri->attr->aspath);
+ as_t highest = aspath_highest(ri->attr->aspath);
+
+ ts->counts[BGP_STATS_ASPATH_COUNT]++;
+
+ if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS])
+ ts->counts[BGP_STATS_ASPATH_MAXHOPS] =
+ hops;
+
+ if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE])
+ ts->counts[BGP_STATS_ASPATH_MAXSIZE] =
+ size;
+
+ ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops;
+ ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size;
#if 0
ts->counts[BGP_STATS_ASPATH_AVGHOPS]
= ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
@@ -8914,41 +9048,39 @@ bgp_table_stats_walker (struct thread *t)
ts->counts[BGP_STATS_ASPATH_AVGSIZE],
size);
#endif
- if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
- ts->counts[BGP_STATS_ASN_HIGHEST] = highest;
- }
- }
- }
- return 0;
+ if (highest > ts->counts[BGP_STATS_ASN_HIGHEST])
+ ts->counts[BGP_STATS_ASN_HIGHEST] =
+ highest;
+ }
+ }
+ }
+ return 0;
}
-static int
-bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi)
+static int bgp_table_stats(struct vty *vty, struct bgp *bgp, afi_t afi,
+ safi_t safi)
{
- struct bgp_table_stats ts;
- unsigned int i;
-
- if (!bgp->rib[afi][safi])
- {
- vty_out (vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
- afi, safi, VTY_NEWLINE);
- return CMD_WARNING;
- }
-
- memset (&ts, 0, sizeof (ts));
- ts.table = bgp->rib[afi][safi];
- thread_execute (bm->master, bgp_table_stats_walker, &ts, 0);
+ struct bgp_table_stats ts;
+ unsigned int i;
- vty_out (vty, "BGP %s RIB statistics%s%s",
- afi_safi_print (afi, safi), VTY_NEWLINE, VTY_NEWLINE);
-
- for (i = 0; i < BGP_STATS_MAX; i++)
- {
- if (!table_stats_strs[i])
- continue;
-
- switch (i)
- {
+ if (!bgp->rib[afi][safi]) {
+ vty_out(vty, "%% No RIB exist's for the AFI(%d)/SAFI(%d)%s",
+ afi, safi, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ memset(&ts, 0, sizeof(ts));
+ ts.table = bgp->rib[afi][safi];
+ thread_execute(bm->master, bgp_table_stats_walker, &ts, 0);
+
+ vty_out(vty, "BGP %s RIB statistics%s%s", afi_safi_print(afi, safi),
+ VTY_NEWLINE, VTY_NEWLINE);
+
+ for (i = 0; i < BGP_STATS_MAX; i++) {
+ if (!table_stats_strs[i])
+ continue;
+
+ switch (i) {
#if 0
case BGP_STATS_ASPATH_AVGHOPS:
case BGP_STATS_ASPATH_AVGSIZE:
@@ -8958,244 +9090,250 @@ bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi)
(float)ts.counts[i] / (float)TALLY_SIGFIG);
break;
#endif
- case BGP_STATS_ASPATH_TOTHOPS:
- case BGP_STATS_ASPATH_TOTSIZE:
- vty_out (vty, "%-30s: ", table_stats_strs[i]);
- vty_out (vty, "%12.2f",
- ts.counts[i] ?
- (float)ts.counts[i] /
- (float)ts.counts[BGP_STATS_ASPATH_COUNT]
- : 0);
- break;
- case BGP_STATS_TOTPLEN:
- vty_out (vty, "%-30s: ", table_stats_strs[i]);
- vty_out (vty, "%12.2f",
- ts.counts[i] ?
- (float)ts.counts[i] /
- (float)ts.counts[BGP_STATS_PREFIXES]
- : 0);
- break;
- case BGP_STATS_SPACE:
- vty_out (vty, "%-30s: ", table_stats_strs[i]);
- vty_out (vty, "%12llu%s", ts.counts[i], VTY_NEWLINE);
- if (ts.counts[BGP_STATS_MAXBITLEN] < 9)
- break;
- vty_out (vty, "%30s: ", "%% announced ");
- vty_out (vty, "%12.2f%s",
- 100 * (float)ts.counts[BGP_STATS_SPACE] /
- (float)((uint64_t)1UL << ts.counts[BGP_STATS_MAXBITLEN]),
- VTY_NEWLINE);
- vty_out (vty, "%30s: ", "/8 equivalent ");
- vty_out (vty, "%12.2f%s",
- (float)ts.counts[BGP_STATS_SPACE] /
- (float)(1UL << (ts.counts[BGP_STATS_MAXBITLEN] - 8)),
- VTY_NEWLINE);
- if (ts.counts[BGP_STATS_MAXBITLEN] < 25)
- break;
- vty_out (vty, "%30s: ", "/24 equivalent ");
- vty_out (vty, "%12.2f",
- (float)ts.counts[BGP_STATS_SPACE] /
- (float)(1UL << (ts.counts[BGP_STATS_MAXBITLEN] - 24)));
- break;
- default:
- vty_out (vty, "%-30s: ", table_stats_strs[i]);
- vty_out (vty, "%12llu", ts.counts[i]);
- }
-
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- return CMD_SUCCESS;
-}
+ case BGP_STATS_ASPATH_TOTHOPS:
+ case BGP_STATS_ASPATH_TOTSIZE:
+ vty_out(vty, "%-30s: ", table_stats_strs[i]);
+ vty_out(vty, "%12.2f",
+ ts.counts[i]
+ ? (float)ts.counts[i]
+ / (float)ts.counts
+ [BGP_STATS_ASPATH_COUNT]
+ : 0);
+ break;
+ case BGP_STATS_TOTPLEN:
+ vty_out(vty, "%-30s: ", table_stats_strs[i]);
+ vty_out(vty, "%12.2f",
+ ts.counts[i]
+ ? (float)ts.counts[i]
+ / (float)ts.counts
+ [BGP_STATS_PREFIXES]
+ : 0);
+ break;
+ case BGP_STATS_SPACE:
+ vty_out(vty, "%-30s: ", table_stats_strs[i]);
+ vty_out(vty, "%12llu%s", ts.counts[i], VTY_NEWLINE);
+ if (ts.counts[BGP_STATS_MAXBITLEN] < 9)
+ break;
+ vty_out(vty, "%30s: ", "%% announced ");
+ vty_out(vty, "%12.2f%s",
+ 100 * (float)ts.counts[BGP_STATS_SPACE]
+ / (float)((uint64_t)1UL
+ << ts.counts
+ [BGP_STATS_MAXBITLEN]),
+ VTY_NEWLINE);
+ vty_out(vty, "%30s: ", "/8 equivalent ");
+ vty_out(vty, "%12.2f%s",
+ (float)ts.counts[BGP_STATS_SPACE]
+ / (float)(1UL
+ << (ts.counts
+ [BGP_STATS_MAXBITLEN]
+ - 8)),
+ VTY_NEWLINE);
+ if (ts.counts[BGP_STATS_MAXBITLEN] < 25)
+ break;
+ vty_out(vty, "%30s: ", "/24 equivalent ");
+ vty_out(vty, "%12.2f",
+ (float)ts.counts[BGP_STATS_SPACE]
+ / (float)(1UL
+ << (ts.counts
+ [BGP_STATS_MAXBITLEN]
+ - 24)));
+ break;
+ default:
+ vty_out(vty, "%-30s: ", table_stats_strs[i]);
+ vty_out(vty, "%12llu", ts.counts[i]);
+ }
-enum bgp_pcounts
-{
- PCOUNT_ADJ_IN = 0,
- PCOUNT_DAMPED,
- PCOUNT_REMOVED,
- PCOUNT_HISTORY,
- PCOUNT_STALE,
- PCOUNT_VALID,
- PCOUNT_ALL,
- PCOUNT_COUNTED,
- PCOUNT_PFCNT, /* the figure we display to users */
- PCOUNT_MAX,
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+ return CMD_SUCCESS;
+}
+
+enum bgp_pcounts {
+ PCOUNT_ADJ_IN = 0,
+ PCOUNT_DAMPED,
+ PCOUNT_REMOVED,
+ PCOUNT_HISTORY,
+ PCOUNT_STALE,
+ PCOUNT_VALID,
+ PCOUNT_ALL,
+ PCOUNT_COUNTED,
+ PCOUNT_PFCNT, /* the figure we display to users */
+ PCOUNT_MAX,
};
-static const char *pcount_strs[] =
-{
- [PCOUNT_ADJ_IN] = "Adj-in",
- [PCOUNT_DAMPED] = "Damped",
- [PCOUNT_REMOVED] = "Removed",
- [PCOUNT_HISTORY] = "History",
- [PCOUNT_STALE] = "Stale",
- [PCOUNT_VALID] = "Valid",
- [PCOUNT_ALL] = "All RIB",
- [PCOUNT_COUNTED] = "PfxCt counted",
- [PCOUNT_PFCNT] = "Useable",
- [PCOUNT_MAX] = NULL,
+static const char *pcount_strs[] = {
+ [PCOUNT_ADJ_IN] = "Adj-in",
+ [PCOUNT_DAMPED] = "Damped",
+ [PCOUNT_REMOVED] = "Removed",
+ [PCOUNT_HISTORY] = "History",
+ [PCOUNT_STALE] = "Stale",
+ [PCOUNT_VALID] = "Valid",
+ [PCOUNT_ALL] = "All RIB",
+ [PCOUNT_COUNTED] = "PfxCt counted",
+ [PCOUNT_PFCNT] = "Useable",
+ [PCOUNT_MAX] = NULL,
};
-struct peer_pcounts
-{
- unsigned int count[PCOUNT_MAX];
- const struct peer *peer;
- const struct bgp_table *table;
+struct peer_pcounts {
+ unsigned int count[PCOUNT_MAX];
+ const struct peer *peer;
+ const struct bgp_table *table;
};
-static int
-bgp_peer_count_walker (struct thread *t)
-{
- struct bgp_node *rn;
- struct peer_pcounts *pc = THREAD_ARG (t);
- const struct peer *peer = pc->peer;
-
- for (rn = bgp_table_top (pc->table); rn; rn = bgp_route_next (rn))
- {
- struct bgp_adj_in *ain;
- struct bgp_info *ri;
-
- for (ain = rn->adj_in; ain; ain = ain->next)
- if (ain->peer == peer)
- pc->count[PCOUNT_ADJ_IN]++;
-
- for (ri = rn->info; ri; ri = ri->next)
- {
- char buf[SU_ADDRSTRLEN];
-
- if (ri->peer != peer)
- continue;
-
- pc->count[PCOUNT_ALL]++;
-
- if (CHECK_FLAG (ri->flags, BGP_INFO_DAMPED))
- pc->count[PCOUNT_DAMPED]++;
- if (CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
- pc->count[PCOUNT_HISTORY]++;
- if (CHECK_FLAG (ri->flags, BGP_INFO_REMOVED))
- pc->count[PCOUNT_REMOVED]++;
- if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
- pc->count[PCOUNT_STALE]++;
- if (CHECK_FLAG (ri->flags, BGP_INFO_VALID))
- pc->count[PCOUNT_VALID]++;
- if (!CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
- pc->count[PCOUNT_PFCNT]++;
-
- if (CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
- {
- pc->count[PCOUNT_COUNTED]++;
- if (CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
- zlog_warn ("%s [pcount] %s/%d is counted but flags 0x%x",
- peer->host,
- inet_ntop(rn->p.family, &rn->p.u.prefix,
- buf, SU_ADDRSTRLEN),
- rn->p.prefixlen,
- ri->flags);
- }
- else
- {
- if (!CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
- zlog_warn ("%s [pcount] %s/%d not counted but flags 0x%x",
- peer->host,
- inet_ntop(rn->p.family, &rn->p.u.prefix,
- buf, SU_ADDRSTRLEN),
- rn->p.prefixlen,
- ri->flags);
- }
- }
- }
- return 0;
+static int bgp_peer_count_walker(struct thread *t)
+{
+ struct bgp_node *rn;
+ struct peer_pcounts *pc = THREAD_ARG(t);
+ const struct peer *peer = pc->peer;
+
+ for (rn = bgp_table_top(pc->table); rn; rn = bgp_route_next(rn)) {
+ struct bgp_adj_in *ain;
+ struct bgp_info *ri;
+
+ for (ain = rn->adj_in; ain; ain = ain->next)
+ if (ain->peer == peer)
+ pc->count[PCOUNT_ADJ_IN]++;
+
+ for (ri = rn->info; ri; ri = ri->next) {
+ char buf[SU_ADDRSTRLEN];
+
+ if (ri->peer != peer)
+ continue;
+
+ pc->count[PCOUNT_ALL]++;
+
+ if (CHECK_FLAG(ri->flags, BGP_INFO_DAMPED))
+ pc->count[PCOUNT_DAMPED]++;
+ if (CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
+ pc->count[PCOUNT_HISTORY]++;
+ if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
+ pc->count[PCOUNT_REMOVED]++;
+ if (CHECK_FLAG(ri->flags, BGP_INFO_STALE))
+ pc->count[PCOUNT_STALE]++;
+ if (CHECK_FLAG(ri->flags, BGP_INFO_VALID))
+ pc->count[PCOUNT_VALID]++;
+ if (!CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
+ pc->count[PCOUNT_PFCNT]++;
+
+ if (CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
+ pc->count[PCOUNT_COUNTED]++;
+ if (CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
+ zlog_warn(
+ "%s [pcount] %s/%d is counted but flags 0x%x",
+ peer->host,
+ inet_ntop(rn->p.family,
+ &rn->p.u.prefix, buf,
+ SU_ADDRSTRLEN),
+ rn->p.prefixlen, ri->flags);
+ } else {
+ if (!CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
+ zlog_warn(
+ "%s [pcount] %s/%d not counted but flags 0x%x",
+ peer->host,
+ inet_ntop(rn->p.family,
+ &rn->p.u.prefix, buf,
+ SU_ADDRSTRLEN),
+ rn->p.prefixlen, ri->flags);
+ }
+ }
+ }
+ return 0;
}
-static int
-bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, u_char use_json)
+static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi,
+ safi_t safi, u_char use_json)
{
- struct peer_pcounts pcounts = { .peer = peer };
- unsigned int i;
- json_object *json = NULL;
- json_object *json_loop = NULL;
+ struct peer_pcounts pcounts = {.peer = peer};
+ unsigned int i;
+ json_object *json = NULL;
+ json_object *json_loop = NULL;
- if (use_json)
- {
- json = json_object_new_object();
- json_loop = json_object_new_object();
- }
-
- if (!peer || !peer->bgp || !peer->afc[afi][safi]
- || !peer->bgp->rib[afi][safi])
- {
- if (use_json)
- {
- json_object_string_add(json, "warning", "No such neighbor or address family");
- vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
- json_object_free(json);
- }
- else
- vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
-
- return CMD_WARNING;
- }
-
- memset (&pcounts, 0, sizeof(pcounts));
- pcounts.peer = peer;
- pcounts.table = peer->bgp->rib[afi][safi];
-
- /* in-place call via thread subsystem so as to record execution time
- * * stats for the thread-walk (i.e. ensure this can't be blamed on
- * * on just vty_read()).
- * */
- thread_execute (bm->master, bgp_peer_count_walker, &pcounts, 0);
+ if (use_json) {
+ json = json_object_new_object();
+ json_loop = json_object_new_object();
+ }
- if (use_json)
- {
- json_object_string_add(json, "prefixCountsFor", peer->host);
- json_object_string_add(json, "multiProtocol", afi_safi_print (afi, safi));
- json_object_int_add(json, "pfxCounter", peer->pcount[afi][safi]);
-
- for (i = 0; i < PCOUNT_MAX; i++)
- json_object_int_add(json_loop, pcount_strs[i], pcounts.count[i]);
-
- json_object_object_add(json, "ribTableWalkCounters", json_loop);
-
- if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi])
- {
- json_object_string_add(json, "pfxctDriftFor", peer->host);
- json_object_string_add(json, "recommended", "Please report this bug, with the above command output");
- }
- vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
- json_object_free(json);
- }
- else
- {
+ if (!peer || !peer->bgp || !peer->afc[afi][safi]
+ || !peer->bgp->rib[afi][safi]) {
+ if (use_json) {
+ json_object_string_add(
+ json, "warning",
+ "No such neighbor or address family");
+ vty_out(vty, "%s%s", json_object_to_json_string(json),
+ VTY_NEWLINE);
+ json_object_free(json);
+ } else
+ vty_out(vty, "%% No such neighbor or address family%s",
+ VTY_NEWLINE);
+
+ return CMD_WARNING;
+ }
- if (peer->hostname && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME))
- {
- vty_out (vty, "Prefix counts for %s/%s, %s%s",
- peer->hostname, peer->host, afi_safi_print (afi, safi),
- VTY_NEWLINE);
- }
- else
- {
- vty_out (vty, "Prefix counts for %s, %s%s",
- peer->host, afi_safi_print (afi, safi), VTY_NEWLINE);
- }
-
- vty_out (vty, "PfxCt: %ld%s", peer->pcount[afi][safi], VTY_NEWLINE);
- vty_out (vty, "%sCounts from RIB table walk:%s%s",
- VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
-
- for (i = 0; i < PCOUNT_MAX; i++)
- vty_out (vty, "%20s: %-10d%s", pcount_strs[i], pcounts.count[i], VTY_NEWLINE);
-
- if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi])
- {
- vty_out (vty, "%s [pcount] PfxCt drift!%s",
- peer->host, VTY_NEWLINE);
- vty_out (vty, "Please report this bug, with the above command output%s",
- VTY_NEWLINE);
- }
- }
-
- return CMD_SUCCESS;
+ memset(&pcounts, 0, sizeof(pcounts));
+ pcounts.peer = peer;
+ pcounts.table = peer->bgp->rib[afi][safi];
+
+ /* in-place call via thread subsystem so as to record execution time
+ * * stats for the thread-walk (i.e. ensure this can't be blamed on
+ * * on just vty_read()).
+ * */
+ thread_execute(bm->master, bgp_peer_count_walker, &pcounts, 0);
+
+ if (use_json) {
+ json_object_string_add(json, "prefixCountsFor", peer->host);
+ json_object_string_add(json, "multiProtocol",
+ afi_safi_print(afi, safi));
+ json_object_int_add(json, "pfxCounter",
+ peer->pcount[afi][safi]);
+
+ for (i = 0; i < PCOUNT_MAX; i++)
+ json_object_int_add(json_loop, pcount_strs[i],
+ pcounts.count[i]);
+
+ json_object_object_add(json, "ribTableWalkCounters", json_loop);
+
+ if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
+ json_object_string_add(json, "pfxctDriftFor",
+ peer->host);
+ json_object_string_add(
+ json, "recommended",
+ "Please report this bug, with the above command output");
+ }
+ vty_out(vty, "%s%s", json_object_to_json_string(json),
+ VTY_NEWLINE);
+ json_object_free(json);
+ } else {
+
+ if (peer->hostname
+ && bgp_flag_check(peer->bgp, BGP_FLAG_SHOW_HOSTNAME)) {
+ vty_out(vty, "Prefix counts for %s/%s, %s%s",
+ peer->hostname, peer->host,
+ afi_safi_print(afi, safi), VTY_NEWLINE);
+ } else {
+ vty_out(vty, "Prefix counts for %s, %s%s", peer->host,
+ afi_safi_print(afi, safi), VTY_NEWLINE);
+ }
+
+ vty_out(vty, "PfxCt: %ld%s", peer->pcount[afi][safi],
+ VTY_NEWLINE);
+ vty_out(vty, "%sCounts from RIB table walk:%s%s", VTY_NEWLINE,
+ VTY_NEWLINE, VTY_NEWLINE);
+
+ for (i = 0; i < PCOUNT_MAX; i++)
+ vty_out(vty, "%20s: %-10d%s", pcount_strs[i],
+ pcounts.count[i], VTY_NEWLINE);
+
+ if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) {
+ vty_out(vty, "%s [pcount] PfxCt drift!%s", peer->host,
+ VTY_NEWLINE);
+ vty_out(vty,
+ "Please report this bug, with the above command output%s",
+ VTY_NEWLINE);
+ }
+ }
+
+ return CMD_SUCCESS;
}
DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
@@ -9218,25 +9356,27 @@ DEFUN (show_ip_bgp_instance_neighbor_prefix_counts,
"Display detailed prefix count information\n"
JSON_STR)
{
- afi_t afi = AFI_IP6;
- safi_t safi = SAFI_UNICAST;
- struct peer *peer;
- int idx = 0;
- struct bgp *bgp = NULL;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ struct peer *peer;
+ int idx = 0;
+ struct bgp *bgp = NULL;
- bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
- if (!idx)
- return CMD_WARNING;
+ bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
+ &bgp);
+ if (!idx)
+ return CMD_WARNING;
- int uj = use_json (argc, argv);
- if (uj) argc--;
+ int uj = use_json(argc, argv);
+ if (uj)
+ argc--;
- argv_find (argv, argc, "neighbors", &idx);
- peer = peer_lookup_in_view (vty, bgp, argv[idx+1]->arg, uj);
- if (! peer)
- return CMD_WARNING;
+ argv_find(argv, argc, "neighbors", &idx);
+ peer = peer_lookup_in_view(vty, bgp, argv[idx + 1]->arg, uj);
+ if (!peer)
+ return CMD_WARNING;
- return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST, uj);
+ return bgp_peer_counts(vty, peer, AFI_IP, SAFI_UNICAST, uj);
}
#ifdef KEEP_OLD_VPN_COMMANDS
@@ -9255,15 +9395,15 @@ DEFUN (show_ip_bgp_vpn_neighbor_prefix_counts,
"Display detailed prefix count information\n"
JSON_STR)
{
- int idx_peer = 6;
- struct peer *peer;
- u_char uj = use_json(argc, argv);
+ int idx_peer = 6;
+ struct peer *peer;
+ u_char uj = use_json(argc, argv);
- peer = peer_lookup_in_view (vty, NULL, argv[idx_peer]->arg, uj);
- if (! peer)
- return CMD_WARNING;
-
- return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
+ peer = peer_lookup_in_view(vty, NULL, argv[idx_peer]->arg, uj);
+ if (!peer)
+ return CMD_WARNING;
+
+ return bgp_peer_counts(vty, peer, AFI_IP, SAFI_MPLS_VPN, uj);
}
DEFUN (show_ip_bgp_vpn_all_route_prefix,
@@ -9278,26 +9418,25 @@ DEFUN (show_ip_bgp_vpn_all_route_prefix,
"Network in the BGP routing table to display\n"
JSON_STR)
{
- int idx = 0;
- char *network = NULL;
- struct bgp *bgp = bgp_get_default();
- if (!bgp)
- {
- vty_out (vty, "Can't find default instance%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ int idx = 0;
+ char *network = NULL;
+ struct bgp *bgp = bgp_get_default();
+ if (!bgp) {
+ vty_out(vty, "Can't find default instance%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- if (argv_find (argv, argc, "A.B.C.D", &idx))
- network = argv[idx]->arg;
- else if (argv_find (argv, argc, "A.B.C.D/M", &idx))
- network = argv[idx]->arg;
- else
- {
- vty_out (vty, "Unable to figure out Network%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ if (argv_find(argv, argc, "A.B.C.D", &idx))
+ network = argv[idx]->arg;
+ else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
+ network = argv[idx]->arg;
+ else {
+ vty_out(vty, "Unable to figure out Network%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_show_route (vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
+ return bgp_show_route(vty, bgp, network, AFI_IP, SAFI_MPLS_VPN, NULL, 0,
+ BGP_PATH_ALL, use_json(argc, argv));
}
#endif /* KEEP_OLD_VPN_COMMANDS */
@@ -9314,259 +9453,305 @@ DEFUN (show_ip_bgp_l2vpn_evpn_all_route_prefix,
"Network in the BGP routing table to display\n"
JSON_STR)
{
- int idx = 0;
- char *network = NULL;
-
- if (argv_find (argv, argc, "A.B.C.D", &idx))
- network = argv[idx]->arg;
- else if (argv_find (argv, argc, "A.B.C.D/M", &idx))
- network = argv[idx]->arg;
- else
- {
- vty_out (vty, "Unable to figure out Network%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show_route (vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL, 0, BGP_PATH_ALL, use_json(argc, argv));
-}
-
- static void
-show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
- int in, const char *rmap_name, u_char use_json, json_object *json)
-{
- struct bgp_table *table;
- struct bgp_adj_in *ain;
- struct bgp_adj_out *adj;
- unsigned long output_count;
- unsigned long filtered_count;
- struct bgp_node *rn;
- int header1 = 1;
- struct bgp *bgp;
- int header2 = 1;
- struct attr attr;
- struct attr_extra extra;
- int ret;
- struct update_subgroup *subgrp;
- json_object *json_scode = NULL;
- json_object *json_ocode = NULL;
- json_object *json_ar = NULL;
- struct peer_af *paf;
-
- if (use_json)
- {
- json_scode = json_object_new_object();
- json_ocode = json_object_new_object();
- json_ar = json_object_new_object();
-
- json_object_string_add(json_scode, "suppressed", "s");
- json_object_string_add(json_scode, "damped", "d");
- json_object_string_add(json_scode, "history", "h");
- json_object_string_add(json_scode, "valid", "*");
- json_object_string_add(json_scode, "best", ">");
- json_object_string_add(json_scode, "multipath", "=");
- json_object_string_add(json_scode, "internal", "i");
- json_object_string_add(json_scode, "ribFailure", "r");
- json_object_string_add(json_scode, "stale", "S");
- json_object_string_add(json_scode, "removed", "R");
-
- json_object_string_add(json_ocode, "igp", "i");
- json_object_string_add(json_ocode, "egp", "e");
- json_object_string_add(json_ocode, "incomplete", "?");
- }
-
- bgp = peer->bgp;
-
- if (! bgp)
- {
- if (use_json)
- {
- json_object_string_add(json, "alert", "no BGP");
- vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
- json_object_free(json);
- }
- else
- vty_out (vty, "%% No bgp%s", VTY_NEWLINE);
- return;
- }
+ int idx = 0;
+ char *network = NULL;
- table = bgp->rib[afi][safi];
+ if (argv_find(argv, argc, "A.B.C.D", &idx))
+ network = argv[idx]->arg;
+ else if (argv_find(argv, argc, "A.B.C.D/M", &idx))
+ network = argv[idx]->arg;
+ else {
+ vty_out(vty, "Unable to figure out Network%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_route(vty, NULL, network, AFI_L2VPN, SAFI_EVPN, NULL, 0,
+ BGP_PATH_ALL, use_json(argc, argv));
+}
+
+static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
+ safi_t safi, int in, const char *rmap_name,
+ u_char use_json, json_object *json)
+{
+ struct bgp_table *table;
+ struct bgp_adj_in *ain;
+ struct bgp_adj_out *adj;
+ unsigned long output_count;
+ unsigned long filtered_count;
+ struct bgp_node *rn;
+ int header1 = 1;
+ struct bgp *bgp;
+ int header2 = 1;
+ struct attr attr;
+ struct attr_extra extra;
+ int ret;
+ struct update_subgroup *subgrp;
+ json_object *json_scode = NULL;
+ json_object *json_ocode = NULL;
+ json_object *json_ar = NULL;
+ struct peer_af *paf;
+
+ if (use_json) {
+ json_scode = json_object_new_object();
+ json_ocode = json_object_new_object();
+ json_ar = json_object_new_object();
+
+ json_object_string_add(json_scode, "suppressed", "s");
+ json_object_string_add(json_scode, "damped", "d");
+ json_object_string_add(json_scode, "history", "h");
+ json_object_string_add(json_scode, "valid", "*");
+ json_object_string_add(json_scode, "best", ">");
+ json_object_string_add(json_scode, "multipath", "=");
+ json_object_string_add(json_scode, "internal", "i");
+ json_object_string_add(json_scode, "ribFailure", "r");
+ json_object_string_add(json_scode, "stale", "S");
+ json_object_string_add(json_scode, "removed", "R");
+
+ json_object_string_add(json_ocode, "igp", "i");
+ json_object_string_add(json_ocode, "egp", "e");
+ json_object_string_add(json_ocode, "incomplete", "?");
+ }
- output_count = filtered_count = 0;
- subgrp = peer_subgroup(peer, afi, safi);
+ bgp = peer->bgp;
- if (!in && subgrp && CHECK_FLAG (subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE))
- {
- if (use_json)
- {
- json_object_int_add(json, "bgpTableVersion", table->version);
- json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
- json_object_object_add(json, "bgpStatusCodes", json_scode);
- json_object_object_add(json, "bgpOriginCodes", json_ocode);
- json_object_string_add(json, "bgpOriginatingDefaultNetwork", "0.0.0.0");
- }
- else
- {
- vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version, inet_ntoa (bgp->router_id), VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
-
- vty_out (vty, "Originating default network 0.0.0.0%s%s",
- VTY_NEWLINE, VTY_NEWLINE);
- }
- header1 = 0;
- }
-
- attr.extra = &extra;
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- {
- if (in)
- {
- for (ain = rn->adj_in; ain; ain = ain->next)
- {
- if (ain->peer == peer)
- {
- if (header1)
- {
- if (use_json)
- {
- json_object_int_add(json, "bgpTableVersion", 0);
- json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
- json_object_object_add(json, "bgpStatusCodes", json_scode);
- json_object_object_add(json, "bgpOriginCodes", json_ocode);
- }
- else
- {
- vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (bgp->router_id), VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- }
- header1 = 0;
- }
- if (header2)
- {
- if (!use_json)
- vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
- header2 = 0;
- }
- if (ain->attr)
- {
- bgp_attr_dup(&attr, ain->attr);
- if (bgp_input_modifier(peer, &rn->p, &attr, afi, safi, rmap_name) != RMAP_DENY)
- {
- route_vty_out_tmp (vty, &rn->p, &attr, safi, use_json, json_ar);
- output_count++;
- }
- else
- filtered_count++;
- }
- }
- }
- }
- else
- {
- for (adj = rn->adj_out; adj; adj = adj->next)
- SUBGRP_FOREACH_PEER(adj->subgroup, paf)
- if (paf->peer == peer)
- {
- if (header1)
- {
- if (use_json)
- {
- json_object_int_add(json, "bgpTableVersion", table->version);
- json_object_string_add(json, "bgpLocalRouterId", inet_ntoa (bgp->router_id));
- json_object_object_add(json, "bgpStatusCodes", json_scode);
- json_object_object_add(json, "bgpOriginCodes", json_ocode);
- }
- else
- {
- vty_out (vty, "BGP table version is %" PRIu64 ", local router ID is %s%s", table->version,
- inet_ntoa (bgp->router_id), VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- vty_out (vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE, VTY_NEWLINE);
- }
- header1 = 0;
- }
-
- if (header2)
- {
- if (!use_json)
- vty_out (vty, BGP_SHOW_HEADER, VTY_NEWLINE);
- header2 = 0;
- }
-
- if (adj->attr)
- {
- bgp_attr_dup(&attr, adj->attr);
- ret = bgp_output_modifier(peer, &rn->p, &attr, afi, safi, rmap_name);
- if (ret != RMAP_DENY)
- {
- route_vty_out_tmp (vty, &rn->p, &attr, safi, use_json, json_ar);
- output_count++;
- }
- else
- filtered_count++;
- }
- }
- }
- }
- if (use_json)
- json_object_object_add(json, "advertisedRoutes", json_ar);
+ if (!bgp) {
+ if (use_json) {
+ json_object_string_add(json, "alert", "no BGP");
+ vty_out(vty, "%s%s", json_object_to_json_string(json),
+ VTY_NEWLINE);
+ json_object_free(json);
+ } else
+ vty_out(vty, "%% No bgp%s", VTY_NEWLINE);
+ return;
+ }
- if (output_count != 0)
- {
- if (use_json)
- json_object_int_add(json, "totalPrefixCounter", output_count);
- else
- vty_out (vty, "%sTotal number of prefixes %ld%s",
- VTY_NEWLINE, output_count, VTY_NEWLINE);
- }
- if (use_json)
- {
- vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
- json_object_free(json);
- }
+ table = bgp->rib[afi][safi];
+
+ output_count = filtered_count = 0;
+ subgrp = peer_subgroup(peer, afi, safi);
+
+ if (!in && subgrp
+ && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
+ if (use_json) {
+ json_object_int_add(json, "bgpTableVersion",
+ table->version);
+ json_object_string_add(json, "bgpLocalRouterId",
+ inet_ntoa(bgp->router_id));
+ json_object_object_add(json, "bgpStatusCodes",
+ json_scode);
+ json_object_object_add(json, "bgpOriginCodes",
+ json_ocode);
+ json_object_string_add(json,
+ "bgpOriginatingDefaultNetwork",
+ "0.0.0.0");
+ } else {
+ vty_out(vty, "BGP table version is %" PRIu64
+ ", local router ID is %s%s",
+ table->version, inet_ntoa(bgp->router_id),
+ VTY_NEWLINE);
+ vty_out(vty, BGP_SHOW_SCODE_HEADER, VTY_NEWLINE,
+ VTY_NEWLINE);
+ vty_out(vty, BGP_SHOW_OCODE_HEADER, VTY_NEWLINE,
+ VTY_NEWLINE);
+
+ vty_out(vty, "Originating default network 0.0.0.0%s%s",
+ VTY_NEWLINE, VTY_NEWLINE);
+ }
+ header1 = 0;
+ }
+ attr.extra = &extra;
+ for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
+ if (in) {
+ for (ain = rn->adj_in; ain; ain = ain->next) {
+ if (ain->peer == peer) {
+ if (header1) {
+ if (use_json) {
+ json_object_int_add(
+ json,
+ "bgpTableVersion",
+ 0);
+ json_object_string_add(
+ json,
+ "bgpLocalRouterId",
+ inet_ntoa(
+ bgp->router_id));
+ json_object_object_add(
+ json,
+ "bgpStatusCodes",
+ json_scode);
+ json_object_object_add(
+ json,
+ "bgpOriginCodes",
+ json_ocode);
+ } else {
+ vty_out(vty,
+ "BGP table version is 0, local router ID is %s%s",
+ inet_ntoa(
+ bgp->router_id),
+ VTY_NEWLINE);
+ vty_out(vty,
+ BGP_SHOW_SCODE_HEADER,
+ VTY_NEWLINE,
+ VTY_NEWLINE);
+ vty_out(vty,
+ BGP_SHOW_OCODE_HEADER,
+ VTY_NEWLINE,
+ VTY_NEWLINE);
+ }
+ header1 = 0;
+ }
+ if (header2) {
+ if (!use_json)
+ vty_out(vty,
+ BGP_SHOW_HEADER,
+ VTY_NEWLINE);
+ header2 = 0;
+ }
+ if (ain->attr) {
+ bgp_attr_dup(&attr, ain->attr);
+ if (bgp_input_modifier(
+ peer, &rn->p, &attr,
+ afi, safi,
+ rmap_name)
+ != RMAP_DENY) {
+ route_vty_out_tmp(
+ vty, &rn->p,
+ &attr, safi,
+ use_json,
+ json_ar);
+ output_count++;
+ } else
+ filtered_count++;
+ }
+ }
+ }
+ } else {
+ for (adj = rn->adj_out; adj; adj = adj->next)
+ SUBGRP_FOREACH_PEER(adj->subgroup, paf)
+ if (paf->peer == peer) {
+ if (header1) {
+ if (use_json) {
+ json_object_int_add(
+ json, "bgpTableVersion",
+ table->version);
+ json_object_string_add(
+ json,
+ "bgpLocalRouterId",
+ inet_ntoa(
+ bgp->router_id));
+ json_object_object_add(
+ json, "bgpStatusCodes",
+ json_scode);
+ json_object_object_add(
+ json, "bgpOriginCodes",
+ json_ocode);
+ } else {
+ vty_out(vty,
+ "BGP table version is %" PRIu64
+ ", local router ID is %s%s",
+ table->version,
+ inet_ntoa(
+ bgp->router_id),
+ VTY_NEWLINE);
+ vty_out(vty,
+ BGP_SHOW_SCODE_HEADER,
+ VTY_NEWLINE,
+ VTY_NEWLINE);
+ vty_out(vty,
+ BGP_SHOW_OCODE_HEADER,
+ VTY_NEWLINE,
+ VTY_NEWLINE);
+ }
+ header1 = 0;
+ }
+
+ if (header2) {
+ if (!use_json)
+ vty_out(vty, BGP_SHOW_HEADER,
+ VTY_NEWLINE);
+ header2 = 0;
+ }
+
+ if (adj->attr) {
+ bgp_attr_dup(&attr, adj->attr);
+ ret = bgp_output_modifier(
+ peer, &rn->p, &attr, afi, safi,
+ rmap_name);
+ if (ret != RMAP_DENY) {
+ route_vty_out_tmp(vty, &rn->p,
+ &attr, safi,
+ use_json,
+ json_ar);
+ output_count++;
+ } else
+ filtered_count++;
+ }
+ }
+ }
+ }
+ if (use_json)
+ json_object_object_add(json, "advertisedRoutes", json_ar);
+
+ if (output_count != 0) {
+ if (use_json)
+ json_object_int_add(json, "totalPrefixCounter",
+ output_count);
+ else
+ vty_out(vty, "%sTotal number of prefixes %ld%s",
+ VTY_NEWLINE, output_count, VTY_NEWLINE);
+ }
+ if (use_json) {
+ vty_out(vty, "%s%s", json_object_to_json_string(json),
+ VTY_NEWLINE);
+ json_object_free(json);
+ }
}
-static int
-peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
- int in, const char *rmap_name, u_char use_json)
+static int peer_adj_routes(struct vty *vty, struct peer *peer, afi_t afi,
+ safi_t safi, int in, const char *rmap_name,
+ u_char use_json)
{
- json_object *json = NULL;
+ json_object *json = NULL;
- if (use_json)
- json = json_object_new_object();
+ if (use_json)
+ json = json_object_new_object();
- if (!peer || !peer->afc[afi][safi])
- {
- if (use_json)
- {
- json_object_string_add(json, "warning", "No such neighbor or address family");
- vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
- json_object_free(json);
- }
- else
- vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
-
- return CMD_WARNING;
- }
+ if (!peer || !peer->afc[afi][safi]) {
+ if (use_json) {
+ json_object_string_add(
+ json, "warning",
+ "No such neighbor or address family");
+ vty_out(vty, "%s%s", json_object_to_json_string(json),
+ VTY_NEWLINE);
+ json_object_free(json);
+ } else
+ vty_out(vty, "%% No such neighbor or address family%s",
+ VTY_NEWLINE);
- if (in && !CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG))
- {
- if (use_json)
- {
- json_object_string_add(json, "warning", "Inbound soft reconfiguration not enabled");
- vty_out (vty, "%s%s", json_object_to_json_string(json), VTY_NEWLINE);
- json_object_free(json);
- }
- else
- vty_out (vty, "%% Inbound soft reconfiguration not enabled%s", VTY_NEWLINE);
-
- return CMD_WARNING;
- }
+ return CMD_WARNING;
+ }
+
+ if (in
+ && !CHECK_FLAG(peer->af_flags[afi][safi],
+ PEER_FLAG_SOFT_RECONFIG)) {
+ if (use_json) {
+ json_object_string_add(
+ json, "warning",
+ "Inbound soft reconfiguration not enabled");
+ vty_out(vty, "%s%s", json_object_to_json_string(json),
+ VTY_NEWLINE);
+ json_object_free(json);
+ } else
+ vty_out(vty,
+ "%% Inbound soft reconfiguration not enabled%s",
+ VTY_NEWLINE);
+
+ return CMD_WARNING;
+ }
- show_adj_route (vty, peer, afi, safi, in, rmap_name, use_json, json);
+ show_adj_route(vty, peer, afi, safi, in, rmap_name, use_json, json);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
@@ -9589,39 +9774,41 @@ DEFUN (show_ip_bgp_instance_neighbor_advertised_route,
"Name of the route map\n"
JSON_STR)
{
- afi_t afi = AFI_IP6;
- safi_t safi = SAFI_UNICAST;
- char *rmap_name = NULL;
- char *peerstr = NULL;
- int rcvd = 0;
- struct bgp *bgp = NULL;
- struct peer *peer;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ char *rmap_name = NULL;
+ char *peerstr = NULL;
+ int rcvd = 0;
+ struct bgp *bgp = NULL;
+ struct peer *peer;
- int idx = 0;
+ int idx = 0;
- bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
- if (!idx)
- return CMD_WARNING;
+ bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
+ &bgp);
+ if (!idx)
+ return CMD_WARNING;
- int uj = use_json (argc, argv);
- if (uj) argc--;
+ int uj = use_json(argc, argv);
+ if (uj)
+ argc--;
- /* neighbors <A.B.C.D|X:X::X:X|WORD> */
- argv_find (argv, argc, "neighbors", &idx);
- peerstr = argv[++idx]->arg;
+ /* neighbors <A.B.C.D|X:X::X:X|WORD> */
+ argv_find(argv, argc, "neighbors", &idx);
+ peerstr = argv[++idx]->arg;
- peer = peer_lookup_in_view (vty, bgp, peerstr, uj);
- if (! peer)
- return CMD_WARNING;
+ peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
+ if (!peer)
+ return CMD_WARNING;
- if (argv_find (argv, argc, "received-routes", &idx))
- rcvd = 1;
- if (argv_find (argv, argc, "advertised-routes", &idx))
- rcvd = 0;
- if (argv_find (argv, argc, "route-map", &idx))
- rmap_name = argv[++idx]->arg;
+ if (argv_find(argv, argc, "received-routes", &idx))
+ rcvd = 1;
+ if (argv_find(argv, argc, "advertised-routes", &idx))
+ rcvd = 0;
+ if (argv_find(argv, argc, "route-map", &idx))
+ rmap_name = argv[++idx]->arg;
- return peer_adj_routes (vty, peer, afi, safi, rcvd, rmap_name, uj);
+ return peer_adj_routes(vty, peer, afi, safi, rcvd, rmap_name, uj);
}
DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
@@ -9641,96 +9828,93 @@ DEFUN (show_ip_bgp_neighbor_received_prefix_filter,
"Display the prefixlist filter\n"
JSON_STR)
{
- afi_t afi = AFI_IP6;
- safi_t safi = SAFI_UNICAST;
- char *peerstr = NULL;
-
- char name[BUFSIZ];
- union sockunion su;
- struct peer *peer;
- int count, ret;
-
- int idx = 0;
-
- /* show [ip] bgp */
- if (argv_find (argv, argc, "ip", &idx))
- afi = AFI_IP;
- /* [<ipv4|ipv6> [unicast]] */
- if (argv_find (argv, argc, "ipv4", &idx))
- afi = AFI_IP;
- if (argv_find (argv, argc, "ipv6", &idx))
- afi = AFI_IP6;
- /* neighbors <A.B.C.D|X:X::X:X|WORD> */
- argv_find (argv, argc, "neighbors", &idx);
- peerstr = argv[++idx]->arg;
-
- u_char uj = use_json(argc, argv);
-
- ret = str2sockunion (peerstr, &su);
- if (ret < 0)
- {
- peer = peer_lookup_by_conf_if (NULL, peerstr);
- if (! peer)
- {
- if (uj)
- vty_out (vty, "{}%s", VTY_NEWLINE);
- else
- vty_out (vty, "%% Malformed address or name: %s%s", peerstr, VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- else
- {
- peer = peer_lookup (NULL, &su);
- if (! peer)
- {
- if (uj)
- vty_out (vty, "{}%s", VTY_NEWLINE);
- else
- vty_out (vty, "No peer%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
-
- sprintf (name, "%s.%d.%d", peer->host, afi, safi);
- count = prefix_bgp_show_prefix_list (NULL, afi, name, uj);
- if (count)
- {
- if (!uj)
- vty_out (vty, "Address Family: %s%s", afi_safi_print(afi, safi), VTY_NEWLINE);
- prefix_bgp_show_prefix_list (vty, afi, name, uj);
- }
- else
- {
- if (uj)
- vty_out (vty, "{}%s", VTY_NEWLINE);
- else
- vty_out (vty, "No functional output%s", VTY_NEWLINE);
- }
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ char *peerstr = NULL;
+
+ char name[BUFSIZ];
+ union sockunion su;
+ struct peer *peer;
+ int count, ret;
+
+ int idx = 0;
+
+ /* show [ip] bgp */
+ if (argv_find(argv, argc, "ip", &idx))
+ afi = AFI_IP;
+ /* [<ipv4|ipv6> [unicast]] */
+ if (argv_find(argv, argc, "ipv4", &idx))
+ afi = AFI_IP;
+ if (argv_find(argv, argc, "ipv6", &idx))
+ afi = AFI_IP6;
+ /* neighbors <A.B.C.D|X:X::X:X|WORD> */
+ argv_find(argv, argc, "neighbors", &idx);
+ peerstr = argv[++idx]->arg;
+
+ u_char uj = use_json(argc, argv);
+
+ ret = str2sockunion(peerstr, &su);
+ if (ret < 0) {
+ peer = peer_lookup_by_conf_if(NULL, peerstr);
+ if (!peer) {
+ if (uj)
+ vty_out(vty, "{}%s", VTY_NEWLINE);
+ else
+ vty_out(vty,
+ "%% Malformed address or name: %s%s",
+ peerstr, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ } else {
+ peer = peer_lookup(NULL, &su);
+ if (!peer) {
+ if (uj)
+ vty_out(vty, "{}%s", VTY_NEWLINE);
+ else
+ vty_out(vty, "No peer%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ }
- return CMD_SUCCESS;
-}
+ sprintf(name, "%s.%d.%d", peer->host, afi, safi);
+ count = prefix_bgp_show_prefix_list(NULL, afi, name, uj);
+ if (count) {
+ if (!uj)
+ vty_out(vty, "Address Family: %s%s",
+ afi_safi_print(afi, safi), VTY_NEWLINE);
+ prefix_bgp_show_prefix_list(vty, afi, name, uj);
+ } else {
+ if (uj)
+ vty_out(vty, "{}%s", VTY_NEWLINE);
+ else
+ vty_out(vty, "No functional output%s", VTY_NEWLINE);
+ }
-static int
-bgp_show_neighbor_route (struct vty *vty, struct peer *peer, afi_t afi,
- safi_t safi, enum bgp_show_type type, u_char use_json)
-{
- if (! peer || ! peer->afc[afi][safi])
- {
- if (use_json)
- {
- json_object *json_no = NULL;
- json_no = json_object_new_object();
- json_object_string_add(json_no, "warning", "No such neighbor or address family");
- vty_out (vty, "%s%s", json_object_to_json_string(json_no), VTY_NEWLINE);
- json_object_free(json_no);
- }
- else
- vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ return CMD_SUCCESS;
+}
+
+static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
+ afi_t afi, safi_t safi,
+ enum bgp_show_type type, u_char use_json)
+{
+ if (!peer || !peer->afc[afi][safi]) {
+ if (use_json) {
+ json_object *json_no = NULL;
+ json_no = json_object_new_object();
+ json_object_string_add(
+ json_no, "warning",
+ "No such neighbor or address family");
+ vty_out(vty, "%s%s",
+ json_object_to_json_string(json_no),
+ VTY_NEWLINE);
+ json_object_free(json_no);
+ } else
+ vty_out(vty, "%% No such neighbor or address family%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_show (vty, peer->bgp, afi, safi, type, &peer->su, use_json);
+ return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, use_json);
}
DEFUN (show_ip_bgp_neighbor_routes,
@@ -9752,52 +9936,52 @@ DEFUN (show_ip_bgp_neighbor_routes,
"Display routes learned from neighbor\n"
JSON_STR)
{
- char *peerstr = NULL;
- struct bgp *bgp = NULL;
- afi_t afi = AFI_IP6;
- safi_t safi = SAFI_UNICAST;
- struct peer *peer;
- enum bgp_show_type sh_type = bgp_show_type_neighbor;
+ char *peerstr = NULL;
+ struct bgp *bgp = NULL;
+ afi_t afi = AFI_IP6;
+ safi_t safi = SAFI_UNICAST;
+ struct peer *peer;
+ enum bgp_show_type sh_type = bgp_show_type_neighbor;
- int idx = 0;
+ int idx = 0;
- bgp_vty_find_and_parse_afi_safi_bgp (vty, argv, argc, &idx, &afi, &safi, &bgp);
- if (!idx)
- return CMD_WARNING;
+ bgp_vty_find_and_parse_afi_safi_bgp(vty, argv, argc, &idx, &afi, &safi,
+ &bgp);
+ if (!idx)
+ return CMD_WARNING;
- int uj = use_json (argc, argv);
- if (uj) argc--;
+ int uj = use_json(argc, argv);
+ if (uj)
+ argc--;
- /* neighbors <A.B.C.D|X:X::X:X|WORD> */
- argv_find (argv, argc, "neighbors", &idx);
- peerstr = argv[++idx]->arg;
+ /* neighbors <A.B.C.D|X:X::X:X|WORD> */
+ argv_find(argv, argc, "neighbors", &idx);
+ peerstr = argv[++idx]->arg;
- peer = peer_lookup_in_view (vty, bgp, peerstr, uj);
- if (! peer)
- {
- vty_out (vty, "No such neighbor%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ peer = peer_lookup_in_view(vty, bgp, peerstr, uj);
+ if (!peer) {
+ vty_out(vty, "No such neighbor%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- if (argv_find (argv, argc, "flap-statistics", &idx))
- sh_type = bgp_show_type_flap_neighbor;
- else if (argv_find (argv, argc, "dampened-routes", &idx))
- sh_type = bgp_show_type_damp_neighbor;
- else if (argv_find (argv, argc, "routes", &idx))
- sh_type = bgp_show_type_neighbor;
+ if (argv_find(argv, argc, "flap-statistics", &idx))
+ sh_type = bgp_show_type_flap_neighbor;
+ else if (argv_find(argv, argc, "dampened-routes", &idx))
+ sh_type = bgp_show_type_damp_neighbor;
+ else if (argv_find(argv, argc, "routes", &idx))
+ sh_type = bgp_show_type_neighbor;
- return bgp_show_neighbor_route (vty, peer, afi, safi, sh_type, uj);
+ return bgp_show_neighbor_route(vty, peer, afi, safi, sh_type, uj);
}
struct bgp_table *bgp_distance_table[AFI_MAX][SAFI_MAX];
-struct bgp_distance
-{
- /* Distance value for the IP source prefix. */
- u_char distance;
+struct bgp_distance {
+ /* Distance value for the IP source prefix. */
+ u_char distance;
- /* Name of the access-list to be matched. */
- char *access_list;
+ /* Name of the access-list to be matched. */
+ char *access_list;
};
DEFUN (show_bgp_afi_vpn_rd_route,
@@ -9813,197 +9997,180 @@ DEFUN (show_bgp_afi_vpn_rd_route,
"Network in the BGP routing table to display\n"
JSON_STR)
{
- int ret;
- struct prefix_rd prd;
- afi_t afi = AFI_MAX;
- int idx = 0;
+ int ret;
+ struct prefix_rd prd;
+ afi_t afi = AFI_MAX;
+ int idx = 0;
- argv_find_and_parse_afi (argv, argc, &idx, &afi);
- ret = str2prefix_rd (argv[5]->arg, &prd);
- if (! ret)
- {
- vty_out (vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- return bgp_show_route (vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd, 0, BGP_PATH_ALL, use_json (argc, argv));
+ argv_find_and_parse_afi(argv, argc, &idx, &afi);
+ ret = str2prefix_rd(argv[5]->arg, &prd);
+ if (!ret) {
+ vty_out(vty, "%% Malformed Route Distinguisher%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ return bgp_show_route(vty, NULL, argv[6]->arg, afi, SAFI_MPLS_VPN, &prd,
+ 0, BGP_PATH_ALL, use_json(argc, argv));
}
-static struct bgp_distance *
-bgp_distance_new (void)
+static struct bgp_distance *bgp_distance_new(void)
{
- return XCALLOC (MTYPE_BGP_DISTANCE, sizeof (struct bgp_distance));
+ return XCALLOC(MTYPE_BGP_DISTANCE, sizeof(struct bgp_distance));
}
-static void
-bgp_distance_free (struct bgp_distance *bdistance)
+static void bgp_distance_free(struct bgp_distance *bdistance)
{
- XFREE (MTYPE_BGP_DISTANCE, bdistance);
+ XFREE(MTYPE_BGP_DISTANCE, bdistance);
}
-static int
-bgp_distance_set (struct vty *vty, const char *distance_str,
- const char *ip_str, const char *access_list_str)
+static int bgp_distance_set(struct vty *vty, const char *distance_str,
+ const char *ip_str, const char *access_list_str)
{
- int ret;
- afi_t afi;
- safi_t safi;
- struct prefix p;
- u_char distance;
- struct bgp_node *rn;
- struct bgp_distance *bdistance;
+ int ret;
+ afi_t afi;
+ safi_t safi;
+ struct prefix p;
+ u_char distance;
+ struct bgp_node *rn;
+ struct bgp_distance *bdistance;
- afi = bgp_node_afi (vty);
- safi = bgp_node_safi (vty);
+ afi = bgp_node_afi(vty);
+ safi = bgp_node_safi(vty);
- ret = str2prefix (ip_str, &p);
- if (ret == 0)
- {
- vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ ret = str2prefix(ip_str, &p);
+ if (ret == 0) {
+ vty_out(vty, "Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- distance = atoi (distance_str);
+ distance = atoi(distance_str);
- /* Get BGP distance node. */
- rn = bgp_node_get (bgp_distance_table[afi][safi], (struct prefix *) &p);
- if (rn->info)
- {
- bdistance = rn->info;
- bgp_unlock_node (rn);
- }
- else
- {
- bdistance = bgp_distance_new ();
- rn->info = bdistance;
- }
+ /* Get BGP distance node. */
+ rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
+ if (rn->info) {
+ bdistance = rn->info;
+ bgp_unlock_node(rn);
+ } else {
+ bdistance = bgp_distance_new();
+ rn->info = bdistance;
+ }
- /* Set distance value. */
- bdistance->distance = distance;
+ /* Set distance value. */
+ bdistance->distance = distance;
- /* Reset access-list configuration. */
- if (bdistance->access_list)
- {
- XFREE(MTYPE_AS_LIST, bdistance->access_list);
- bdistance->access_list = NULL;
- }
- if (access_list_str)
- bdistance->access_list = XSTRDUP(MTYPE_AS_LIST, access_list_str);
+ /* Reset access-list configuration. */
+ if (bdistance->access_list) {
+ XFREE(MTYPE_AS_LIST, bdistance->access_list);
+ bdistance->access_list = NULL;
+ }
+ if (access_list_str)
+ bdistance->access_list =
+ XSTRDUP(MTYPE_AS_LIST, access_list_str);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
-static int
-bgp_distance_unset (struct vty *vty, const char *distance_str,
- const char *ip_str, const char *access_list_str)
+static int bgp_distance_unset(struct vty *vty, const char *distance_str,
+ const char *ip_str, const char *access_list_str)
{
- int ret;
- afi_t afi;
- safi_t safi;
- struct prefix p;
- int distance;
- struct bgp_node *rn;
- struct bgp_distance *bdistance;
+ int ret;
+ afi_t afi;
+ safi_t safi;
+ struct prefix p;
+ int distance;
+ struct bgp_node *rn;
+ struct bgp_distance *bdistance;
- afi = bgp_node_afi (vty);
- safi = bgp_node_safi (vty);
+ afi = bgp_node_afi(vty);
+ safi = bgp_node_safi(vty);
- ret = str2prefix (ip_str, &p);
- if (ret == 0)
- {
- vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ ret = str2prefix(ip_str, &p);
+ if (ret == 0) {
+ vty_out(vty, "Malformed prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- rn = bgp_node_lookup (bgp_distance_table[afi][safi], (struct prefix *)&p);
- if (! rn)
- {
- vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ rn = bgp_node_lookup(bgp_distance_table[afi][safi],
+ (struct prefix *)&p);
+ if (!rn) {
+ vty_out(vty, "Can't find specified prefix%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- bdistance = rn->info;
- distance = atoi(distance_str);
+ bdistance = rn->info;
+ distance = atoi(distance_str);
- if (bdistance->distance != distance)
- {
- vty_out (vty, "Distance does not match configured%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ if (bdistance->distance != distance) {
+ vty_out(vty, "Distance does not match configured%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- if (bdistance->access_list)
- XFREE(MTYPE_AS_LIST, bdistance->access_list);
- bgp_distance_free (bdistance);
+ if (bdistance->access_list)
+ XFREE(MTYPE_AS_LIST, bdistance->access_list);
+ bgp_distance_free(bdistance);
- rn->info = NULL;
- bgp_unlock_node (rn);
- bgp_unlock_node (rn);
+ rn->info = NULL;
+ bgp_unlock_node(rn);
+ bgp_unlock_node(rn);
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
/* Apply BGP information to distance method. */
-u_char
-bgp_distance_apply (struct prefix *p, struct bgp_info *rinfo, afi_t afi,
- safi_t safi, struct bgp *bgp)
-{
- struct bgp_node *rn;
- struct prefix q;
- struct peer *peer;
- struct bgp_distance *bdistance;
- struct access_list *alist;
- struct bgp_static *bgp_static;
-
- if (! bgp)
- return 0;
-
- peer = rinfo->peer;
-
- /* Check source address. */
- sockunion2hostprefix (&peer->su, &q);
- rn = bgp_node_match (bgp_distance_table[afi][safi], &q);
- if (rn)
- {
- bdistance = rn->info;
- bgp_unlock_node (rn);
-
- if (bdistance->access_list)
- {
- alist = access_list_lookup (afi, bdistance->access_list);
- if (alist && access_list_apply (alist, p) == FILTER_PERMIT)
- return bdistance->distance;
+u_char bgp_distance_apply(struct prefix *p, struct bgp_info *rinfo, afi_t afi,
+ safi_t safi, struct bgp *bgp)
+{
+ struct bgp_node *rn;
+ struct prefix q;
+ struct peer *peer;
+ struct bgp_distance *bdistance;
+ struct access_list *alist;
+ struct bgp_static *bgp_static;
+
+ if (!bgp)
+ return 0;
+
+ peer = rinfo->peer;
+
+ /* Check source address. */
+ sockunion2hostprefix(&peer->su, &q);
+ rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
+ if (rn) {
+ bdistance = rn->info;
+ bgp_unlock_node(rn);
+
+ if (bdistance->access_list) {
+ alist = access_list_lookup(afi, bdistance->access_list);
+ if (alist
+ && access_list_apply(alist, p) == FILTER_PERMIT)
+ return bdistance->distance;
+ } else
+ return bdistance->distance;
}
- else
- return bdistance->distance;
- }
- /* Backdoor check. */
- rn = bgp_node_lookup (bgp->route[afi][safi], p);
- if (rn)
- {
- bgp_static = rn->info;
- bgp_unlock_node (rn);
+ /* Backdoor check. */
+ rn = bgp_node_lookup(bgp->route[afi][safi], p);
+ if (rn) {
+ bgp_static = rn->info;
+ bgp_unlock_node(rn);
- if (bgp_static->backdoor)
- {
- if (bgp->distance_local[afi][safi])
- return bgp->distance_local[afi][safi];
- else
- return ZEBRA_IBGP_DISTANCE_DEFAULT;
+ if (bgp_static->backdoor) {
+ if (bgp->distance_local[afi][safi])
+ return bgp->distance_local[afi][safi];
+ else
+ return ZEBRA_IBGP_DISTANCE_DEFAULT;
+ }
}
- }
- if (peer->sort == BGP_PEER_EBGP)
- {
- if (bgp->distance_ebgp[afi][safi])
- return bgp->distance_ebgp[afi][safi];
- return ZEBRA_EBGP_DISTANCE_DEFAULT;
- }
- else
- {
- if (bgp->distance_ibgp[afi][safi])
- return bgp->distance_ibgp[afi][safi];
- return ZEBRA_IBGP_DISTANCE_DEFAULT;
- }
+ if (peer->sort == BGP_PEER_EBGP) {
+ if (bgp->distance_ebgp[afi][safi])
+ return bgp->distance_ebgp[afi][safi];
+ return ZEBRA_EBGP_DISTANCE_DEFAULT;
+ } else {
+ if (bgp->distance_ibgp[afi][safi])
+ return bgp->distance_ibgp[afi][safi];
+ return ZEBRA_IBGP_DISTANCE_DEFAULT;
+ }
}
DEFUN (bgp_distance,
@@ -10015,20 +10182,20 @@ DEFUN (bgp_distance,
"Distance for routes internal to the AS\n"
"Distance for local routes\n")
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx_number = 2;
- int idx_number_2 = 3;
- int idx_number_3 = 4;
- afi_t afi;
- safi_t safi;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_number = 2;
+ int idx_number_2 = 3;
+ int idx_number_3 = 4;
+ afi_t afi;
+ safi_t safi;
- afi = bgp_node_afi (vty);
- safi = bgp_node_safi (vty);
+ afi = bgp_node_afi(vty);
+ safi = bgp_node_safi(vty);
- bgp->distance_ebgp[afi][safi] = atoi (argv[idx_number]->arg);
- bgp->distance_ibgp[afi][safi] = atoi (argv[idx_number_2]->arg);
- bgp->distance_local[afi][safi] = atoi (argv[idx_number_3]->arg);
- return CMD_SUCCESS;
+ bgp->distance_ebgp[afi][safi] = atoi(argv[idx_number]->arg);
+ bgp->distance_ibgp[afi][safi] = atoi(argv[idx_number_2]->arg);
+ bgp->distance_local[afi][safi] = atoi(argv[idx_number_3]->arg);
+ return CMD_SUCCESS;
}
DEFUN (no_bgp_distance,
@@ -10041,17 +10208,17 @@ DEFUN (no_bgp_distance,
"Distance for routes internal to the AS\n"
"Distance for local routes\n")
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- afi_t afi;
- safi_t safi;
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ afi_t afi;
+ safi_t safi;
- afi = bgp_node_afi (vty);
- safi = bgp_node_safi (vty);
+ afi = bgp_node_afi(vty);
+ safi = bgp_node_safi(vty);
- bgp->distance_ebgp[afi][safi] = 0;
- bgp->distance_ibgp[afi][safi] = 0;
- bgp->distance_local[afi][safi] = 0;
- return CMD_SUCCESS;
+ bgp->distance_ebgp[afi][safi] = 0;
+ bgp->distance_ibgp[afi][safi] = 0;
+ bgp->distance_local[afi][safi] = 0;
+ return CMD_SUCCESS;
}
@@ -10062,10 +10229,11 @@ DEFUN (bgp_distance_source,
"Administrative distance\n"
"IP source prefix\n")
{
- int idx_number = 1;
- int idx_ipv4_prefixlen = 2;
- bgp_distance_set (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
- return CMD_SUCCESS;
+ int idx_number = 1;
+ int idx_ipv4_prefixlen = 2;
+ bgp_distance_set(vty, argv[idx_number]->arg,
+ argv[idx_ipv4_prefixlen]->arg, NULL);
+ return CMD_SUCCESS;
}
DEFUN (no_bgp_distance_source,
@@ -10076,10 +10244,11 @@ DEFUN (no_bgp_distance_source,
"Administrative distance\n"
"IP source prefix\n")
{
- int idx_number = 2;
- int idx_ipv4_prefixlen = 3;
- bgp_distance_unset (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, NULL);
- return CMD_SUCCESS;
+ int idx_number = 2;
+ int idx_ipv4_prefixlen = 3;
+ bgp_distance_unset(vty, argv[idx_number]->arg,
+ argv[idx_ipv4_prefixlen]->arg, NULL);
+ return CMD_SUCCESS;
}
DEFUN (bgp_distance_source_access_list,
@@ -10090,11 +10259,12 @@ DEFUN (bgp_distance_source_access_list,
"IP source prefix\n"
"Access list name\n")
{
- int idx_number = 1;
- int idx_ipv4_prefixlen = 2;
- int idx_word = 3;
- bgp_distance_set (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
- return CMD_SUCCESS;
+ int idx_number = 1;
+ int idx_ipv4_prefixlen = 2;
+ int idx_word = 3;
+ bgp_distance_set(vty, argv[idx_number]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
+ return CMD_SUCCESS;
}
DEFUN (no_bgp_distance_source_access_list,
@@ -10106,11 +10276,12 @@ DEFUN (no_bgp_distance_source_access_list,
"IP source prefix\n"
"Access list name\n")
{
- int idx_number = 2;
- int idx_ipv4_prefixlen = 3;
- int idx_word = 4;
- bgp_distance_unset (vty, argv[idx_number]->arg, argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
- return CMD_SUCCESS;
+ int idx_number = 2;
+ int idx_ipv4_prefixlen = 3;
+ int idx_word = 4;
+ bgp_distance_unset(vty, argv[idx_number]->arg,
+ argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
+ return CMD_SUCCESS;
}
DEFUN (ipv6_bgp_distance_source,
@@ -10120,8 +10291,8 @@ DEFUN (ipv6_bgp_distance_source,
"Administrative distance\n"
"IP source prefix\n")
{
- bgp_distance_set (vty, argv[1]->arg, argv[2]->arg, NULL);
- return CMD_SUCCESS;
+ bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_bgp_distance_source,
@@ -10132,8 +10303,8 @@ DEFUN (no_ipv6_bgp_distance_source,
"Administrative distance\n"
"IP source prefix\n")
{
- bgp_distance_unset (vty, argv[2]->arg, argv[3]->arg, NULL);
- return CMD_SUCCESS;
+ bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
+ return CMD_SUCCESS;
}
DEFUN (ipv6_bgp_distance_source_access_list,
@@ -10144,8 +10315,8 @@ DEFUN (ipv6_bgp_distance_source_access_list,
"IP source prefix\n"
"Access list name\n")
{
- bgp_distance_set (vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
- return CMD_SUCCESS;
+ bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
+ return CMD_SUCCESS;
}
DEFUN (no_ipv6_bgp_distance_source_access_list,
@@ -10157,8 +10328,8 @@ DEFUN (no_ipv6_bgp_distance_source_access_list,
"IP source prefix\n"
"Access list name\n")
{
- bgp_distance_unset (vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
- return CMD_SUCCESS;
+ bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
+ return CMD_SUCCESS;
}
DEFUN (bgp_damp_set,
@@ -10171,38 +10342,35 @@ DEFUN (bgp_damp_set,
"Value to start suppressing a route\n"
"Maximum duration to suppress a stable route\n")
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- int idx_half_life = 2;
- int idx_reuse = 3;
- int idx_suppress = 4;
- int idx_max_suppress = 5;
- int half = DEFAULT_HALF_LIFE * 60;
- int reuse = DEFAULT_REUSE;
- int suppress = DEFAULT_SUPPRESS;
- int max = 4 * half;
-
- if (argc == 6)
- {
- half = atoi (argv[idx_half_life]->arg) * 60;
- reuse = atoi (argv[idx_reuse]->arg);
- suppress = atoi (argv[idx_suppress]->arg);
- max = atoi (argv[idx_max_suppress]->arg) * 60;
- }
- else if (argc == 3)
- {
- half = atoi (argv[idx_half_life]->arg) * 60;
- max = 4 * half;
- }
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ int idx_half_life = 2;
+ int idx_reuse = 3;
+ int idx_suppress = 4;
+ int idx_max_suppress = 5;
+ int half = DEFAULT_HALF_LIFE * 60;
+ int reuse = DEFAULT_REUSE;
+ int suppress = DEFAULT_SUPPRESS;
+ int max = 4 * half;
+
+ if (argc == 6) {
+ half = atoi(argv[idx_half_life]->arg) * 60;
+ reuse = atoi(argv[idx_reuse]->arg);
+ suppress = atoi(argv[idx_suppress]->arg);
+ max = atoi(argv[idx_max_suppress]->arg) * 60;
+ } else if (argc == 3) {
+ half = atoi(argv[idx_half_life]->arg) * 60;
+ max = 4 * half;
+ }
- if (suppress < reuse)
- {
- vty_out (vty, "Suppress value cannot be less than reuse value %s",
- VTY_NEWLINE);
- return 0;
- }
+ if (suppress < reuse) {
+ vty_out(vty,
+ "Suppress value cannot be less than reuse value %s",
+ VTY_NEWLINE);
+ return 0;
+ }
- return bgp_damp_enable (bgp, bgp_node_afi (vty), bgp_node_safi (vty),
- half, reuse, suppress, max);
+ return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
+ reuse, suppress, max);
}
DEFUN (bgp_damp_unset,
@@ -10216,110 +10384,106 @@ DEFUN (bgp_damp_unset,
"Value to start suppressing a route\n"
"Maximum duration to suppress a stable route\n")
{
- VTY_DECLVAR_CONTEXT(bgp, bgp);
- return bgp_damp_disable (bgp, bgp_node_afi (vty), bgp_node_safi (vty));
+ VTY_DECLVAR_CONTEXT(bgp, bgp);
+ return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
}
/* Display specified route of BGP table. */
-static int
-bgp_clear_damp_route (struct vty *vty, const char *view_name,
- const char *ip_str, afi_t afi, safi_t safi,
- struct prefix_rd *prd, int prefix_check)
-{
- int ret;
- struct prefix match;
- struct bgp_node *rn;
- struct bgp_node *rm;
- struct bgp_info *ri;
- struct bgp_info *ri_temp;
- struct bgp *bgp;
- struct bgp_table *table;
-
- /* BGP structure lookup. */
- if (view_name)
- {
- bgp = bgp_lookup_by_name (view_name);
- if (bgp == NULL)
- {
- vty_out (vty, "%% Can't find BGP instance %s%s", view_name, VTY_NEWLINE);
- return CMD_WARNING;
- }
- }
- else
- {
- bgp = bgp_get_default ();
- if (bgp == NULL)
- {
- vty_out (vty, "%% No BGP process is configured%s", VTY_NEWLINE);
- return CMD_WARNING;
+static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
+ const char *ip_str, afi_t afi, safi_t safi,
+ struct prefix_rd *prd, int prefix_check)
+{
+ int ret;
+ struct prefix match;
+ struct bgp_node *rn;
+ struct bgp_node *rm;
+ struct bgp_info *ri;
+ struct bgp_info *ri_temp;
+ struct bgp *bgp;
+ struct bgp_table *table;
+
+ /* BGP structure lookup. */
+ if (view_name) {
+ bgp = bgp_lookup_by_name(view_name);
+ if (bgp == NULL) {
+ vty_out(vty, "%% Can't find BGP instance %s%s",
+ view_name, VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+ } else {
+ bgp = bgp_get_default();
+ if (bgp == NULL) {
+ vty_out(vty, "%% No BGP process is configured%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
}
- }
-
- /* Check IP address argument. */
- ret = str2prefix (ip_str, &match);
- if (! ret)
- {
- vty_out (vty, "%% address is malformed%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
- match.family = afi2family (afi);
+ /* Check IP address argument. */
+ ret = str2prefix(ip_str, &match);
+ if (!ret) {
+ vty_out(vty, "%% address is malformed%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP) || (safi == SAFI_EVPN))
- {
- for (rn = bgp_table_top (bgp->rib[AFI_IP][safi]); rn; rn = bgp_route_next (rn))
- {
- if (prd && memcmp (rn->p.u.val, prd->val, 8) != 0)
- continue;
-
- if ((table = rn->info) != NULL)
- if ((rm = bgp_node_match (table, &match)) != NULL)
- {
- if (! prefix_check || rm->p.prefixlen == match.prefixlen)
- {
- ri = rm->info;
- while (ri)
- {
- if (ri->extra && ri->extra->damp_info)
- {
- ri_temp = ri->next;
- bgp_damp_info_free (ri->extra->damp_info, 1);
- ri = ri_temp;
- }
- else
- ri = ri->next;
- }
- }
-
- bgp_unlock_node (rm);
- }
- }
- }
- else
- {
- if ((rn = bgp_node_match (bgp->rib[afi][safi], &match)) != NULL)
- {
- if (! prefix_check || rn->p.prefixlen == match.prefixlen)
- {
- ri = rn->info;
- while (ri)
- {
- if (ri->extra && ri->extra->damp_info)
- {
- ri_temp = ri->next;
- bgp_damp_info_free (ri->extra->damp_info, 1);
- ri = ri_temp;
- }
- else
- ri = ri->next;
- }
- }
-
- bgp_unlock_node (rn);
- }
- }
+ match.family = afi2family(afi);
+
+ if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
+ || (safi == SAFI_EVPN)) {
+ for (rn = bgp_table_top(bgp->rib[AFI_IP][safi]); rn;
+ rn = bgp_route_next(rn)) {
+ if (prd && memcmp(rn->p.u.val, prd->val, 8) != 0)
+ continue;
+
+ if ((table = rn->info) != NULL)
+ if ((rm = bgp_node_match(table, &match))
+ != NULL) {
+ if (!prefix_check
+ || rm->p.prefixlen
+ == match.prefixlen) {
+ ri = rm->info;
+ while (ri) {
+ if (ri->extra
+ && ri->extra
+ ->damp_info) {
+ ri_temp =
+ ri->next;
+ bgp_damp_info_free(
+ ri->extra
+ ->damp_info,
+ 1);
+ ri = ri_temp;
+ } else
+ ri = ri->next;
+ }
+ }
+
+ bgp_unlock_node(rm);
+ }
+ }
+ } else {
+ if ((rn = bgp_node_match(bgp->rib[afi][safi], &match))
+ != NULL) {
+ if (!prefix_check
+ || rn->p.prefixlen == match.prefixlen) {
+ ri = rn->info;
+ while (ri) {
+ if (ri->extra && ri->extra->damp_info) {
+ ri_temp = ri->next;
+ bgp_damp_info_free(
+ ri->extra->damp_info,
+ 1);
+ ri = ri_temp;
+ } else
+ ri = ri->next;
+ }
+ }
+
+ bgp_unlock_node(rn);
+ }
+ }
- return CMD_SUCCESS;
+ return CMD_SUCCESS;
}
DEFUN (clear_ip_bgp_dampening,
@@ -10330,8 +10494,8 @@ DEFUN (clear_ip_bgp_dampening,
BGP_STR
"Clear route flap dampening information\n")
{
- bgp_damp_info_clean ();
- return CMD_SUCCESS;
+ bgp_damp_info_clean();
+ return CMD_SUCCESS;
}
DEFUN (clear_ip_bgp_dampening_prefix,
@@ -10343,9 +10507,9 @@ DEFUN (clear_ip_bgp_dampening_prefix,
"Clear route flap dampening information\n"
"IPv4 prefix\n")
{
- int idx_ipv4_prefixlen = 4;
- return bgp_clear_damp_route (vty, NULL, argv[idx_ipv4_prefixlen]->arg, AFI_IP,
- SAFI_UNICAST, NULL, 1);
+ int idx_ipv4_prefixlen = 4;
+ return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4_prefixlen]->arg,
+ AFI_IP, SAFI_UNICAST, NULL, 1);
}
DEFUN (clear_ip_bgp_dampening_address,
@@ -10357,9 +10521,9 @@ DEFUN (clear_ip_bgp_dampening_address,
"Clear route flap dampening information\n"
"Network to clear damping information\n")
{
- int idx_ipv4 = 4;
- return bgp_clear_damp_route (vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
- SAFI_UNICAST, NULL, 0);
+ int idx_ipv4 = 4;
+ return bgp_clear_damp_route(vty, NULL, argv[idx_ipv4]->arg, AFI_IP,
+ SAFI_UNICAST, NULL, 0);
}
DEFUN (clear_ip_bgp_dampening_address_mask,
@@ -10372,425 +10536,455 @@ DEFUN (clear_ip_bgp_dampening_address_mask,
"Network to clear damping information\n"
"Network mask\n")
{
- int idx_ipv4 = 4;
- int idx_ipv4_2 = 5;
- int ret;
- char prefix_str[BUFSIZ];
+ int idx_ipv4 = 4;
+ int idx_ipv4_2 = 5;
+ int ret;
+ char prefix_str[BUFSIZ];
- ret = netmask_str2prefix_str (argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg, prefix_str);
- if (! ret)
- {
- vty_out (vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
- return CMD_WARNING;
- }
+ ret = netmask_str2prefix_str(argv[idx_ipv4]->arg, argv[idx_ipv4_2]->arg,
+ prefix_str);
+ if (!ret) {
+ vty_out(vty, "%% Inconsistent address and mask%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
- return bgp_clear_damp_route (vty, NULL, prefix_str, AFI_IP,
- SAFI_UNICAST, NULL, 0);
+ return bgp_clear_damp_route(vty, NULL, prefix_str, AFI_IP, SAFI_UNICAST,
+ NULL, 0);
}
/* also used for encap safi */
-static int
-bgp_config_write_network_vpn (struct vty *vty, struct bgp *bgp,
- afi_t afi, safi_t safi, int *write)
-{
- struct bgp_node *prn;
- struct bgp_node *rn;
- struct bgp_table *table;
- struct prefix *p;
- struct prefix_rd *prd;
- struct bgp_static *bgp_static;
- u_int32_t label;
- char buf[SU_ADDRSTRLEN];
- char rdbuf[RD_ADDRSTRLEN];
-
- /* Network configuration. */
- for (prn = bgp_table_top (bgp->route[afi][safi]); prn; prn = bgp_route_next (prn))
- if ((table = prn->info) != NULL)
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- if ((bgp_static = rn->info) != NULL)
- {
- p = &rn->p;
- prd = (struct prefix_rd *) &prn->p;
-
- /* "address-family" display. */
- bgp_config_write_family_header (vty, afi, safi, write);
-
- /* "network" configuration display. */
- prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN);
- label = decode_label (bgp_static->tag);
-
- vty_out (vty, " network %s/%d rd %s",
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen, rdbuf);
- if (safi == SAFI_MPLS_VPN)
- vty_out (vty, " label %u", label);
-
- if (bgp_static->rmap.name)
- vty_out (vty, " route-map %s", bgp_static->rmap.name);
- else
- {
- if (bgp_static->backdoor)
- vty_out (vty, " backdoor");
- }
- vty_out (vty, "%s", VTY_NEWLINE);
- }
- return 0;
-}
-
-static int
-bgp_config_write_network_evpn (struct vty *vty, struct bgp *bgp,
- afi_t afi, safi_t safi, int *write)
-{
- struct bgp_node *prn;
- struct bgp_node *rn;
- struct bgp_table *table;
- struct prefix *p;
- struct prefix_rd *prd;
- struct bgp_static *bgp_static;
- char buf[PREFIX_STRLEN];
- char buf2[SU_ADDRSTRLEN];
- char rdbuf[RD_ADDRSTRLEN];
-
- /* Network configuration. */
- for (prn = bgp_table_top (bgp->route[afi][safi]); prn; prn = bgp_route_next (prn))
- if ((table = prn->info) != NULL)
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- if ((bgp_static = rn->info) != NULL)
- {
- char *macrouter = NULL;
- char *esi = NULL;
-
- if(bgp_static->router_mac)
- macrouter = prefix_mac2str(bgp_static->router_mac, NULL, 0);
- if(bgp_static->eth_s_id)
- esi = esi2str(bgp_static->eth_s_id);
- p = &rn->p;
- prd = (struct prefix_rd *) &prn->p;
-
- /* "address-family" display. */
- bgp_config_write_family_header (vty, afi, safi, write);
-
- /* "network" configuration display. */
- prefix_rd2str (prd, rdbuf, RD_ADDRSTRLEN);
-
- inet_ntop (AF_INET, &bgp_static->igpnexthop, buf2, SU_ADDRSTRLEN);
-
- prefix2str (p, buf, sizeof (buf)),
- vty_out (vty, " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
- buf, rdbuf, p->u.prefix_evpn.eth_tag,
- decode_label (bgp_static->tag), esi, buf2 , macrouter);
- vty_out (vty, "%s", VTY_NEWLINE);
- if (macrouter)
- XFREE (MTYPE_TMP, macrouter);
- if (esi)
- XFREE (MTYPE_TMP, esi);
- }
- return 0;
+static int bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
+ afi_t afi, safi_t safi, int *write)
+{
+ struct bgp_node *prn;
+ struct bgp_node *rn;
+ struct bgp_table *table;
+ struct prefix *p;
+ struct prefix_rd *prd;
+ struct bgp_static *bgp_static;
+ u_int32_t label;
+ char buf[SU_ADDRSTRLEN];
+ char rdbuf[RD_ADDRSTRLEN];
+
+ /* Network configuration. */
+ for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
+ prn = bgp_route_next(prn))
+ if ((table = prn->info) != NULL)
+ for (rn = bgp_table_top(table); rn;
+ rn = bgp_route_next(rn))
+ if ((bgp_static = rn->info) != NULL) {
+ p = &rn->p;
+ prd = (struct prefix_rd *)&prn->p;
+
+ /* "address-family" display. */
+ bgp_config_write_family_header(
+ vty, afi, safi, write);
+
+ /* "network" configuration display. */
+ prefix_rd2str(prd, rdbuf,
+ RD_ADDRSTRLEN);
+ label = decode_label(bgp_static->tag);
+
+ vty_out(vty, " network %s/%d rd %s",
+ inet_ntop(p->family,
+ &p->u.prefix, buf,
+ SU_ADDRSTRLEN),
+ p->prefixlen, rdbuf);
+ if (safi == SAFI_MPLS_VPN)
+ vty_out(vty, " label %u",
+ label);
+
+ if (bgp_static->rmap.name)
+ vty_out(vty, " route-map %s",
+ bgp_static->rmap.name);
+ else {
+ if (bgp_static->backdoor)
+ vty_out(vty,
+ " backdoor");
+ }
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
+ return 0;
+}
+
+static int bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
+ afi_t afi, safi_t safi, int *write)
+{
+ struct bgp_node *prn;
+ struct bgp_node *rn;
+ struct bgp_table *table;
+ struct prefix *p;
+ struct prefix_rd *prd;
+ struct bgp_static *bgp_static;
+ char buf[PREFIX_STRLEN];
+ char buf2[SU_ADDRSTRLEN];
+ char rdbuf[RD_ADDRSTRLEN];
+
+ /* Network configuration. */
+ for (prn = bgp_table_top(bgp->route[afi][safi]); prn;
+ prn = bgp_route_next(prn))
+ if ((table = prn->info) != NULL)
+ for (rn = bgp_table_top(table); rn;
+ rn = bgp_route_next(rn))
+ if ((bgp_static = rn->info) != NULL) {
+ char *macrouter = NULL;
+ char *esi = NULL;
+
+ if (bgp_static->router_mac)
+ macrouter = prefix_mac2str(
+ bgp_static->router_mac,
+ NULL, 0);
+ if (bgp_static->eth_s_id)
+ esi = esi2str(
+ bgp_static->eth_s_id);
+ p = &rn->p;
+ prd = (struct prefix_rd *)&prn->p;
+
+ /* "address-family" display. */
+ bgp_config_write_family_header(
+ vty, afi, safi, write);
+
+ /* "network" configuration display. */
+ prefix_rd2str(prd, rdbuf,
+ RD_ADDRSTRLEN);
+
+ inet_ntop(AF_INET,
+ &bgp_static->igpnexthop, buf2,
+ SU_ADDRSTRLEN);
+
+ prefix2str(p, buf, sizeof(buf)),
+ vty_out(vty,
+ " network %s rd %s ethtag %u tag %u esi %s gwip %s routermac %s",
+ buf, rdbuf,
+ p->u.prefix_evpn
+ .eth_tag,
+ decode_label(
+ bgp_static
+ ->tag),
+ esi, buf2, macrouter);
+ vty_out(vty, "%s", VTY_NEWLINE);
+ if (macrouter)
+ XFREE(MTYPE_TMP, macrouter);
+ if (esi)
+ XFREE(MTYPE_TMP, esi);
+ }
+ return 0;
}
/* Configuration of static route announcement and aggregate
information. */
-int
-bgp_config_write_network (struct vty *vty, struct bgp *bgp,
- afi_t afi, safi_t safi, int *write)
-{
- struct bgp_node *rn;
- struct prefix *p;
- struct bgp_static *bgp_static;
- struct bgp_aggregate *bgp_aggregate;
- char buf[SU_ADDRSTRLEN];
-
- if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
- return bgp_config_write_network_vpn (vty, bgp, afi, safi, write);
-
- if (afi == AFI_L2VPN && safi == SAFI_EVPN)
- return bgp_config_write_network_evpn (vty, bgp, afi, safi, write);
-
- /* Network configuration. */
- for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
- if ((bgp_static = rn->info) != NULL)
- {
- p = &rn->p;
-
- /* "address-family" display. */
- bgp_config_write_family_header (vty, afi, safi, write);
-
- /* "network" configuration display. */
- if (bgp_option_check (BGP_OPT_CONFIG_CISCO) && afi == AFI_IP)
- {
- u_int32_t destination;
- struct in_addr netmask;
-
- destination = ntohl (p->u.prefix4.s_addr);
- masklen2ip (p->prefixlen, &netmask);
- vty_out (vty, " network %s",
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN));
-
- if ((IN_CLASSC (destination) && p->prefixlen == 24)
- || (IN_CLASSB (destination) && p->prefixlen == 16)
- || (IN_CLASSA (destination) && p->prefixlen == 8)
- || p->u.prefix4.s_addr == 0)
- {
- /* Natural mask is not display. */
- }
- else
- vty_out (vty, " mask %s", inet_ntoa (netmask));
- }
- else
- {
- vty_out (vty, " network %s/%d",
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- }
-
- if (bgp_static->rmap.name)
- vty_out (vty, " route-map %s", bgp_static->rmap.name);
- else
- {
- if (bgp_static->backdoor)
- vty_out (vty, " backdoor");
- }
-
- vty_out (vty, "%s", VTY_NEWLINE);
- }
-
- /* Aggregate-address configuration. */
- for (rn = bgp_table_top (bgp->aggregate[afi][safi]); rn; rn = bgp_route_next (rn))
- if ((bgp_aggregate = rn->info) != NULL)
- {
- p = &rn->p;
-
- /* "address-family" display. */
- bgp_config_write_family_header (vty, afi, safi, write);
+int bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
+ safi_t safi, int *write)
+{
+ struct bgp_node *rn;
+ struct prefix *p;
+ struct bgp_static *bgp_static;
+ struct bgp_aggregate *bgp_aggregate;
+ char buf[SU_ADDRSTRLEN];
+
+ if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP))
+ return bgp_config_write_network_vpn(vty, bgp, afi, safi, write);
+
+ if (afi == AFI_L2VPN && safi == SAFI_EVPN)
+ return bgp_config_write_network_evpn(vty, bgp, afi, safi,
+ write);
+
+ /* Network configuration. */
+ for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
+ rn = bgp_route_next(rn))
+ if ((bgp_static = rn->info) != NULL) {
+ p = &rn->p;
+
+ /* "address-family" display. */
+ bgp_config_write_family_header(vty, afi, safi, write);
+
+ /* "network" configuration display. */
+ if (bgp_option_check(BGP_OPT_CONFIG_CISCO)
+ && afi == AFI_IP) {
+ u_int32_t destination;
+ struct in_addr netmask;
+
+ destination = ntohl(p->u.prefix4.s_addr);
+ masklen2ip(p->prefixlen, &netmask);
+ vty_out(vty, " network %s",
+ inet_ntop(p->family, &p->u.prefix, buf,
+ SU_ADDRSTRLEN));
+
+ if ((IN_CLASSC(destination)
+ && p->prefixlen == 24)
+ || (IN_CLASSB(destination)
+ && p->prefixlen == 16)
+ || (IN_CLASSA(destination)
+ && p->prefixlen == 8)
+ || p->u.prefix4.s_addr == 0) {
+ /* Natural mask is not display. */
+ } else
+ vty_out(vty, " mask %s",
+ inet_ntoa(netmask));
+ } else {
+ vty_out(vty, " network %s/%d",
+ inet_ntop(p->family, &p->u.prefix, buf,
+ SU_ADDRSTRLEN),
+ p->prefixlen);
+ }
+
+ if (bgp_static->rmap.name)
+ vty_out(vty, " route-map %s",
+ bgp_static->rmap.name);
+ else {
+ if (bgp_static->backdoor)
+ vty_out(vty, " backdoor");
+ }
+
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
- if (bgp_option_check (BGP_OPT_CONFIG_CISCO) && afi == AFI_IP)
- {
- struct in_addr netmask;
+ /* Aggregate-address configuration. */
+ for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
+ rn = bgp_route_next(rn))
+ if ((bgp_aggregate = rn->info) != NULL) {
+ p = &rn->p;
+
+ /* "address-family" display. */
+ bgp_config_write_family_header(vty, afi, safi, write);
+
+ if (bgp_option_check(BGP_OPT_CONFIG_CISCO)
+ && afi == AFI_IP) {
+ struct in_addr netmask;
+
+ masklen2ip(p->prefixlen, &netmask);
+ vty_out(vty, " aggregate-address %s %s",
+ inet_ntop(p->family, &p->u.prefix, buf,
+ SU_ADDRSTRLEN),
+ inet_ntoa(netmask));
+ } else {
+ vty_out(vty, " aggregate-address %s/%d",
+ inet_ntop(p->family, &p->u.prefix, buf,
+ SU_ADDRSTRLEN),
+ p->prefixlen);
+ }
+
+ if (bgp_aggregate->as_set)
+ vty_out(vty, " as-set");
+
+ if (bgp_aggregate->summary_only)
+ vty_out(vty, " summary-only");
+
+ vty_out(vty, "%s", VTY_NEWLINE);
+ }
- masklen2ip (p->prefixlen, &netmask);
- vty_out (vty, " aggregate-address %s %s",
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- inet_ntoa (netmask));
- }
- else
- {
- vty_out (vty, " aggregate-address %s/%d",
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen);
- }
-
- if (bgp_aggregate->as_set)
- vty_out (vty, " as-set");
-
- if (bgp_aggregate->summary_only)
- vty_out (vty, " summary-only");
-
- vty_out (vty, "%s", VTY_NEWLINE);
- }
-
- return 0;
-}
-
-int
-bgp_config_write_distance (struct vty *vty, struct bgp *bgp, afi_t afi,
- safi_t safi, int *write)
-{
- struct bgp_node *rn;
- struct bgp_distance *bdistance;
-
- /* Distance configuration. */
- if (bgp->distance_ebgp[afi][safi]
- && bgp->distance_ibgp[afi][safi]
- && bgp->distance_local[afi][safi]
- && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
- || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
- || bgp->distance_local[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT))
- {
- bgp_config_write_family_header (vty, afi, safi, write);
- vty_out (vty, " distance bgp %d %d %d%s",
- bgp->distance_ebgp[afi][safi], bgp->distance_ibgp[afi][safi],
- bgp->distance_local[afi][safi], VTY_NEWLINE);
- }
+ return 0;
+}
- for (rn = bgp_table_top (bgp_distance_table[afi][safi]); rn;
- rn = bgp_route_next (rn))
- if ((bdistance = rn->info) != NULL)
- {
- char buf[PREFIX_STRLEN];
+int bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
+ safi_t safi, int *write)
+{
+ struct bgp_node *rn;
+ struct bgp_distance *bdistance;
+
+ /* Distance configuration. */
+ if (bgp->distance_ebgp[afi][safi] && bgp->distance_ibgp[afi][safi]
+ && bgp->distance_local[afi][safi]
+ && (bgp->distance_ebgp[afi][safi] != ZEBRA_EBGP_DISTANCE_DEFAULT
+ || bgp->distance_ibgp[afi][safi] != ZEBRA_IBGP_DISTANCE_DEFAULT
+ || bgp->distance_local[afi][safi]
+ != ZEBRA_IBGP_DISTANCE_DEFAULT)) {
+ bgp_config_write_family_header(vty, afi, safi, write);
+ vty_out(vty, " distance bgp %d %d %d%s",
+ bgp->distance_ebgp[afi][safi],
+ bgp->distance_ibgp[afi][safi],
+ bgp->distance_local[afi][safi], VTY_NEWLINE);
+ }
- bgp_config_write_family_header (vty, afi, safi, write);
- vty_out (vty, " distance %d %s %s%s", bdistance->distance,
- prefix2str (&rn->p, buf, sizeof (buf)),
- bdistance->access_list ? bdistance->access_list : "",
- VTY_NEWLINE);
- }
+ for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
+ rn = bgp_route_next(rn))
+ if ((bdistance = rn->info) != NULL) {
+ char buf[PREFIX_STRLEN];
+
+ bgp_config_write_family_header(vty, afi, safi, write);
+ vty_out(vty, " distance %d %s %s%s",
+ bdistance->distance,
+ prefix2str(&rn->p, buf, sizeof(buf)),
+ bdistance->access_list ? bdistance->access_list
+ : "",
+ VTY_NEWLINE);
+ }
- return *write;
+ return *write;
}
/* Allocate routing table structure and install commands. */
-void
-bgp_route_init (void)
-{
- afi_t afi;
- safi_t safi;
-
- /* Init BGP distance table. */
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- bgp_distance_table[afi][safi] = bgp_table_init (afi, safi);
-
- /* IPv4 BGP commands. */
- install_element (BGP_NODE, &bgp_table_map_cmd);
- install_element (BGP_NODE, &bgp_network_cmd);
- install_element (BGP_NODE, &bgp_network_mask_cmd);
- install_element (BGP_NODE, &bgp_network_mask_natural_cmd);
- install_element (BGP_NODE, &bgp_network_route_map_cmd);
- install_element (BGP_NODE, &bgp_network_mask_route_map_cmd);
- install_element (BGP_NODE, &bgp_network_mask_natural_route_map_cmd);
- install_element (BGP_NODE, &bgp_network_backdoor_cmd);
- install_element (BGP_NODE, &bgp_network_mask_backdoor_cmd);
- install_element (BGP_NODE, &bgp_network_mask_natural_backdoor_cmd);
- install_element (BGP_NODE, &no_bgp_table_map_cmd);
- install_element (BGP_NODE, &no_bgp_network_cmd);
- install_element (BGP_NODE, &no_bgp_network_mask_cmd);
- install_element (BGP_NODE, &no_bgp_network_mask_natural_cmd);
-
- install_element (BGP_NODE, &aggregate_address_cmd);
- install_element (BGP_NODE, &aggregate_address_mask_cmd);
- install_element (BGP_NODE, &no_aggregate_address_cmd);
- install_element (BGP_NODE, &no_aggregate_address_mask_cmd);
-
- /* IPv4 unicast configuration. */
- install_element (BGP_IPV4_NODE, &bgp_table_map_cmd);
- install_element (BGP_IPV4_NODE, &bgp_network_cmd);
- install_element (BGP_IPV4_NODE, &bgp_network_mask_cmd);
- install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_cmd);
- install_element (BGP_IPV4_NODE, &bgp_network_route_map_cmd);
- install_element (BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd);
- install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_table_map_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_network_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_network_mask_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_cmd);
-
- install_element (BGP_IPV4_NODE, &aggregate_address_cmd);
- install_element (BGP_IPV4_NODE, &aggregate_address_mask_cmd);
- install_element (BGP_IPV4_NODE, &no_aggregate_address_cmd);
- install_element (BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
-
- /* IPv4 multicast configuration. */
- install_element (BGP_IPV4M_NODE, &bgp_table_map_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_network_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_network_mask_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_network_route_map_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_network_mask_route_map_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_route_map_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_network_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_cmd);
- install_element (BGP_IPV4M_NODE, &aggregate_address_cmd);
- install_element (BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
- install_element (BGP_IPV4M_NODE, &no_aggregate_address_cmd);
- install_element (BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
-
- install_element (VIEW_NODE, &show_ip_bgp_instance_all_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_route_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_regexp_cmd);
-
- install_element (VIEW_NODE, &show_ip_bgp_instance_neighbor_advertised_route_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd);
+void bgp_route_init(void)
+{
+ afi_t afi;
+ safi_t safi;
+
+ /* Init BGP distance table. */
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ bgp_distance_table[afi][safi] =
+ bgp_table_init(afi, safi);
+
+ /* IPv4 BGP commands. */
+ install_element(BGP_NODE, &bgp_table_map_cmd);
+ install_element(BGP_NODE, &bgp_network_cmd);
+ install_element(BGP_NODE, &bgp_network_mask_cmd);
+ install_element(BGP_NODE, &bgp_network_mask_natural_cmd);
+ install_element(BGP_NODE, &bgp_network_route_map_cmd);
+ install_element(BGP_NODE, &bgp_network_mask_route_map_cmd);
+ install_element(BGP_NODE, &bgp_network_mask_natural_route_map_cmd);
+ install_element(BGP_NODE, &bgp_network_backdoor_cmd);
+ install_element(BGP_NODE, &bgp_network_mask_backdoor_cmd);
+ install_element(BGP_NODE, &bgp_network_mask_natural_backdoor_cmd);
+ install_element(BGP_NODE, &no_bgp_table_map_cmd);
+ install_element(BGP_NODE, &no_bgp_network_cmd);
+ install_element(BGP_NODE, &no_bgp_network_mask_cmd);
+ install_element(BGP_NODE, &no_bgp_network_mask_natural_cmd);
+
+ install_element(BGP_NODE, &aggregate_address_cmd);
+ install_element(BGP_NODE, &aggregate_address_mask_cmd);
+ install_element(BGP_NODE, &no_aggregate_address_cmd);
+ install_element(BGP_NODE, &no_aggregate_address_mask_cmd);
+
+ /* IPv4 unicast configuration. */
+ install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
+ install_element(BGP_IPV4_NODE, &bgp_network_cmd);
+ install_element(BGP_IPV4_NODE, &bgp_network_mask_cmd);
+ install_element(BGP_IPV4_NODE, &bgp_network_mask_natural_cmd);
+ install_element(BGP_IPV4_NODE, &bgp_network_route_map_cmd);
+ install_element(BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd);
+ install_element(BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd);
+ install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
+ install_element(BGP_IPV4_NODE, &no_bgp_network_cmd);
+ install_element(BGP_IPV4_NODE, &no_bgp_network_mask_cmd);
+ install_element(BGP_IPV4_NODE, &no_bgp_network_mask_natural_cmd);
+
+ install_element(BGP_IPV4_NODE, &aggregate_address_cmd);
+ install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd);
+ install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd);
+ install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
+
+ /* IPv4 multicast configuration. */
+ install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
+ install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
+ install_element(BGP_IPV4M_NODE, &bgp_network_mask_cmd);
+ install_element(BGP_IPV4M_NODE, &bgp_network_mask_natural_cmd);
+ install_element(BGP_IPV4M_NODE, &bgp_network_route_map_cmd);
+ install_element(BGP_IPV4M_NODE, &bgp_network_mask_route_map_cmd);
+ install_element(BGP_IPV4M_NODE,
+ &bgp_network_mask_natural_route_map_cmd);
+ install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
+ install_element(BGP_IPV4M_NODE, &no_bgp_network_cmd);
+ install_element(BGP_IPV4M_NODE, &no_bgp_network_mask_cmd);
+ install_element(BGP_IPV4M_NODE, &no_bgp_network_mask_natural_cmd);
+ install_element(BGP_IPV4M_NODE, &aggregate_address_cmd);
+ install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
+ install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd);
+ install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
+
+ install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
+ install_element(VIEW_NODE, &show_ip_bgp_cmd);
+ install_element(VIEW_NODE, &show_ip_bgp_route_cmd);
+ install_element(VIEW_NODE, &show_ip_bgp_regexp_cmd);
+
+ install_element(VIEW_NODE,
+ &show_ip_bgp_instance_neighbor_advertised_route_cmd);
+ install_element(VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd);
+ install_element(VIEW_NODE,
+ &show_ip_bgp_neighbor_received_prefix_filter_cmd);
#ifdef KEEP_OLD_VPN_COMMANDS
- install_element (VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
+ install_element(VIEW_NODE, &show_ip_bgp_vpn_all_route_prefix_cmd);
#endif /* KEEP_OLD_VPN_COMMANDS */
- install_element (VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd);
-
- /* BGP dampening clear commands */
- install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
+ install_element(VIEW_NODE, &show_bgp_afi_vpn_rd_route_cmd);
+ install_element(VIEW_NODE,
+ &show_ip_bgp_l2vpn_evpn_all_route_prefix_cmd);
+
+ /* BGP dampening clear commands */
+ install_element(ENABLE_NODE, &clear_ip_bgp_dampening_cmd);
+ install_element(ENABLE_NODE, &clear_ip_bgp_dampening_prefix_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
- install_element (ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
+ install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd);
+ install_element(ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd);
- /* prefix count */
- install_element (ENABLE_NODE, &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
+ /* prefix count */
+ install_element(ENABLE_NODE,
+ &show_ip_bgp_instance_neighbor_prefix_counts_cmd);
#ifdef KEEP_OLD_VPN_COMMANDS
- install_element (ENABLE_NODE, &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
+ install_element(ENABLE_NODE,
+ &show_ip_bgp_vpn_neighbor_prefix_counts_cmd);
#endif /* KEEP_OLD_VPN_COMMANDS */
- /* New config IPv6 BGP commands. */
- install_element (BGP_IPV6_NODE, &bgp_table_map_cmd);
- install_element (BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
- install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd);
- install_element (BGP_IPV6_NODE, &no_bgp_table_map_cmd);
- install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd);
-
- install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
- install_element (BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
-
- install_element (BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
- install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_network_cmd);
-
- install_element (BGP_NODE, &bgp_distance_cmd);
- install_element (BGP_NODE, &no_bgp_distance_cmd);
- install_element (BGP_NODE, &bgp_distance_source_cmd);
- install_element (BGP_NODE, &no_bgp_distance_source_cmd);
- install_element (BGP_NODE, &bgp_distance_source_access_list_cmd);
- install_element (BGP_NODE, &no_bgp_distance_source_access_list_cmd);
- install_element (BGP_IPV4_NODE, &bgp_distance_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_distance_cmd);
- install_element (BGP_IPV4_NODE, &bgp_distance_source_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
- install_element (BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
- install_element (BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_distance_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_distance_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_distance_source_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
- install_element (BGP_IPV4M_NODE, &no_bgp_distance_source_access_list_cmd);
- install_element (BGP_IPV6_NODE, &bgp_distance_cmd);
- install_element (BGP_IPV6_NODE, &no_bgp_distance_cmd);
- install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
- install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
- install_element (BGP_IPV6_NODE, &ipv6_bgp_distance_source_access_list_cmd);
- install_element (BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_access_list_cmd);
- install_element (BGP_IPV6M_NODE, &bgp_distance_cmd);
- install_element (BGP_IPV6M_NODE, &no_bgp_distance_cmd);
- install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
- install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
- install_element (BGP_IPV6M_NODE, &ipv6_bgp_distance_source_access_list_cmd);
- install_element (BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_access_list_cmd);
-
- install_element (BGP_NODE, &bgp_damp_set_cmd);
- install_element (BGP_NODE, &bgp_damp_unset_cmd);
- install_element (BGP_IPV4_NODE, &bgp_damp_set_cmd);
- install_element (BGP_IPV4_NODE, &bgp_damp_unset_cmd);
-
- /* IPv4 Multicast Mode */
- install_element (BGP_IPV4M_NODE, &bgp_damp_set_cmd);
- install_element (BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
-
- /* Large Communities */
- install_element (VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
- install_element (VIEW_NODE, &show_ip_bgp_large_community_cmd);
-}
-
-void
-bgp_route_finish (void)
-{
- afi_t afi;
- safi_t safi;
-
- for (afi = AFI_IP; afi < AFI_MAX; afi++)
- for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
- {
- bgp_table_unlock (bgp_distance_table[afi][safi]);
- bgp_distance_table[afi][safi] = NULL;
- }
+ /* New config IPv6 BGP commands. */
+ install_element(BGP_IPV6_NODE, &bgp_table_map_cmd);
+ install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
+ install_element(BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd);
+ install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
+ install_element(BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd);
+
+ install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
+ install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
+
+ install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
+ install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_network_cmd);
+
+ install_element(BGP_NODE, &bgp_distance_cmd);
+ install_element(BGP_NODE, &no_bgp_distance_cmd);
+ install_element(BGP_NODE, &bgp_distance_source_cmd);
+ install_element(BGP_NODE, &no_bgp_distance_source_cmd);
+ install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
+ install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
+ install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
+ install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
+ install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
+ install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
+ install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
+ install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
+ install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
+ install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
+ install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
+ install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
+ install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
+ install_element(BGP_IPV4M_NODE,
+ &no_bgp_distance_source_access_list_cmd);
+ install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
+ install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
+ install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
+ install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
+ install_element(BGP_IPV6_NODE,
+ &ipv6_bgp_distance_source_access_list_cmd);
+ install_element(BGP_IPV6_NODE,
+ &no_ipv6_bgp_distance_source_access_list_cmd);
+ install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
+ install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
+ install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
+ install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
+ install_element(BGP_IPV6M_NODE,
+ &ipv6_bgp_distance_source_access_list_cmd);
+ install_element(BGP_IPV6M_NODE,
+ &no_ipv6_bgp_distance_source_access_list_cmd);
+
+ install_element(BGP_NODE, &bgp_damp_set_cmd);
+ install_element(BGP_NODE, &bgp_damp_unset_cmd);
+ install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
+ install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
+
+ /* IPv4 Multicast Mode */
+ install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
+ install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
+
+ /* Large Communities */
+ install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
+ install_element(VIEW_NODE, &show_ip_bgp_large_community_cmd);
+}
+
+void bgp_route_finish(void)
+{
+ afi_t afi;
+ safi_t safi;
+
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) {
+ bgp_table_unlock(bgp_distance_table[afi][safi]);
+ bgp_distance_table[afi][safi] = NULL;
+ }
}