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.c3262
1 files changed, 2030 insertions, 1232 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index aabd264a..bcf23db5 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -36,6 +36,9 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "workqueue.h"
#include "bgpd/bgpd.h"
+
+#include "bgpd/bgp_peer.h"
+
#include "bgpd/bgp_table.h"
#include "bgpd/bgp_route.h"
#include "bgpd/bgp_attr.h"
@@ -58,18 +61,18 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
/* Extern from bgp_dump.c */
extern const char *bgp_origin_str[];
extern const char *bgp_origin_long_str[];
-
+
static 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)
{
prn = bgp_node_get (table, (struct prefix *) prd);
@@ -88,7 +91,7 @@ bgp_afi_node_get (struct bgp_table *table, afi_t afi, safi_t safi, struct prefix
return rn;
}
-
+
/* Allocate bgp_info_extra */
static struct bgp_info_extra *
bgp_info_extra_new (void)
@@ -105,11 +108,11 @@ bgp_info_extra_free (struct bgp_info_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;
}
}
@@ -138,10 +141,8 @@ bgp_info_free (struct bgp_info *binfo)
{
if (binfo->attr)
bgp_attr_unintern (&binfo->attr);
-
- bgp_info_extra_free (&binfo->extra);
- peer_unlock (binfo->peer); /* bgp_info peer reference */
+ bgp_info_extra_free (&binfo->extra);
XFREE (MTYPE_BGP_ROUTE, binfo);
}
@@ -158,7 +159,7 @@ bgp_info_unlock (struct bgp_info *binfo)
{
assert (binfo && binfo->lock > 0);
binfo->lock--;
-
+
if (binfo->lock == 0)
{
#if 0
@@ -176,42 +177,67 @@ bgp_info_unlock (struct bgp_info *binfo)
zlog_backtrace (LOG_DEBUG);
}
#endif
-
+
return binfo;
}
void
bgp_info_add (struct bgp_node *rn, struct bgp_info *ri)
{
- struct bgp_info *top;
+ bgp_peer peer = ri->peer ;
+ struct bgp_info** routes_head ;
- top = rn->info;
-
- ri->next = rn->info;
- ri->prev = NULL;
- if (top)
- top->prev = ri;
+ /* add to list of routes for this bgp_node */
+ ri->rn = rn ;
+ ri->info_next = rn->info;
+ ri->info_prev = NULL;
+ if (rn->info != NULL)
+ ((struct bgp_info*)rn->info)->info_prev = ri;
rn->info = ri;
-
+
+ /* add to list of routes for this peer */
+ routes_head = &(peer->routes_head[rn->table->afi][rn->table->safi]) ;
+ ri->routes_next = *routes_head ;
+ ri->routes_prev = NULL ;
+ if (*routes_head != NULL)
+ (*routes_head)->routes_prev = ri ;
+ *routes_head = ri ;
+
bgp_info_lock (ri);
bgp_lock_node (rn);
- peer_lock (ri->peer); /* bgp_info peer reference */
+ bgp_peer_lock (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)
{
- if (ri->next)
- ri->next->prev = ri->prev;
- if (ri->prev)
- ri->prev->next = ri->next;
+ bgp_peer peer = ri->peer ;
+ struct bgp_info** routes_head ;
+
+ assert(ri->rn == rn) ;
+
+ /* remove from list of routes for the bgp_node */
+ if (ri->info_next)
+ ri->info_next->info_prev = ri->info_prev;
+ if (ri->info_prev)
+ ri->info_prev->info_next = ri->info_next;
else
- rn->info = ri->next;
-
- bgp_info_unlock (ri);
- bgp_unlock_node (rn);
+ rn->info = ri->info_next;
+
+ /* remove from list of routes for the peer */
+ routes_head = &(peer->routes_head[rn->table->afi][rn->table->safi]) ;
+ if (ri->routes_next != NULL)
+ ri->routes_next->routes_prev = ri->routes_prev ;
+ if (ri->routes_prev != NULL)
+ ri->routes_prev->routes_next = ri->routes_next ;
+ else
+ *routes_head = ri->routes_next ;
+
+ bgp_info_unlock (ri); /* fewer references to bgp_info */
+ bgp_unlock_node (rn); /* fewer references to bgp_node */
+ bgp_peer_unlock (peer); /* fewer references to peer */
}
void
@@ -233,7 +259,7 @@ bgp_info_restore (struct bgp_node *rn, struct bgp_info *ri)
SET_FLAG (ri->flags, BGP_INFO_VALID);
}
-/* Adjust pcount as required */
+/* Adjust pcount as required */
static void
bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri)
{
@@ -244,13 +270,13 @@ bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri)
if (rn->table->type != BGP_TABLE_MAIN
|| ri->peer == ri->peer->bgp->peer_self)
return;
-
+
if (BGP_INFO_HOLDDOWN (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[rn->table->afi][rn->table->safi])
ri->peer->pcount[rn->table->afi][rn->table->safi]--;
@@ -260,9 +286,9 @@ bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri)
__func__, ri->peer->host);
zlog_backtrace (LOG_WARNING);
zlog_warn ("%s: Please report to Quagga bugzilla", __func__);
- }
+ }
}
- else if (!BGP_INFO_HOLDDOWN (ri)
+ else if (!BGP_INFO_HOLDDOWN (ri)
&& !CHECK_FLAG (ri->flags, BGP_INFO_COUNTED))
{
SET_FLAG (ri->flags, BGP_INFO_COUNTED);
@@ -278,11 +304,11 @@ 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 useability state */
if (!CHECK_FLAG (flag, BGP_INFO_VALID|BGP_INFO_UNUSEABLE))
return;
-
+
bgp_pcount_adjust (rn, ri);
}
@@ -290,11 +316,11 @@ 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 useability state */
if (!CHECK_FLAG (flag, BGP_INFO_VALID|BGP_INFO_UNUSEABLE))
return;
-
+
bgp_pcount_adjust (rn, ri);
}
@@ -331,6 +357,7 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist)
int internal_as_route = 0;
int confed_as_route = 0;
int ret;
+ bgp_peer_sort_t new_sort, exist_sort ;
/* 0. Null check. */
if (new == NULL)
@@ -358,7 +385,7 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist)
exist_pref = exist->attr->local_pref;
else
exist_pref = bgp->default_local_pref;
-
+
if (new_pref > exist_pref)
return 1;
if (new_pref < exist_pref)
@@ -385,14 +412,14 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist)
{
int exist_hops = aspath_count_hops (exist->attr->aspath);
int exist_confeds = aspath_count_confeds (exist->attr->aspath);
-
+
if (bgp_flag_check (bgp, BGP_FLAG_ASPATH_CONFED))
{
int aspath_hops;
-
+
aspath_hops = aspath_count_hops (new->attr->aspath);
aspath_hops += aspath_count_confeds (new->attr->aspath);
-
+
if ( aspath_hops < (exist_hops + exist_confeds))
return 1;
if ( aspath_hops > (exist_hops + exist_confeds))
@@ -401,7 +428,7 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist)
else
{
int newhops = aspath_count_hops (new->attr->aspath);
-
+
if (newhops < exist_hops)
return 1;
if (newhops > exist_hops)
@@ -422,7 +449,7 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist)
&& aspath_count_confeds (exist->attr->aspath) > 0
&& aspath_count_hops (new->attr->aspath) == 0
&& aspath_count_hops (exist->attr->aspath) == 0);
-
+
if (bgp_flag_check (bgp, BGP_FLAG_ALWAYS_COMPARE_MED)
|| (bgp_flag_check (bgp, BGP_FLAG_MED_CONFED)
&& confed_as_route)
@@ -439,18 +466,18 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist)
return 0;
}
- /* 7. Peer type check. */
- if (peer_sort (new->peer) == BGP_PEER_EBGP
- && peer_sort (exist->peer) == BGP_PEER_IBGP)
+ /* 7. Peer type check. CONFED and iBGP rank equal, "internal" (RFC5065)
+ */
+ new_sort = peer_sort(new->peer) ;
+ exist_sort = peer_sort(exist->peer) ;
+
+ if ((new_sort == BGP_PEER_EBGP) && (exist_sort == BGP_PEER_IBGP))
return 1;
- if (peer_sort (new->peer) == BGP_PEER_EBGP
- && peer_sort (exist->peer) == BGP_PEER_CONFED)
+ if ((new_sort == BGP_PEER_EBGP) && (exist_sort == BGP_PEER_CONFED))
return 1;
- if (peer_sort (new->peer) == BGP_PEER_IBGP
- && peer_sort (exist->peer) == BGP_PEER_EBGP)
+ if ((new_sort == BGP_PEER_IBGP) && (exist_sort == BGP_PEER_EBGP))
return 0;
- if (peer_sort (new->peer) == BGP_PEER_CONFED
- && peer_sort (exist->peer) == BGP_PEER_EBGP)
+ if ((new_sort == BGP_PEER_CONFED) && (exist_sort == BGP_PEER_EBGP))
return 0;
/* 8. IGP metric check. */
@@ -458,7 +485,7 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist)
{
uint32_t newm = (new->extra ? new->extra->igpmetric : 0);
uint32_t existm = (exist->extra ? exist->extra->igpmetric : 0);
-
+
if (newm < existm)
return 1;
if (newm > existm)
@@ -472,8 +499,8 @@ bgp_info_cmp (struct bgp *bgp, struct bgp_info *new, struct bgp_info *exist)
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)
- && peer_sort (new->peer) == BGP_PEER_EBGP
- && peer_sort (exist->peer) == BGP_PEER_EBGP)
+ && (new_sort == BGP_PEER_EBGP)
+ && (exist_sort == BGP_PEER_EBGP) )
{
if (CHECK_FLAG (new->flags, BGP_INFO_SELECTED))
return 1;
@@ -532,31 +559,31 @@ bgp_input_filter (struct peer *peer, struct prefix *p, struct attr *attr,
#define FILTER_EXIST_WARN(F,f,filter) \
if (BGP_DEBUG (update, UPDATE_IN) \
- && !(F ## _IN (filter))) \
+ && !(F ## _IN_LIST (filter))) \
plog_warn (peer->log, "%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)
+
+ if (access_list_apply (DISTRIBUTE_IN_LIST (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)
+
+ if (prefix_list_apply (PREFIX_LIST_IN_LIST(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)
+
+ if (as_list_apply (FILTER_LIST_IN_LIST (filter), attr->aspath)== AS_FILTER_DENY)
return FILTER_DENY;
}
-
+
return FILTER_PERMIT;
#undef FILTER_EXIST_WARN
}
@@ -571,28 +598,29 @@ bgp_output_filter (struct peer *peer, struct prefix *p, struct attr *attr,
#define FILTER_EXIST_WARN(F,f,filter) \
if (BGP_DEBUG (update, UPDATE_OUT) \
- && !(F ## _OUT (filter))) \
+ && !(F ## _OUT_LIST (filter))) \
plog_warn (peer->log, "%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)
+
+ if (access_list_apply (DISTRIBUTE_OUT_LIST (filter), p) == FILTER_DENY)
return FILTER_DENY;
}
- if (PREFIX_LIST_OUT_NAME (filter)) {
+ if (PREFIX_LIST_OUT_REF (filter)) {
FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
-
- if (prefix_list_apply (PREFIX_LIST_OUT (filter), p) == PREFIX_DENY)
+
+ if (prefix_list_apply (PREFIX_LIST_OUT_LIST (filter), p) == PREFIX_DENY)
return FILTER_DENY;
}
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)
+
+ if (as_list_apply (FILTER_LIST_OUT_LIST (filter), attr->aspath)
+ == AS_FILTER_DENY)
return FILTER_DENY;
}
@@ -606,18 +634,19 @@ bgp_community_filter (struct peer *peer, struct attr *attr)
{
if (attr->community)
{
+ bgp_peer_sort_t sort = peer_sort(peer) ;
+
/* NO_ADVERTISE check. */
if (community_include (attr->community, COMMUNITY_NO_ADVERTISE))
return 1;
/* NO_EXPORT check. */
- if (peer_sort (peer) == BGP_PEER_EBGP &&
+ if ((sort == BGP_PEER_EBGP) &&
community_include (attr->community, COMMUNITY_NO_EXPORT))
return 1;
/* NO_EXPORT_SUBCONFED check. */
- if (peer_sort (peer) == BGP_PEER_EBGP
- || peer_sort (peer) == BGP_PEER_CONFED)
+ if ((sort == BGP_PEER_EBGP) || (sort == BGP_PEER_CONFED))
if (community_include (attr->community, COMMUNITY_NO_EXPORT_SUBCONFED))
return 1;
}
@@ -636,139 +665,447 @@ bgp_cluster_filter (struct peer *peer, struct attr *attr)
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
+
+/*------------------------------------------------------------------------------
+ * Process given attributes against any in route-map.
+ *
+ * If the result is RMAP_PERMIT, then returns address of newly internalised
+ * version of the attributes.
+ *
+ * If the result is RMAP_DENY, then returns NULL.
+ *
+ * The structure pointed to by attr is untouched.
+ *
+ * NB: All the elements of the incoming attr must have been internalised.
+ *
+ * This is because a copy -- bgp_attr_dup() -- of those attributes is handed
+ * to the route-map. Any element of the attributes which is changed is
+ * overwritten by the route-map -- and if it has a 0 reference count, the
+ * element will be deleted. Unfortunately, that leaves a dangling reference
+ * in the original attr.
+ */
+static struct attr*
bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
afi_t afi, safi_t safi)
{
struct bgp_filter *filter;
- struct bgp_info info;
- route_map_result_t ret;
+ struct attr rmap_attr_s ;
+ struct attr* rmap_attr ;
+ struct attr* use_attr ;
- filter = &peer->filter[afi][safi];
+ rmap_attr = NULL ;
- /* Apply default weight value. */
+ /* Apply default weight value. */
if (peer->weight)
- (bgp_attr_extra_get (attr))->weight = peer->weight;
+ {
+ rmap_attr = &rmap_attr_s ;
+ bgp_attr_dup (rmap_attr, attr) ;
+
+ (bgp_attr_extra_get (rmap_attr))->weight = peer->weight;
+ } ;
/* Route map apply. */
+ filter = &peer->filter[afi][safi];
+
if (ROUTE_MAP_IN_NAME (filter))
{
- /* Duplicate current value to new strucutre for modification. */
- info.peer = peer;
- info.attr = attr;
+ struct bgp_info info_s = { 0 } ;
+ route_map_result_t ret;
- SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN);
+ if (rmap_attr == NULL)
+ {
+ rmap_attr = &rmap_attr_s ;
+ bgp_attr_dup (rmap_attr, attr) ;
+ } ;
- /* Apply BGP route map to the attribute. */
- ret = route_map_apply (ROUTE_MAP_IN (filter), p, RMAP_BGP, &info);
+ /* Duplicate current value to new structure for modification. */
+ info_s.peer = peer;
+ info_s.attr = rmap_attr;
+
+ SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN);
+
+ /* Apply BGP route map to the attribute. */
+ ret = route_map_apply (ROUTE_MAP_IN (filter), p, RMAP_BGP, &info_s);
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;
- }
+ {
+ /* Discard any new elements set by the route-map -- these will have
+ * reference counts == 0.
+ *
+ * Discard any "extra" part of the duplicated attributes.
+ */
+ bgp_attr_flush (rmap_attr);
+ bgp_attr_extra_free (rmap_attr);
+
+ return NULL ;
+ } ;
+ } ;
+
+ /* If the attributes may have changed, intern the result.
+ *
+ * Otherwise, intern the incoming stuff
+ */
+ if (rmap_attr != NULL)
+ {
+ use_attr = bgp_attr_intern(rmap_attr) ;
+
+ bgp_attr_extra_free (rmap_attr) ;
+ }
+ else
+ use_attr = bgp_attr_intern(attr) ;
+
+ return use_attr ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Structure to capture route-server route.
+ *
+ * Main purpose of this is to do any required rs-in route-map once when
+ * updating a set of route server clients, and not at all if there are no
+ * route server clients for the given afi/safi.
+ */
+struct rs_route
+{
+ bool rs_in_applied ; /* whether rs-in applied yet */
+ bool rs_in_deny ; /* answer when it has been */
+
+ /* The orig_attr MUST have all elements interned, but may or may not be
+ * interned itself.
+ */
+ struct attr* orig_attr ; /* attributes before rs-in applied */
+
+ /* The rs_in_attr is interned when the pointer is set.
+ *
+ * The pointer is NULL if the rs-in has not been applied, and remains NULL
+ * if the answer is RMAP_DENY.
+ */
+ struct attr* rs_in_attr ; /* attributes after rs-in applied */
+
+ /* The other attributes of the route */
+
+ struct peer* peer ;
+
+ afi_t afi ;
+ safi_t safi ;
+
+ struct prefix* p ;
+
+ int type ;
+ int sub_type ;
+
+ struct prefix_rd* prd ;
+ u_char* tag ;
+};
+
+/*------------------------------------------------------------------------------
+ * Set up an rs_route object.
+ */
+static void
+bgp_rs_route_init(struct rs_route* rt, afi_t afi, safi_t safi,
+ struct attr* attr, struct peer* peer, struct prefix* p,
+ int type, int sub_type, struct prefix_rd* prd, u_char* tag)
+{
+ rt->rs_in_applied = false ;
+ rt->rs_in_deny = 0 ; /* invalid while !rs_in_applied */
+ rt->rs_in_attr = NULL ; /* nothing yet */
+
+ rt->orig_attr = attr ;
+
+ rt->peer = peer ;
+ rt->afi = afi ;
+ rt->safi = safi ;
+ rt->p = p ;
+ rt->type = type ;
+ rt->sub_type = sub_type ;
+ rt->prd = prd ;
+ rt->tag = tag ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Reset an rs_route object.
+ *
+ * Discards any rs_in_attr and clears the rs_in_applied flag.
+ *
+ * Leaves everything else -- so can be reused pretty much as is.
+ */
+static void
+bgp_rs_route_reset(struct rs_route* rt)
+{
+ if (rt->rs_in_attr != NULL)
+ {
+ bgp_attr_unintern(&rt->rs_in_attr) ;
+ rt->rs_in_attr = NULL ;
+ } ;
+
+ rt->rs_in_applied = false ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Process rt->orig_attr against any rs-in route-map.
+ *
+ * If the result is RMAP_PERMIT, then rt->rs_in_attr will be set to a newly
+ * internalised version of the attributes.
+ *
+ * If the result is RMAP_DENY, then rt->rs_in_attr is left NULL.
+ *
+ * The structure pointed to by rt->orig_attr is untouched.
+ *
+ * NB: All the elements of the incoming rt->orig_attr must have been
+ * internalised.
+ *
+ * This is because a copy -- bgp_attr_dup() -- of those attributes is handed
+ * to the route-map. Any element of the attributes which is changed is
+ * overwritten by the route-map -- and if it has a 0 reference count, the
+ * element will be deleted. Unfortunately, that leaves a dangling reference
+ * in the original rt->orig_attr.
+ *
+ * NB: must NOT be called more than once for the same "rt", hence the
+ * "rs_in_applied" flag.
+ */
+static void
+bgp_rs_input_modifier (struct rs_route* rt)
+{
+ struct bgp_filter *filter;
+
+ assert(! rt->rs_in_applied && (rt->rs_in_attr == NULL)) ;
+
+ rt->rs_in_applied = true ;
+
+ /* Route map apply. */
+ filter = &rt->peer->filter[rt->afi][rt->safi];
+
+ if (ROUTE_MAP_RS_IN_NAME (filter))
+ {
+ struct bgp_info info_s = { 0 } ;
+ route_map_result_t ret ;
+ struct attr* rmap_attr ;
+ struct attr rmap_attr_s ;
+
+ rmap_attr = &rmap_attr_s ;
+ bgp_attr_dup(rmap_attr, rt->orig_attr) ;
+
+ /* Duplicate current value to new structure for modification. */
+ info_s.peer = rt->peer;
+ info_s.attr = rmap_attr ;
+
+ SET_FLAG (rt->peer->rmap_type, PEER_RMAP_TYPE_RS_IN);
+
+ /* Apply BGP route map to the attribute. */
+ ret = route_map_apply(ROUTE_MAP_RS_IN(filter), rt->p, RMAP_BGP, &info_s) ;
+
+ rt->peer->rmap_type = 0;
+
+ if (ret == RMAP_DENYMATCH)
+ {
+ /* Discard any new elements set by the route-map -- these will have
+ * reference counts == 0.
+ */
+ bgp_attr_flush (rmap_attr);
+
+ rt->rs_in_deny = true ; /* NB: rs_in_attr is NULL */
+ }
+ else
+ {
+ rt->rs_in_attr = bgp_attr_intern(rmap_attr) ;
+ rt->rs_in_deny = false ;
+ } ;
+
+ /* Discard any "extra" part of the duplicated attributes. */
+ bgp_attr_extra_free (rmap_attr);
}
- return RMAP_PERMIT;
-}
-
-static int
-bgp_export_modifier (struct peer *rsclient, struct peer *peer,
- struct prefix *p, struct attr *attr, afi_t afi, safi_t safi)
+ else
+ {
+ /* Simply intern the original */
+ rt->rs_in_attr = bgp_attr_intern(rt->orig_attr) ;
+ rt->rs_in_deny = false ;
+ } ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Take the already interned client_attr, and if required apply the export
+ * route-map for the peer.
+ *
+ * If not DENY, returns interned client_attr, which may or may not have changed.
+ *
+ * If DENY, returns NULL and the client_attr will have been uninterned.
+ */
+static struct attr*
+bgp_export_modifier (struct peer *rsclient, struct rs_route* rt,
+ struct attr* client_attr)
{
struct bgp_filter *filter;
- struct bgp_info info;
- route_map_result_t ret;
- filter = &peer->filter[afi][safi];
+ /* Route map apply. */
+ filter = &rt->peer->filter[rt->afi][rt->safi];
- /* Route map apply. */
if (ROUTE_MAP_EXPORT_NAME (filter))
{
- /* Duplicate current value to new strucutre for modification. */
- info.peer = rsclient;
- info.attr = attr;
+ struct bgp_info info_s = { 0 } ;
+ struct attr rmap_attr_s ;
+ struct attr* rmap_attr ;
+ route_map_result_t ret;
+
+ rmap_attr = &rmap_attr_s ;
+ bgp_attr_dup (rmap_attr, client_attr) ;
+
+ /* Duplicate current value to new structure for modification. */
+ info_s.peer = rsclient;
+ info_s.attr = rmap_attr ;
SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_EXPORT);
- /* Apply BGP route map to the attribute. */
- ret = route_map_apply (ROUTE_MAP_EXPORT (filter), p, RMAP_BGP, &info);
+ /* Apply BGP route map to the attribute. */
+ ret = route_map_apply(ROUTE_MAP_EXPORT(filter), rt->p, RMAP_BGP, &info_s);
rsclient->rmap_type = 0;
if (ret == RMAP_DENYMATCH)
{
- /* Free newly generated AS path and community by route-map. */
- bgp_attr_flush (attr);
- return RMAP_DENY;
- }
- }
- return RMAP_PERMIT;
-}
+ /* Discard any new elements set by the route-map -- these will have
+ * reference counts == 0.
+ */
+ bgp_attr_flush (rmap_attr);
-static int
-bgp_import_modifier (struct peer *rsclient, struct peer *peer,
- struct prefix *p, struct attr *attr, afi_t afi, safi_t safi)
+ bgp_attr_unintern(&client_attr) ;
+
+ client_attr = NULL ;
+ }
+ else
+ {
+ /* Intern the result of the rmap and unintern the old version
+ *
+ * Done in this order so that any unchanged elements in rmap_attr
+ * gain a reference before they are released from the old interned
+ * attributes.
+ */
+ struct attr* old_attr ;
+
+ old_attr = client_attr ;
+ client_attr = bgp_attr_intern(rmap_attr) ;
+ bgp_attr_unintern(&old_attr) ;
+ } ;
+
+ /* Discard any "extra" part of the duplicated attributes. */
+ bgp_attr_extra_free (rmap_attr) ;
+ } ;
+
+ return client_attr ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Take the already interned client_attr, and if required apply the import
+ * route-map for the route server client.
+ *
+ * If not DENY, returns interned client_attr, which may or may not have changed.
+ *
+ * If DENY, returns NULL and the client_attr will have been uninterned.
+ */
+static struct attr*
+bgp_import_modifier (struct peer *rsclient, struct rs_route* rt,
+ struct attr* client_attr)
{
struct bgp_filter *filter;
- struct bgp_info info;
- route_map_result_t ret;
+ struct attr rmap_attr_s ;
+ struct attr* rmap_attr ;
- filter = &rsclient->filter[afi][safi];
+ rmap_attr = NULL ;
- /* Apply default weight value. */
- if (peer->weight)
- (bgp_attr_extra_get (attr))->weight = peer->weight;
+ /* Apply default weight value. */
+ if (rt->peer->weight)
+ {
+ rmap_attr = &rmap_attr_s ;
+ bgp_attr_dup (rmap_attr, client_attr) ;
+
+ (bgp_attr_extra_get (rmap_attr))->weight = rt->peer->weight;
+ } ;
+
+ /* Route map apply. */
+ filter = &rsclient->filter[rt->afi][rt->safi];
- /* Route map apply. */
if (ROUTE_MAP_IMPORT_NAME (filter))
{
- /* Duplicate current value to new strucutre for modification. */
- info.peer = peer;
- info.attr = attr;
+ struct bgp_info info_s = { 0 } ;
+ route_map_result_t ret ;
- SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IMPORT);
+ if (rmap_attr == NULL)
+ {
+ rmap_attr = &rmap_attr_s ;
+ bgp_attr_dup (rmap_attr, client_attr) ;
+ } ;
+
+ /* Duplicate current value to new structure for modification. */
+ /* TODO: should this be rt->peer or rsclient ?? */
+ info_s.peer = rt->peer;
+ info_s.attr = rmap_attr;
+
+ SET_FLAG (rt->peer->rmap_type, PEER_RMAP_TYPE_IMPORT);
/* Apply BGP route map to the attribute. */
- ret = route_map_apply (ROUTE_MAP_IMPORT (filter), p, RMAP_BGP, &info);
+ ret = route_map_apply(ROUTE_MAP_IMPORT(filter), rt->p, RMAP_BGP, &info_s);
- peer->rmap_type = 0;
+ rt->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;
+ /* Discard any new elements set by the route-map -- these will have
+ * reference counts == 0.
+ *
+ * Discard any "extra" part of the duplicated attributes.
+ */
+ bgp_attr_flush (rmap_attr);
+ bgp_attr_extra_free (rmap_attr);
+
+ bgp_attr_unintern(&client_attr) ;
+
+ return NULL ;
}
}
- return RMAP_PERMIT;
-}
-
+
+ /* If the attributes may have changed, intern the new result and unintern the
+ * old version
+ *
+ * Done in this order so that any unchanged elements in rmap_attr gain
+ * an extra reference before they are released from the old interned
+ * attributes.
+ */
+ if (rmap_attr != NULL)
+ {
+ struct attr* old_attr ;
+
+ old_attr = client_attr ;
+ client_attr = bgp_attr_intern(rmap_attr) ;
+ bgp_attr_unintern(&old_attr) ;
+
+ bgp_attr_extra_free (rmap_attr) ;
+ } ;
+
+ return client_attr ;
+} ;
+
static int
bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
struct attr *attr, afi_t afi, safi_t safi)
{
- int ret;
char buf[SU_ADDRSTRLEN];
struct bgp_filter *filter;
struct peer *from;
struct bgp *bgp;
int transparent;
int reflect;
+ bgp_peer_sort_t sort, from_sort ;
from = ri->peer;
filter = &peer->filter[afi][safi];
bgp = peer->bgp;
-
+
if (DISABLE_BGP_ANNOUNCE)
return 0;
@@ -814,7 +1151,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
transparent = 0;
/* If community is not disabled check the no-export and local. */
- if (! transparent && bgp_community_filter (peer, ri->attr))
+ if (! transparent && bgp_community_filter (peer, ri->attr))
return 0;
/* If the attribute has originator-id and it is same as remote
@@ -823,7 +1160,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
{
if (IPV4_ADDR_SAME (&peer->remote_id, &ri->attr->extra->originator_id))
{
- if (BGP_DEBUG (filter, FILTER))
+ if (BGP_DEBUG (filter, FILTER))
zlog (peer->log, LOG_DEBUG,
"%s [Update:SEND] %s/%d originator-id is same as remote router-id",
peer->host,
@@ -832,7 +1169,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
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)
@@ -859,8 +1196,8 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
/* AS path loop check. */
if (aspath_loop_check (ri->attr->aspath, peer->as))
{
- if (BGP_DEBUG (filter, FILTER))
- zlog (peer->log, LOG_DEBUG,
+ if (BGP_DEBUG (filter, FILTER))
+ zlog (peer->log, LOG_DEBUG,
"%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
peer->host, peer->as);
return 0;
@@ -872,17 +1209,20 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
{
if (aspath_loop_check(ri->attr->aspath, bgp->confed_id))
{
- if (BGP_DEBUG (filter, FILTER))
- zlog (peer->log, LOG_DEBUG,
+ if (BGP_DEBUG (filter, FILTER))
+ zlog (peer->log, LOG_DEBUG,
"%s [Update:SEND] suppress announcement to peer AS %u is AS path.",
peer->host,
bgp->confed_id);
return 0;
- }
+ }
}
/* Route-Reflect check. */
- if (peer_sort (from) == BGP_PEER_IBGP && peer_sort (peer) == BGP_PEER_IBGP)
+ from_sort = peer_sort (from) ;
+ sort = peer_sort (peer) ;
+
+ if ((from_sort == BGP_PEER_IBGP) && (sort == BGP_PEER_IBGP))
reflect = 1;
else
reflect = 0;
@@ -909,13 +1249,12 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
return 0;
}
}
-
+
/* For modify attribute, copy it to temporary structure. */
bgp_attr_dup (attr, ri->attr);
-
+
/* If local-preference is not set. */
- if ((peer_sort (peer) == BGP_PEER_IBGP
- || peer_sort (peer) == BGP_PEER_CONFED)
+ if (((sort == BGP_PEER_IBGP) || (sort == BGP_PEER_CONFED))
&& (! (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF))))
{
attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF);
@@ -923,7 +1262,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
}
/* Remove MED if its an EBGP peer - will get overwritten by route-maps */
- if (peer_sort (peer) == BGP_PEER_EBGP
+ if ((sort == BGP_PEER_EBGP)
&& attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))
{
if (ri->peer != bgp->peer_self && ! transparent
@@ -936,7 +1275,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
|| (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_UNCHANGED)
&& ((p->family == AF_INET && attr->nexthop.s_addr)
#ifdef HAVE_IPV6
- || (p->family == AF_INET6 &&
+ || (p->family == AF_INET6 &&
! IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global))
#endif /* HAVE_IPV6 */
)))
@@ -946,10 +1285,10 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
else if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_NEXTHOP_SELF)
|| (p->family == AF_INET && attr->nexthop.s_addr == 0)
#ifdef HAVE_IPV6
- || (p->family == AF_INET6 &&
+ || (p->family == AF_INET6 &&
IN6_IS_ADDR_UNSPECIFIED(&attr->extra->mp_nexthop_global))
#endif /* HAVE_IPV6 */
- || (peer_sort (peer) == BGP_PEER_EBGP
+ || ((sort == BGP_PEER_EBGP)
&& bgp_multiaccess_check_v4 (attr->nexthop, peer->host) == 0))
{
/* Set IPv4 nexthop. */
@@ -966,7 +1305,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
if (p->family == AF_INET6)
{
/* IPv6 global nexthop must be included. */
- memcpy (&attr->extra->mp_nexthop_global, &peer->nexthop.v6_global,
+ memcpy (&attr->extra->mp_nexthop_global, &peer->nexthop.v6_global,
IPV6_MAX_BYTELEN);
attr->extra->mp_nexthop_len = 16;
}
@@ -976,8 +1315,8 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
#ifdef HAVE_IPV6
if (p->family == AF_INET6)
{
- /* Left nexthop_local unchanged if so configured. */
- if ( CHECK_FLAG (peer->af_flags[afi][safi],
+ /* Left nexthop_local unchanged if so configured. */
+ if ( CHECK_FLAG (peer->af_flags[afi][safi],
PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) )
{
if ( IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_local) )
@@ -987,16 +1326,16 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
}
/* Default nexthop_local treatment for non-RS-Clients */
- else
+ else
{
/* Link-local address should not be transit to different peer. */
attr->extra->mp_nexthop_len = 16;
/* Set link-local address for shared network peer. */
- if (peer->shared_network
+ if (peer->shared_network
&& ! IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_local))
{
- memcpy (&attr->extra->mp_nexthop_local, &peer->nexthop.v6_local,
+ memcpy (&attr->extra->mp_nexthop_local, &peer->nexthop.v6_local,
IPV6_MAX_BYTELEN);
attr->extra->mp_nexthop_len = 32;
}
@@ -1015,7 +1354,7 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
#endif /* HAVE_IPV6 */
/* If this is EBGP peer and remove-private-AS is set. */
- if (peer_sort (peer) == BGP_PEER_EBGP
+ if ((sort == BGP_PEER_EBGP)
&& peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS)
&& aspath_private_as_check (attr->aspath))
attr->aspath = aspath_empty_get ();
@@ -1024,33 +1363,42 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p,
if (ROUTE_MAP_OUT_NAME (filter)
|| (ri->extra && ri->extra->suppress) )
{
- struct bgp_info info;
- struct attr dummy_attr = { 0 };
-
- info.peer = peer;
- info.attr = attr;
+ struct bgp_info info_s = { 0 } ;
+ struct attr dummy_attr_s ;
+ struct attr* dummy_attr ;
+ route_map_result_t ret;
+
+ info_s.peer = peer;
/* The route reflector is not allowed to modify the attributes
of the reflected IBGP routes. */
- if (peer_sort (from) == BGP_PEER_IBGP
- && peer_sort (peer) == BGP_PEER_IBGP)
+ if ((from_sort == BGP_PEER_IBGP) && (sort == BGP_PEER_IBGP))
{
- bgp_attr_dup (&dummy_attr, attr);
- info.attr = &dummy_attr;
+ dummy_attr = &dummy_attr_s ;
+ bgp_attr_dup (dummy_attr, attr);
+ info_s.attr = dummy_attr;
}
+ else
+ {
+ dummy_attr = NULL ;
+ info_s.attr = attr;
+ } ;
- SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT);
+ 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);
+ ret = route_map_apply (UNSUPPRESS_MAP (filter), p, RMAP_BGP, &info_s);
else
- ret = route_map_apply (ROUTE_MAP_OUT (filter), p, RMAP_BGP, &info);
+ ret = route_map_apply (ROUTE_MAP_OUT (filter), p, RMAP_BGP, &info_s);
peer->rmap_type = 0;
-
- if (dummy_attr.extra)
- bgp_attr_extra_free (&dummy_attr);
-
+
+ if (dummy_attr != NULL)
+ {
+ bgp_attr_flush (dummy_attr) ;
+ bgp_attr_extra_free (dummy_attr) ;
+ } ;
+
if (ret == RMAP_DENYMATCH)
{
bgp_attr_flush (attr);
@@ -1064,10 +1412,8 @@ static int
bgp_announce_check_rsclient (struct bgp_info *ri, struct peer *rsclient,
struct prefix *p, struct attr *attr, afi_t afi, safi_t safi)
{
- int ret;
char buf[SU_ADDRSTRLEN];
struct bgp_filter *filter;
- struct bgp_info info;
struct peer *from;
struct bgp *bgp;
@@ -1103,7 +1449,7 @@ bgp_announce_check_rsclient (struct bgp_info *ri, struct peer *rsclient,
peer's id. */
if (ri->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID))
{
- if (IPV4_ADDR_SAME (&rsclient->remote_id,
+ if (IPV4_ADDR_SAME (&rsclient->remote_id,
&ri->attr->extra->originator_id))
{
if (BGP_DEBUG (filter, FILTER))
@@ -1186,11 +1532,11 @@ bgp_announce_check_rsclient (struct bgp_info *ri, struct peer *rsclient,
if (p->family == AF_INET6)
{
struct attr_extra *attre = attr->extra;
-
+
assert (attr->extra);
-
+
/* Left nexthop_local unchanged if so configured. */
- if ( CHECK_FLAG (rsclient->af_flags[afi][safi],
+ if ( CHECK_FLAG (rsclient->af_flags[afi][safi],
PEER_FLAG_NEXTHOP_LOCAL_UNCHANGED) )
{
if ( IN6_IS_ADDR_LINKLOCAL (&attre->mp_nexthop_local) )
@@ -1198,11 +1544,11 @@ bgp_announce_check_rsclient (struct bgp_info *ri, struct peer *rsclient,
else
attre->mp_nexthop_len=16;
}
-
+
/* Default nexthop_local treatment for RS-Clients */
- else
- {
- /* Announcer and RS-Client are both in the same network */
+ else
+ {
+ /* Announcer and RS-Client are both in the same network */
if (rsclient->shared_network && from->shared_network &&
(rsclient->ifindex == from->ifindex))
{
@@ -1238,15 +1584,18 @@ bgp_announce_check_rsclient (struct bgp_info *ri, struct peer *rsclient,
/* Route map & unsuppress-map apply. */
if (ROUTE_MAP_OUT_NAME (filter) || (ri->extra && ri->extra->suppress) )
{
- info.peer = rsclient;
- info.attr = attr;
+ struct bgp_info info_s = { 0 } ;
+ route_map_result_t ret;
+
+ info_s.peer = rsclient;
+ info_s.attr = attr;
SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_OUT);
if (ri->extra && ri->extra->suppress)
- ret = route_map_apply (UNSUPPRESS_MAP (filter), p, RMAP_BGP, &info);
+ ret = route_map_apply (UNSUPPRESS_MAP (filter), p, RMAP_BGP, &info_s);
else
- ret = route_map_apply (ROUTE_MAP_OUT (filter), p, RMAP_BGP, &info);
+ ret = route_map_apply (ROUTE_MAP_OUT (filter), p, RMAP_BGP, &info_s);
rsclient->rmap_type = 0;
@@ -1275,11 +1624,11 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, struct bgp_info_pair *
struct bgp_info *ri1;
struct bgp_info *ri2;
struct bgp_info *nextri = NULL;
-
+
/* bgp deterministic-med */
new_select = NULL;
if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED))
- for (ri1 = rn->info; ri1; ri1 = ri1->next)
+ for (ri1 = rn->info; ri1; ri1 = ri1->info_next)
{
if (CHECK_FLAG (ri1->flags, BGP_INFO_DMED_CHECK))
continue;
@@ -1287,8 +1636,8 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, struct bgp_info_pair *
continue;
new_select = ri1;
- if (ri1->next)
- for (ri2 = ri1->next; ri2; ri2 = ri2->next)
+ if (ri1->info_next)
+ for (ri2 = ri1->info_next; ri2; ri2 = ri2->info_next)
{
if (CHECK_FLAG (ri2->flags, BGP_INFO_DMED_CHECK))
continue;
@@ -1315,20 +1664,20 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, struct bgp_info_pair *
/* 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)
+ for (ri = rn->info; (ri != NULL) && (nextri = ri->info_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
+ /* 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;
}
@@ -1344,7 +1693,7 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, struct bgp_info_pair *
if (bgp_info_cmp (bgp, ri, new_select))
new_select = ri;
}
-
+
result->old = old_select;
result->new = new_select;
@@ -1361,7 +1710,7 @@ bgp_process_announce_selected (struct peer *peer, struct bgp_info *selected,
p = &rn->p;
/* Announce route to Established peer. */
- if (peer->status != Established)
+ if (peer->state != bgp_peer_pEstablished)
return 0;
/* Address family configuration check. */
@@ -1384,43 +1733,68 @@ bgp_process_announce_selected (struct peer *peer, struct bgp_info *selected,
bgp_adj_out_unset (rn, peer, p, afi, safi);
break;
case BGP_TABLE_RSCLIENT:
- /* Announcement to peer->conf. If the route is filtered,
+ /* Announcement to peer->conf. If the route is filtered,
withdraw it. */
- if (selected &&
+ if (selected &&
bgp_announce_check_rsclient (selected, peer, p, &attr, afi, safi))
bgp_adj_out_set (rn, peer, p, &attr, afi, safi, selected);
else
bgp_adj_out_unset (rn, peer, p, afi, safi);
break;
}
-
+
bgp_attr_extra_free (&attr);
-
+
return 0;
}
-struct bgp_process_queue
+struct bgp_process_queue
{
- struct bgp *bgp;
- struct bgp_node *rn;
- afi_t afi;
- safi_t safi;
+ struct bgp* bgp ;
+ struct bgp_node* head ;
+ struct bgp_node* tail ;
};
+WQ_ARGS_SIZE_OK(bgp_process_queue) ;
+
static wq_item_status
-bgp_process_rsclient (struct work_queue *wq, void *data)
+bgp_process_rsclient (struct work_queue *wq, work_queue_item item)
{
- 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 bgp_process_queue *pq = work_queue_item_args(item) ;
+ struct bgp *bgp = pq->bgp ;
+ struct bgp_node *rn ;
+ afi_t afi ;
+ safi_t safi ;
struct bgp_info *new_select;
struct bgp_info *old_select;
struct bgp_info_pair old_and_new;
struct listnode *node, *nnode;
- struct peer *rsclient = rn->table->owner;
-
+ struct bgp_table *table ;
+ struct peer *rsclient ;
+
+ assert(wq->spec.data == item) ;
+
+ /* Is there anything left on the queue ? */
+ rn = pq->head ;
+ if (rn == NULL)
+ return WQ_SUCCESS ;
+
+ /* hack off queue and prepare to process */
+
+ dassert((rn->on_wq != 0) && (rn->lock > 0)) ;
+
+ pq->head = rn->wq_next ;
+ rn->wq_next = NULL ; /* Keep tidy */
+ rn->on_wq = 0 ;
+
+ table = rn->table ;
+ rsclient = table->owner;
+ afi = table->afi;
+ safi = table->safi;
+
+ dassert(table->lock > 0) ;
+ dassert(rsclient->lock > 0) ;
+
/* Best path selection. */
bgp_best_selection (bgp, rn, &old_and_new);
new_select = old_and_new.new;
@@ -1462,41 +1836,70 @@ bgp_process_rsclient (struct work_queue *wq, void *data)
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;
+
+ bgp_unlock_node (rn);
+ bgp_table_unlock (table); /* NB: *after* node, in case table is deleted */
+ bgp_unlock (bgp);
+
+ if (pq->head == NULL)
+ return WQ_SUCCESS ;
+ else
+ return WQ_REQUEUE ;
}
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;
+bgp_process_main (struct work_queue *wq, work_queue_item item)
+{
+ struct bgp_process_queue *pq = work_queue_item_args(item) ;
+ struct bgp *bgp = pq->bgp ;
+ struct bgp_node *rn ;
+ afi_t afi ;
+ safi_t safi ;
+ struct prefix *p ;
struct bgp_info *new_select;
struct bgp_info *old_select;
struct bgp_info_pair old_and_new;
struct listnode *node, *nnode;
+ struct bgp_table *table ;
struct peer *peer;
-
+
+ assert(wq->spec.data == item) ;
+
+ /* Is there anything left on the queue ? */
+ rn = pq->head ;
+ if (rn == NULL)
+ return WQ_SUCCESS ;
+
+ /* hack off queue and prepare to process */
+
+ dassert((rn->on_wq != 0) && (rn->lock > 0)) ;
+
+ pq->head = rn->wq_next ;
+ rn->wq_next = NULL ; /* Keep tidy */
+ rn->on_wq = 0 ;
+
+ table = rn->table ;
+ afi = table->afi;
+ safi = table->safi;
+
+ dassert(table->lock > 0) ;
+
+ p = &rn->p ;
+
/* Best path selection. */
bgp_best_selection (bgp, rn, &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)
+ if (old_select && (old_select == new_select))
{
if (! CHECK_FLAG (old_select->flags, BGP_INFO_ATTR_CHANGED))
{
if (CHECK_FLAG (old_select->flags, BGP_INFO_IGP_CHANGED))
bgp_zebra_announce (p, old_select, bgp);
-
- UNSET_FLAG (rn->flags, BGP_NODE_PROCESS_SCHEDULED);
- return WQ_SUCCESS;
+
+ goto finish ; /* was return ! */
}
}
@@ -1516,106 +1919,182 @@ bgp_process_main (struct work_queue *wq, void *data)
}
/* FIB update. */
- if (safi == SAFI_UNICAST && ! bgp->name &&
- ! bgp_option_check (BGP_OPT_NO_FIB))
+ if ((safi == SAFI_UNICAST) && (bgp->name == NULL) &&
+ ! bgp_option_check (BGP_OPT_NO_FIB))
{
- if (new_select
- && new_select->type == ZEBRA_ROUTE_BGP
- && new_select->sub_type == BGP_ROUTE_NORMAL)
+ if (new_select && (new_select->type == ZEBRA_ROUTE_BGP)
+ && (new_select->sub_type == BGP_ROUTE_NORMAL))
bgp_zebra_announce (p, new_select, bgp);
else
{
/* Withdraw the route from the kernel. */
- if (old_select
- && old_select->type == ZEBRA_ROUTE_BGP
- && old_select->sub_type == BGP_ROUTE_NORMAL)
+ if (old_select && (old_select->type == ZEBRA_ROUTE_BGP)
+ && (old_select->sub_type == BGP_ROUTE_NORMAL))
bgp_zebra_withdraw (p, old_select);
}
}
-
- /* Reap old select bgp_info, it it has been removed */
+
+ /* Reap old select bgp_info, it 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)
-{
- struct bgp_process_queue *pq = data;
- struct bgp_table *table = pq->rn->table;
-
- bgp_unlock (pq->bgp);
- bgp_unlock_node (pq->rn);
- bgp_table_unlock (table);
- XFREE (MTYPE_BGP_PROCESS_QUEUE, pq);
+ /* Finish up */
+
+finish:
+ bgp_unlock_node (rn) ;
+ bgp_table_unlock (table) ; /* NB: *after* node, in case table is deleted */
+ bgp_unlock (bgp) ;
+
+ if (pq->head == NULL)
+ return WQ_SUCCESS ;
+ else
+ return WQ_REQUEUE ;
}
+/*------------------------------------------------------------------------------
+ * Delete item from work queue
+ */
static void
-bgp_process_queue_init (void)
+bgp_processq_del (struct work_queue *wq, work_queue_item item)
{
- bm->process_main_queue
- = work_queue_new (bm->master, "process_main_queue");
- bm->process_rsclient_queue
- = work_queue_new (bm->master, "process_rsclient_queue");
-
- if ( !(bm->process_main_queue && bm->process_rsclient_queue) )
+ struct bgp_process_queue *pq = work_queue_item_args(item) ;
+ struct bgp_node *rn ;
+
+ assert(wq->spec.data == item) ;
+
+ while ((rn = pq->head) != NULL)
{
- 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;
-
- memcpy (bm->process_rsclient_queue, bm->process_main_queue,
- sizeof (struct work_queue *));
- bm->process_rsclient_queue->spec.workfunc = &bgp_process_rsclient;
-}
+ struct bgp_table *table ;
+
+ dassert((rn->on_wq != 0) && (rn->lock > 0)) ;
+
+ pq->head = rn->wq_next ;
+ rn->wq_next = NULL ; /* Keep tidy */
+ rn->on_wq = 0 ;
+
+ table = rn->table ;
+
+ dassert(table->lock > 0) ;
+
+ bgp_unlock_node (rn);
+ bgp_table_unlock (table); /* NB: *after* node, in case table is deleted */
+ bgp_unlock (pq->bgp);
+ } ;
+
+ wq->spec.data = NULL ;
+} ;
+/*------------------------------------------------------------------------------
+ * Create new work queue for given bgp instance and given type of table
+ */
+static work_queue
+bgp_process_queue_init (struct bgp* bgp, bgp_table_t type)
+{
+ work_queue wq ;
+ const char* name ;
+ wq_workfunc* workfunc ;
+ work_queue* p_wq ;
+
+ switch (type)
+ {
+ case BGP_TABLE_MAIN:
+ p_wq = &bgp->process_main_queue ;
+ name = "process_main_queue" ;
+ workfunc = &bgp_process_main ;
+ break ;
+ case BGP_TABLE_RSCLIENT:
+ p_wq = &bgp->process_rsclient_queue ;
+ name = "process_rsclient_queue" ;
+ workfunc = &bgp_process_rsclient ;
+ break ;
+ default:
+ zabort("invalid BGP table type") ;
+ } ;
+
+ wq = work_queue_new (bm->master, name) ;
+
+ wq->spec.data = NULL ;
+ wq->spec.errorfunc = NULL ;
+ wq->spec.workfunc = workfunc ;
+ wq->spec.del_item_data = &bgp_processq_del ;
+ wq->spec.completion_func = NULL ;
+ wq->spec.max_retries = 0 ;
+ wq->spec.hold = 50 ;
+
+ return *p_wq = wq ;
+}
+
+/*------------------------------------------------------------------------------
+ * Place given route node on appropriate work queue, so that best path
+ * selection etc. can take place later.
+ */
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;
-
- if ( (bm->process_main_queue == NULL) ||
- (bm->process_rsclient_queue == NULL) )
- bgp_process_queue_init ();
-
- pqnode = XCALLOC (MTYPE_BGP_PROCESS_QUEUE,
- sizeof (struct bgp_process_queue));
- if (!pqnode)
+ work_queue_item item ;
+ struct bgp_process_queue *pq ;
+ struct work_queue* wq ;
+
+ /* already scheduled for processing? */
+ if (rn->on_wq)
return;
- /* all unlocked in bgp_processq_del */
- bgp_table_lock (rn->table);
- pqnode->rn = bgp_lock_node (rn);
- pqnode->bgp = bgp;
- bgp_lock (bgp);
- pqnode->afi = afi;
- pqnode->safi = safi;
-
+ /* get the required work queue -- making it if necessary */
switch (rn->table->type)
{
case BGP_TABLE_MAIN:
- work_queue_add (bm->process_main_queue, pqnode);
+ wq = bgp->process_main_queue ;
+ if (wq == NULL)
+ wq = bgp_process_queue_init(bgp, BGP_TABLE_MAIN) ;
break;
case BGP_TABLE_RSCLIENT:
- work_queue_add (bm->process_rsclient_queue, pqnode);
+ wq = bgp->process_rsclient_queue ;
+ if (wq == NULL)
+ wq = bgp_process_queue_init(bgp, BGP_TABLE_RSCLIENT) ;
break;
+ default:
+ zabort("invalid rn->table->type") ;
+ }
+
+ /* get the work queue item -- making it if necessary */
+ item = wq->spec.data ;
+ if (item == NULL)
+ {
+ /* TODO: sort out assumption that item == args */
+ item = wq->spec.data = work_queue_item_add(wq) ;
+ pq = work_queue_item_args(item) ;
+
+ pq->bgp = bgp ;
+ pq->head = NULL ;
+ pq->tail = NULL ;
}
-
+ else
+ pq = work_queue_item_args(item) ;
+
+ /* all unlocked when processed or deleted */
+ bgp_lock (bgp);
+ bgp_table_lock (rn->table);
+ bgp_lock_node (rn);
+
+ /* add to the queue */
+ if (pq->head == NULL)
+ pq->head = rn ;
+ else
+ pq->tail->wq_next = rn ;
+
+ pq->tail = rn ;
+ rn->wq_next = NULL ;
+
+ rn->on_wq = 1 ;
+
return;
}
+/*============================================================================*/
+
+/*------------------------------------------------------------------------------
+ * Max Prefix Overflow timer expired -- turn off overflow status and enable.
+ */
static int
bgp_maximum_prefix_restart_timer (struct thread *thread)
{
@@ -1624,17 +2103,44 @@ bgp_maximum_prefix_restart_timer (struct thread *thread)
peer = THREAD_ARG (thread);
peer->t_pmax_restart = NULL;
+ assert(CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)) ;
+
if (BGP_DEBUG (events, EVENTS))
zlog_debug ("%s Maximum-prefix restart timer expired, restore peering",
peer->host);
- peer_clear (peer);
+ UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW);
+
+ bgp_peer_enable(peer);
return 0;
}
+/*------------------------------------------------------------------------------
+ * If there is an active max prefix restart timer, cancel it now.
+ *
+ * NB: clears PEER_STATUS_PREFIX_OVERFLOW, but does NOT enable the peer.
+ */
+void
+bgp_maximum_prefix_cancel_timer (struct peer *peer)
+{
+ if (peer->t_pmax_restart)
+ {
+ assert(CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)) ;
+
+ BGP_TIMER_OFF (peer->t_pmax_restart);
+ if (BGP_DEBUG (events, EVENTS))
+ zlog_debug ("%s Maximum-prefix restart timer cancelled", peer->host) ;
+ } ;
+
+ UNSET_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW) ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Number of prefixes has overflowed.
+ */
int
-bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
+bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
safi_t safi, int always)
{
if (!CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_MAX_PREFIX))
@@ -1650,17 +2156,18 @@ bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
"%%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;
+ return 0;
{
u_int8_t ndata[7];
if (safi == SAFI_MPLS_VPN)
safi = BGP_SAFI_VPNV4;
-
+
ndata[0] = (afi >> 8);
ndata[1] = afi;
ndata[2] = safi;
@@ -1670,22 +2177,23 @@ bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
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);
+ /* Disable the peer, the timer routine will reenable. */
+ bgp_peer_down_error_with_data(peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_MAX_PREFIX, ndata, 7);
}
/* restart timer start */
if (peer->pmax_restart[afi][safi])
- {
- peer->v_pmax_restart = peer->pmax_restart[afi][safi] * 60;
+ {
+ peer->v_pmax_restart = peer->pmax_restart[afi][safi] * 60;
- if (BGP_DEBUG (events, EVENTS))
- zlog_debug ("%s Maximum-prefix restart timer started for %d secs",
- peer->host, peer->v_pmax_restart);
+ if (BGP_DEBUG (events, EVENTS))
+ 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);
- }
+ BGP_TIMER_ON (peer->t_pmax_restart, bgp_maximum_prefix_restart_timer,
+ peer->v_pmax_restart);
+ }
return 1;
}
@@ -1709,7 +2217,10 @@ bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi,
return 0;
}
-/* Unconditionally remove the route from the RIB, without taking
+/*============================================================================*/
+
+/*------------------------------------------------------------------------------
+ * Unconditionally remove the route from the RIB, without taking
* damping into consideration (eg, because the session went down)
*/
static void
@@ -1717,10 +2228,10 @@ 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);
}
@@ -1730,104 +2241,119 @@ bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer,
{
int status = BGP_DAMP_NONE;
- /* apply dampening, if result is suppressed, we'll be retaining
+ /* 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 (peer) == BGP_PEER_EBGP)
- if ( (status = bgp_damp_withdraw (ri, rn, afi, safi, 0))
+ if ( (status = bgp_damp_withdraw (ri, rn, afi, safi, 0))
== BGP_DAMP_SUPPRESSED)
{
bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi);
return;
}
-
+
bgp_rib_remove (rn, ri, peer, afi, safi);
}
+/*------------------------------------------------------------------------------
+ * Update the given RS Client's RIB with the given route from the given peer.
+ *
+ * The peer's rs-in route-map once for all the rsclients who are to receive
+ * the route.
+ *
+ * Then export and import route-maps for the peer and the rsclient respectively.
+ */
static void
-bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
- struct attr *attr, struct peer *peer, struct prefix *p, int type,
- int sub_type, struct prefix_rd *prd, u_char *tag)
+bgp_update_rsclient (struct peer *rsclient, struct rs_route* rt)
{
- struct bgp_node *rn;
+ struct attr* client_attr ;
struct bgp *bgp;
- struct attr new_attr = { 0 };
- struct attr *attr_new;
- struct attr *attr_new2;
+ struct bgp_node *rn;
struct bgp_info *ri;
- struct bgp_info *new;
const char *reason;
char buf[SU_ADDRSTRLEN];
- /* Do not insert announces from a rsclient into its own 'bgp_table'. */
- if (peer == rsclient)
+ /* Do not insert announces from a rsclient into its own 'bgp_table'. */
+ if (rt->peer == rsclient)
return;
- bgp = peer->bgp;
- rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, prd);
+ /* Apply rs_in policy. */
+ if (!rt->rs_in_applied)
+ bgp_rs_input_modifier(rt) ;
- /* Check previously received route. */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
+ client_attr = NULL ; /* no attributes, yet */
+
+ /* Find node for this route */
+ bgp = rt->peer->bgp;
+ rn = bgp_afi_node_get (rsclient->rib[rt->afi][rt->safi], rt->afi, rt->safi,
+ rt->p, rt->prd);
+
+ /* Check previously received route. */
+ for (ri = rn->info; ri; ri = ri->info_next)
+ if (ri->peer == rt->peer && ri->type == rt->type
+ && ri->sub_type == rt->sub_type)
break;
- /* AS path loop check. */
- if (aspath_loop_check (attr->aspath, rsclient->as) > peer->allowas_in[afi][safi])
+ /* If rs-in denies the route, stop now */
+ if (rt->rs_in_deny)
+ {
+ reason = "rs-in-policy;";
+ goto filtered;
+ } ;
+
+ /* AS path loop check. */
+ if (aspath_loop_check (rt->rs_in_attr->aspath, rsclient->as) >
+ rt->peer->allowas_in[rt->afi][rt->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 (&rsclient->remote_id, &attr->extra->originator_id))
+ /* Route reflector originator ID check. */
+ if (rt->rs_in_attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID)
+ && IPV4_ADDR_SAME (&rsclient->remote_id,
+ &rt->rs_in_attr->extra->originator_id))
{
reason = "originator is us;";
goto filtered;
}
-
- bgp_attr_dup (&new_attr, attr);
- /* Apply export policy. */
- if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT) &&
- bgp_export_modifier (rsclient, peer, p, &new_attr, afi, safi) == RMAP_DENY)
+ /* Need own internalised version of the rs_in attributes */
+ client_attr = bgp_attr_intern(rt->rs_in_attr) ;
+
+ /* Apply export policy. */
+ if (CHECK_FLAG(rt->peer->af_flags[rt->afi][rt->safi],
+ PEER_FLAG_RSERVER_CLIENT))
{
- reason = "export-policy;";
- goto filtered;
- }
+ client_attr = bgp_export_modifier (rsclient, rt, client_attr) ;
+ if (client_attr == NULL)
+ {
+ reason = "export-policy;";
+ goto filtered;
+ } ;
+ } ;
- attr_new2 = bgp_attr_intern (&new_attr);
-
/* Apply import policy. */
- if (bgp_import_modifier (rsclient, peer, p, &new_attr, afi, safi) == RMAP_DENY)
+ client_attr = bgp_import_modifier (rsclient, rt, client_attr) ;
+ if (client_attr == NULL)
{
- bgp_attr_unintern (&attr_new2);
-
reason = "import-policy;";
goto filtered;
}
- attr_new = bgp_attr_intern (&new_attr);
- bgp_attr_unintern (&attr_new2);
-
/* IPv4 unicast next hop check. */
- if (afi == AFI_IP && safi == SAFI_UNICAST)
+ if (rt->afi == AFI_IP && rt->safi == SAFI_UNICAST)
{
/* Next hop must not be 0.0.0.0 nor Class E address. */
- if (new_attr.nexthop.s_addr == 0
- || ntohl (new_attr.nexthop.s_addr) >= 0xe0000000)
+ if (client_attr->nexthop.s_addr == 0
+ || ntohl (client_attr->nexthop.s_addr) >= 0xe0000000)
{
- bgp_attr_unintern (&attr_new);
-
reason = "martian next-hop;";
goto filtered;
}
}
-
- /* new_attr isn't passed to any functions after here */
- bgp_attr_extra_free (&new_attr);
-
+
/* If the update is implicit withdraw. */
if (ri)
{
@@ -1835,109 +2361,106 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
/* Same attribute comes in. */
if (!CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)
- && attrhash_cmp (ri->attr, attr_new))
+ && attrhash_cmp (ri->attr, client_attr))
{
bgp_info_unset_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG,
+ zlog (rt->peer->log, LOG_DEBUG,
"%s rcvd %s/%d for RS-client %s...duplicate ignored",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen, rsclient->host);
+ rt->peer->host,
+ inet_ntop(rt->p->family, &rt->p->u.prefix,
+ buf, SU_ADDRSTRLEN),
+ rt->p->prefixlen, rsclient->host);
- bgp_unlock_node (rn);
- bgp_attr_unintern (&attr_new);
+ /* Discard the duplicate interned attributes */
+ bgp_attr_unintern (&client_attr);
- return;
+ /* Unlock node -- locked in bgp_afi_node_get() */
+ bgp_unlock_node (rn);
+ return; /* FIN <<<<<<<<<<<<<<<<<<< */
}
/* Withdraw/Announce before we fully processed the withdraw */
if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
bgp_info_restore (rn, ri);
-
- /* Received Logging. */
- if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d for RS-client %s",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen, rsclient->host);
- /* The attribute is changed. */
+ /* The attribute is changed. */
bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
- /* Update to new attribute. */
+ /* Discard the old attribute */
bgp_attr_unintern (&ri->attr);
- ri->attr = attr_new;
-
+ }
+ else
+ {
+ /* Make new BGP info. */
+ ri = bgp_info_new ();
+ ri->type = rt->type;
+ ri->sub_type = rt->sub_type;
+ ri->peer = rt->peer;
+ ri->uptime = bgp_clock ();
+#if 0 /* TODO: do we need this ?? */
/* Update MPLS tag. */
if (safi == SAFI_MPLS_VPN)
memcpy ((bgp_info_extra_get (ri))->tag, tag, 3);
+#endif
- bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
+ /* Register new BGP information. */
+ bgp_info_add (rn, ri);
+ } ;
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
- bgp_unlock_node (rn);
+ /* Set the new attributes and update any MPLS tag.
+ *
+ * Any old attributes have been discarded.
+ *
+ * Note that we are here passing responsibility for the client_attr to the
+ * ri entry.
+ */
+ ri->attr = client_attr ;
- return;
- }
+ if (rt->safi == SAFI_MPLS_VPN)
+ memcpy ((bgp_info_extra_get (ri))->tag, rt->tag, 3);
- /* Received Logging. */
+ /* Received Logging. */
if (BGP_DEBUG (update, UPDATE_IN))
- {
- zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d for RS-client %s",
- peer->host,
- inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen, rsclient->host);
- }
+ zlog (rt->peer->log, LOG_DEBUG, "%s rcvd %s/%d for RS-client %s",
+ rt->peer->host,
+ inet_ntop(rt->p->family, &rt->p->u.prefix, buf, SU_ADDRSTRLEN),
+ rt->p->prefixlen, rsclient->host);
- /* Make new BGP info. */
- new = bgp_info_new ();
- new->type = type;
- new->sub_type = sub_type;
- new->peer = peer;
- new->attr = attr_new;
- new->uptime = bgp_clock ();
+ /* Process change. */
+ bgp_info_set_flag (rn, ri, BGP_INFO_VALID);
+ bgp_process (bgp, rn, rt->afi, rt->safi);
- /* Update MPLS tag. */
- if (safi == SAFI_MPLS_VPN)
- memcpy ((bgp_info_extra_get (new))->tag, tag, 3);
-
- bgp_info_set_flag (rn, new, BGP_INFO_VALID);
-
- /* Register new BGP information. */
- bgp_info_add (rn, new);
-
- /* route_node_get lock */
+ /* Unlock node -- locked in bgp_afi_node_get() */
bgp_unlock_node (rn);
-
- /* Process change. */
- bgp_process (bgp, rn, afi, safi);
-
- bgp_attr_extra_free (&new_attr);
-
- return;
- filtered:
+ return; /* FIN <<<<<<<<<<<<<<<<<<< */
+
+ /* Deal with route which has been filtered out.
+ *
+ * If there was a previous route, then remove it.
+ *
+ * If have an interned client attributes, then discard those.
+ */
+ filtered:
/* This BGP update is filtered. Log the reason then update BGP entry. */
if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG,
+ zlog (rt->peer->log, LOG_DEBUG,
"%s rcvd UPDATE about %s/%d -- DENIED for RS-client %s due to: %s",
- peer->host,
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen, rsclient->host, reason);
+ rt->peer->host,
+ inet_ntop (rt->p->family, &rt->p->u.prefix, buf, SU_ADDRSTRLEN),
+ rt->p->prefixlen, rsclient->host, reason);
if (ri)
- bgp_rib_remove (rn, ri, peer, afi, safi);
+ bgp_rib_remove (rn, ri, rt->peer, rt->afi, rt->safi);
+
+ if (client_attr != NULL)
+ bgp_attr_unintern (&client_attr);
bgp_unlock_node (rn);
-
- if (new_attr.extra)
- bgp_attr_extra_free (&new_attr);
-
return;
}
@@ -1956,7 +2479,7 @@ bgp_withdraw_rsclient (struct peer *rsclient, afi_t afi, safi_t safi,
rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, prd);
/* Lookup withdrawn route. */
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
break;
@@ -1978,20 +2501,23 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
afi_t afi, safi_t safi, int type, int sub_type,
struct prefix_rd *prd, u_char *tag, int soft_reconfig)
{
- int ret;
int aspath_loop_count = 0;
struct bgp_node *rn;
struct bgp *bgp;
- struct attr new_attr = { 0 };
- struct attr *attr_new;
+ struct attr* use_attr ;
struct bgp_info *ri;
struct bgp_info *new;
const char *reason;
char buf[SU_ADDRSTRLEN];
+ bgp_peer_sort_t sort ;
+
+ use_attr = NULL ; /* nothing to use, yet */
bgp = peer->bgp;
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
-
+
+ sort = peer_sort(peer) ;
+
/* When peer's soft reconfiguration enabled. Record input packet in
Adj-RIBs-In. */
if (CHECK_FLAG (peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
@@ -1999,7 +2525,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
bgp_adj_in_set (rn, peer, attr);
/* Check previously received route. */
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
break;
@@ -2009,7 +2535,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
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)
+ if (aspath_loop_check (attr->aspath, peer->change_local_as) > aspath_loop_count)
{
reason = "as-path contains our own AS;";
goto filtered;
@@ -2049,21 +2575,20 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
}
/* Apply incoming route-map. */
- bgp_attr_dup (&new_attr, attr);
-
- if (bgp_input_modifier (peer, p, &new_attr, afi, safi) == RMAP_DENY)
+ use_attr = bgp_input_modifier(peer, p, attr, afi, safi) ;
+ if (use_attr == NULL)
{
reason = "route-map;";
goto filtered;
}
/* IPv4 unicast next hop check. */
- if (afi == AFI_IP && safi == SAFI_UNICAST)
+ if ((afi == AFI_IP) && (safi == SAFI_UNICAST))
{
/* If the peer is EBGP and nexthop is not on connected route,
discard it. */
- if (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl == 1
- && ! bgp_nexthop_check_ebgp (afi, &new_attr)
+ if ((sort == BGP_PEER_EBGP) && (peer->ttl == 1)
+ && ! bgp_nexthop_check_ebgp (afi, use_attr)
&& ! CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))
{
reason = "non-connected next-hop;";
@@ -2072,33 +2597,31 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
/* Next hop must not be 0.0.0.0 nor Class E address. Next hop
must not be my own address. */
- if (bgp_nexthop_self (afi, &new_attr)
- || new_attr.nexthop.s_addr == 0
- || ntohl (new_attr.nexthop.s_addr) >= 0xe0000000)
+ if (bgp_nexthop_self (afi, use_attr)
+ || (use_attr->nexthop.s_addr == 0)
+ || (ntohl (use_attr->nexthop.s_addr) >= 0xe0000000))
{
reason = "martian next-hop;";
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))
+ if (!CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)
+ && attrhash_cmp (ri->attr, use_attr))
{
bgp_info_unset_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
- && peer_sort (peer) == BGP_PEER_EBGP
+ && (sort == BGP_PEER_EBGP)
&& CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
{
- if (BGP_DEBUG (update, UPDATE_IN))
+ if (BGP_DEBUG (update, UPDATE_IN))
zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d",
peer->host,
inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
@@ -2112,7 +2635,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
}
else /* Duplicate - odd */
{
- if (BGP_DEBUG (update, UPDATE_IN))
+ if (BGP_DEBUG (update, UPDATE_IN))
zlog (peer->log, LOG_DEBUG,
"%s rcvd %s/%d...duplicate ignored",
peer->host,
@@ -2127,10 +2650,9 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
}
}
- bgp_unlock_node (rn);
- bgp_attr_unintern (&attr_new);
- bgp_attr_extra_free (&new_attr);
-
+ bgp_attr_unintern (&use_attr);
+
+ bgp_unlock_node (rn);
return 0;
}
@@ -2138,7 +2660,8 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
{
if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d, flapped quicker than processing",
+ zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d, "
+ "flapped quicker than processing",
peer->host,
inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
p->prefixlen);
@@ -2146,7 +2669,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
}
/* Received Logging. */
- if (BGP_DEBUG (update, UPDATE_IN))
+ if (BGP_DEBUG (update, UPDATE_IN))
zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d",
peer->host,
inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
@@ -2158,25 +2681,25 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
/* 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 (peer) == BGP_PEER_EBGP)
+ && (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);
+ bgp_damp_withdraw (ri, rn, afi, safi, 1);
}
-
+
/* Update to new attribute. */
bgp_attr_unintern (&ri->attr);
- ri->attr = attr_new;
+ ri->attr = use_attr ;
/* Update MPLS tag. */
if (safi == SAFI_MPLS_VPN)
@@ -2184,24 +2707,24 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
/* Update bgp route dampening information. */
if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING)
- && peer_sort (peer) == BGP_PEER_EBGP)
+ && (sort == BGP_PEER_EBGP))
{
+ int ret ;
/* Now we do normal update dampening. */
ret = bgp_damp_update (ri, rn, afi, safi);
if (ret == BGP_DAMP_SUPPRESSED)
{
bgp_unlock_node (rn);
- bgp_attr_extra_free (&new_attr);
return 0;
}
}
/* Nexthop reachability check. */
if ((afi == AFI_IP || afi == AFI_IP6)
- && safi == SAFI_UNICAST
- && (peer_sort (peer) == BGP_PEER_IBGP
- || peer_sort (peer) == BGP_PEER_CONFED
- || (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
+ && safi == SAFI_UNICAST
+ && ( (sort == BGP_PEER_IBGP)
+ || (sort == BGP_PEER_CONFED)
+ || ((sort == BGP_PEER_EBGP) && (peer->ttl != 1))
|| CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)))
{
if (bgp_nexthop_lookup (afi, peer, ri, NULL, NULL))
@@ -2216,14 +2739,13 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
bgp_aggregate_increment (bgp, p, ri, afi, safi);
bgp_process (bgp, rn, afi, safi);
+
bgp_unlock_node (rn);
- bgp_attr_extra_free (&new_attr);
-
return 0;
}
/* Received Logging. */
- if (BGP_DEBUG (update, UPDATE_IN))
+ if (BGP_DEBUG (update, UPDATE_IN))
{
zlog (peer->log, LOG_DEBUG, "%s rcvd %s/%d",
peer->host,
@@ -2236,7 +2758,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
new->type = type;
new->sub_type = sub_type;
new->peer = peer;
- new->attr = attr_new;
+ new->attr = use_attr;
new->uptime = bgp_clock ();
/* Update MPLS tag. */
@@ -2246,9 +2768,9 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
/* Nexthop reachability check. */
if ((afi == AFI_IP || afi == AFI_IP6)
&& safi == SAFI_UNICAST
- && (peer_sort (peer) == BGP_PEER_IBGP
- || peer_sort (peer) == BGP_PEER_CONFED
- || (peer_sort (peer) == BGP_PEER_EBGP && peer->ttl != 1)
+ && ( (sort == BGP_PEER_IBGP)
+ || (sort == BGP_PEER_CONFED)
+ || ((sort == BGP_PEER_EBGP) && (peer->ttl != 1))
|| CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)))
{
if (bgp_nexthop_lookup (afi, peer, new, NULL, NULL))
@@ -2261,23 +2783,24 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
/* 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);
-
- bgp_attr_extra_free (&new_attr);
-
+
/* If maximum prefix count is configured and current prefix
- count exeed it. */
+ count exceeds it. */
if (bgp_maximum_prefix_overflow (peer, afi, safi, 0))
- return -1;
+ {
+ bgp_unlock_node (rn);
+ return -1;
+ } ;
/* Process change. */
bgp_process (bgp, rn, afi, safi);
+ /* route_node_get lock */
+ bgp_unlock_node (rn);
+
return 0;
/* This BGP update is filtered. Log the reason then update BGP
@@ -2290,13 +2813,13 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr,
inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
p->prefixlen, reason);
- if (ri)
+ if (ri != NULL)
bgp_rib_remove (rn, ri, peer, afi, safi);
+ if (use_attr != NULL)
+ bgp_attr_unintern (&use_attr);
+
bgp_unlock_node (rn);
-
- bgp_attr_extra_free (&new_attr);
-
return 0;
}
@@ -2310,25 +2833,41 @@ bgp_update (struct peer *peer, struct prefix *p, struct attr *attr,
struct bgp *bgp;
int ret;
+ /* For all neighbors, update the main RIB */
ret = bgp_update_main (peer, p, attr, afi, safi, type, sub_type, prd, tag,
soft_reconfig);
+ /* Update all Route-Server Client RIBs */
bgp = peer->bgp;
- /* Process the update for each RS-client. */
- for (ALL_LIST_ELEMENTS (bgp->rsclient, node, nnode, rsclient))
+ if (bgp->rsclient != NULL)
{
- if (CHECK_FLAG (rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
- bgp_update_rsclient (rsclient, afi, safi, attr, peer, p, type,
- sub_type, prd, tag);
- }
+ struct rs_route rt_s ;
+ /* Prepare the rs_route object, ready to update all rs clients active
+ * in this afi/safi.
+ */
+ bgp_rs_route_init(&rt_s, afi, safi, attr, peer, p, type, sub_type,
+ prd, tag) ;
+
+ /* Process the update for each RS-client. */
+ for (ALL_LIST_ELEMENTS (bgp->rsclient, node, nnode, rsclient))
+ if (CHECK_FLAG(rsclient->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
+ bgp_update_rsclient (rsclient, &rt_s) ;
+
+ /* Reset the rs_route object -- in particular discard any interned
+ * rs_in_attr which may have been created.
+ */
+ bgp_rs_route_reset(&rt_s) ;
+ } ;
+
+ /* Return result from bgp_update_main */
return ret;
}
int
-bgp_withdraw (struct peer *peer, struct prefix *p, struct attr *attr,
- afi_t afi, safi_t safi, int type, int sub_type,
+bgp_withdraw (struct peer *peer, struct prefix *p, struct attr *attr,
+ afi_t afi, safi_t safi, int type, int sub_type,
struct prefix_rd *prd, u_char *tag)
{
struct bgp *bgp;
@@ -2348,7 +2887,7 @@ bgp_withdraw (struct peer *peer, struct prefix *p, struct attr *attr,
}
/* Logging. */
- if (BGP_DEBUG (update, UPDATE_IN))
+ if (BGP_DEBUG (update, UPDATE_IN))
zlog (peer->log, LOG_DEBUG, "%s rcvd UPDATE about %s/%d -- withdrawn",
peer->host,
inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
@@ -2364,7 +2903,7 @@ bgp_withdraw (struct peer *peer, struct prefix *p, struct attr *attr,
bgp_adj_in_unset (rn, peer);
/* Lookup withdrawn route. */
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
if (ri->peer == peer && ri->type == type && ri->sub_type == sub_type)
break;
@@ -2372,7 +2911,7 @@ bgp_withdraw (struct peer *peer, struct prefix *p, struct attr *attr,
if (ri && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY))
bgp_rib_withdraw (rn, ri, peer, afi, safi);
else if (BGP_DEBUG (update, UPDATE_IN))
- zlog (peer->log, LOG_DEBUG,
+ zlog (peer->log, LOG_DEBUG,
"%s Can't find the route %s/%d", peer->host,
inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
p->prefixlen);
@@ -2382,7 +2921,7 @@ bgp_withdraw (struct peer *peer, struct prefix *p, struct attr *attr,
return 0;
}
-
+
void
bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
{
@@ -2390,16 +2929,14 @@ bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
struct attr attr = { 0 };
struct aspath *aspath = { 0 };
struct prefix p;
- struct bgp_info binfo;
struct peer *from;
- int ret = RMAP_DENYMATCH;
-
+
if (!(afi == AFI_IP || afi == AFI_IP6))
return;
-
+
bgp = peer->bgp;
from = bgp->peer_self;
-
+
bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
aspath = attr.aspath;
attr.local_pref = bgp->default_local_pref;
@@ -2412,23 +2949,23 @@ bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
{
struct attr_extra *ae;
attr.extra = NULL;
-
+
ae = bgp_attr_extra_get (&attr);
attr.extra = ae;
-
+
str2prefix ("::/0", &p);
/* IPv6 global nexthop must be included. */
- memcpy (&ae->mp_nexthop_global, &peer->nexthop.v6_global,
+ memcpy (&ae->mp_nexthop_global, &peer->nexthop.v6_global,
IPV6_MAX_BYTELEN);
ae->mp_nexthop_len = 16;
-
+
/* If the peer is on shared nextwork and we have link-local
nexthop set it. */
- if (peer->shared_network
+ if (peer->shared_network
&& !IN6_IS_ADDR_UNSPECIFIED (&peer->nexthop.v6_local))
{
- memcpy (&ae->mp_nexthop_local, &peer->nexthop.v6_local,
+ memcpy (&ae->mp_nexthop_local, &peer->nexthop.v6_local,
IPV6_MAX_BYTELEN);
ae->mp_nexthop_len = 32;
}
@@ -2437,13 +2974,16 @@ bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
if (peer->default_rmap[afi][safi].name)
{
- binfo.peer = bgp->peer_self;
- binfo.attr = &attr;
+ struct bgp_info info_s = { 0 } ;
+ route_map_result_t ret;
+
+ info_s.peer = bgp->peer_self ;
+ info_s.attr = &attr;
SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
ret = route_map_apply (peer->default_rmap[afi][safi].map, &p,
- RMAP_BGP, &binfo);
+ RMAP_BGP, &info_s);
bgp->peer_self->rmap_type = 0;
@@ -2465,11 +3005,11 @@ bgp_default_originate (struct peer *peer, afi_t afi, safi_t safi, int withdraw)
SET_FLAG (peer->af_sflags[afi][safi], PEER_STATUS_DEFAULT_ORIGINATE);
bgp_default_update_send (peer, &attr, afi, safi, from);
}
-
+
bgp_attr_extra_free (&attr);
aspath_unintern (&aspath);
}
-
+
static void
bgp_announce_table (struct peer *peer, afi_t afi, safi_t safi,
struct bgp_table *table, int rsclient)
@@ -2477,7 +3017,7 @@ bgp_announce_table (struct peer *peer, afi_t afi, safi_t safi,
struct bgp_node *rn;
struct bgp_info *ri;
struct attr attr = { 0 };
-
+
if (! table)
table = (rsclient) ? peer->rib[afi][safi] : peer->bgp->rib[afi][safi];
@@ -2486,7 +3026,7 @@ bgp_announce_table (struct peer *peer, afi_t afi, safi_t safi,
bgp_default_originate (peer, afi, safi, 0);
for (rn = bgp_table_top (table); rn; rn = bgp_route_next(rn))
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED) && ri->peer != peer)
{
if ( (rsclient) ?
@@ -2495,7 +3035,7 @@ bgp_announce_table (struct peer *peer, afi_t afi, safi_t safi,
bgp_adj_out_set (rn, peer, &rn->p, &attr, afi, safi, ri);
else
bgp_adj_out_unset (rn, peer, &rn->p, afi, safi);
-
+
bgp_attr_extra_free (&attr);
}
}
@@ -2506,7 +3046,7 @@ bgp_announce_route (struct peer *peer, afi_t afi, safi_t safi)
struct bgp_node *rn;
struct bgp_table *table;
- if (peer->status != Established)
+ if (peer->state != bgp_peer_pEstablished)
return;
if (! peer->afc_nego[afi][safi])
@@ -2533,28 +3073,46 @@ 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);
}
-
+
static void
bgp_soft_reconfig_table_rsclient (struct peer *rsclient, afi_t afi,
safi_t safi, struct bgp_table *table)
{
struct bgp_node *rn;
struct bgp_adj_in *ain;
+ struct rs_route rt_s ;
if (! table)
table = rsclient->bgp->rib[afi][safi];
+ /* Prepare the rs_route object, setting all the parts common to all routes
+ * which are about to announce to the rs client.
+ */
+ bgp_rs_route_init(&rt_s, afi, safi, NULL, NULL, NULL,
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL) ;
+
+ /* Announce everything in the table. */
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- for (ain = rn->adj_in; ain; ain = ain->next)
+ for (ain = rn->adj_in; ain; ain = ain->adj_next)
{
- bgp_update_rsclient (rsclient, afi, safi, ain->attr, ain->peer,
- &rn->p, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL);
- }
+ rt_s.orig_attr = ain->attr ;
+ rt_s.peer = ain->peer ;
+ rt_s.p = &rn->p ;
+
+ bgp_update_rsclient (rsclient, &rt_s) ;
+
+ /* Reset the rs_route object -- which discards any interned rs_in_attr
+ * which may have been created and clears the rs_in_applied flag.
+ *
+ * Leaves everything else !
+ */
+ bgp_rs_route_reset(&rt_s) ;
+ } ;
}
void
@@ -2562,7 +3120,7 @@ bgp_soft_reconfig_rsclient (struct peer *rsclient, afi_t afi, safi_t safi)
{
struct bgp_table *table;
struct bgp_node *rn;
-
+
if (safi != SAFI_MPLS_VPN)
bgp_soft_reconfig_table_rsclient (rsclient, afi, safi, NULL);
@@ -2572,7 +3130,7 @@ bgp_soft_reconfig_rsclient (struct peer *rsclient, afi_t afi, safi_t safi)
if ((table = rn->info) != NULL)
bgp_soft_reconfig_table_rsclient (rsclient, afi, safi, table);
}
-
+
static void
bgp_soft_reconfig_table (struct peer *peer, afi_t afi, safi_t safi,
struct bgp_table *table)
@@ -2585,7 +3143,7 @@ bgp_soft_reconfig_table (struct peer *peer, afi_t afi, safi_t safi,
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)
+ for (ain = rn->adj_in; ain; ain = ain->adj_next)
{
if (ain->peer == peer)
{
@@ -2608,7 +3166,7 @@ bgp_soft_reconfig_in (struct peer *peer, afi_t afi, safi_t safi)
struct bgp_node *rn;
struct bgp_table *table;
- if (peer->status != Established)
+ if (peer->state != bgp_peer_pEstablished)
return;
if (safi != SAFI_MPLS_VPN)
@@ -2619,7 +3177,332 @@ bgp_soft_reconfig_in (struct peer *peer, afi_t afi, safi_t safi)
if ((table = rn->info) != NULL)
bgp_soft_reconfig_table (peer, afi, safi, table);
}
-
+
+/*==============================================================================
+ * Clearing.
+ *
+ * There are two (quite different) forms of clearing:
+ *
+ * 1. Normal clearing -- mass withdraw of given peer's routes for all
+ * or individual AFI/SAFI.
+ *
+ * This is clears the routes *from* the given peer.
+ *
+ * Note that normal clearing deals with the main RIB and any RS Client
+ * RIBs that may also contain routes.
+ *
+ * 2. RS Client clearing -- dismantling of RS Client RIB for an AFI/SAFI.
+ *
+ * This clears out the routes *for* the given RS Client.
+ *
+ *------------------------------------------------------------------------------
+ * Normal clearing
+ *
+ * This is used in two ways:
+ *
+ * 1. when a peer falls out of Established state.
+ *
+ * See: bgp_clear_route_all().
+ *
+ * All the peer's routes in all AFI/SAFI are withdrawn, but may be subject
+ * to NSF.
+ *
+ * 2. when an individual AFI/SAFI is disabled.
+ *
+ * See: bgp_clear_route().
+ *
+ * [This appears to be for Dynamic Capabilities only.]
+ * TODO: discover whether NSF affects Dynamic Capability route clear.
+ *
+ * All the peer's routes in the AFI/SAFI are withdrawn. (NSF ??).
+ *
+ * Normal clearing affects:
+ *
+ * 1. the main RIB in all relevant AFI/SAFI.
+ *
+ * 2. all RS Client RIBs in all relevant AFI/SAFI
+ *
+ * Any routes (ie bgp_info objects) in the affected tables are either marked
+ * stale or are removed all together.
+ *
+ * Any adj_in (soft reconfig) and adj_out (announcement state) objects are
+ * removed.
+ *
+ * The peer's:
+ *
+ * struct bgp_info* routes_head[AFI_MAX][SAFI_MAX] ;
+ *
+ * This list threads through every use of all routes which belong to
+ * the peer, in all RIBs.
+ *
+ * struct bgp_adj_in* adj_in_head[AFI_MAX][SAFI_MAX] ;
+ *
+ * This list threads through every copy of all routes which belong to the
+ * peer and which have been preserved for soft reconfiguration, in all RIBs.
+ *
+ * struct bgp_adj_out* adj_out_head[AFI_MAX][SAFI_MAX] ;
+ *
+ * This list threads through every route which has been selected for the
+ * peer, in all RIBs.
+ *
+ * Are maintained for exactly this purpose.
+ *
+ * NB: this is now a linear process, because the lists identify the stuff to
+ * be processed.
+ *
+ * Not much work is required to remove a route -- the consequences are
+ * dealt with by the relevant processing work queue.
+ *
+ * In theory it would be better to break up the work. A peer who announces
+ * 500,000 prefixes has a fair amount to do here. A peer who announces
+ * 10,000 prefixes to 1,000 RS Clients has 10,000,000 routes to withdraw.
+ *
+ * Nevertheless, a really hard case looks like less than 10secs work...
+ * For the time being, the simplicity of living without a clearing work
+ * queue task is preferred -- and the
+ *
+ * [The old code walked the main RIB, and then every RS Client RIB, searching
+ * for bgp_node objects which had bgp_info from the given peer. It then issued
+ * a work queue task to do the actual change (which was probably more work than
+ * doing the change straight away).]
+ *
+ * [The MPLS VPN stuff has a two level RIB, which the above probably doesn't
+ * work for... more work required, here.]
+ *
+ * TODO: fix bgp_clear_route() and MPLS VPN !!
+ *
+ *------------------------------------------------------------------------------
+ * RS Client Clearing
+ *
+ * This is done when a given RS Client RIB is about to be dismantled.
+ *
+ * This walks the RS Client RIB and discards all bgp_info, adj_in and adj_out.
+ * (This is unconditional -- no NSF gets in the way.)
+ *
+ */
+
+/*------------------------------------------------------------------------------
+ * Normal clearing of a a given peer's routes.
+ *
+ * The following lists are processed:
+ *
+ * * struct bgp_info* routes_head
+ *
+ * Walks this and clears each route.
+ *
+ * * struct bgp_adj_in* adj_in_head
+ * * struct bgp_adj_out* adj_out_head
+ *
+ * These two are simply emptied out.
+ *
+ * NB: in the latest scheme of things this is completed immediately...
+ *
+ * ...however, retain the ability for this to kick off background or other
+ * activity.
+ *
+ * Returns: true <=> clearing has completed
+ *
+ */
+extern bool
+bgp_clear_routes(struct peer *peer, afi_t afi, safi_t safi, bool nsf)
+{
+ struct bgp_info* ri ;
+ struct bgp_info* next_ri ;
+ struct bgp_adj_in* adj_in ;
+ struct bgp_adj_out* adj_out ;
+ struct bgp_adj_in** adj_in_head ;
+ struct bgp_adj_out** adj_out_head ;
+
+ next_ri = peer->routes_head[afi][safi] ;
+
+ /* If NSF requested and nsf configured for this afi/safi, do nsf and
+ * set flag to indicate that at least one afi/safi may have stale routes.
+ */
+ nsf = nsf && peer->nsf[afi][safi] ;
+ if (nsf)
+ SET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT) ;
+
+ /* TODO: fix bgp_clear_route_normal() so can clear an MPLS VPN table.... */
+ if (next_ri != NULL)
+ assert(safi != SAFI_MPLS_VPN) ;
+
+ while (next_ri != NULL)
+ {
+ /* The current bgp_info object may vanish, so bank the next */
+ ri = next_ri ;
+ next_ri = ri->routes_next ;
+
+ assert (peer == ri->peer) ;
+
+ if (nsf && ! CHECK_FLAG (ri->flags, BGP_INFO_STALE)
+ && ! CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE))
+ bgp_info_set_flag (ri->rn, ri, BGP_INFO_STALE);
+ else
+ bgp_rib_remove (ri->rn, ri, peer, afi, safi);
+ } ;
+
+ /* Empty out all adjacencies */
+ adj_in_head = &(peer->adj_in_head[afi][safi]) ;
+ while ((adj_in = *adj_in_head) != NULL)
+ {
+ assert(adj_in->route_prev == NULL) ;
+ bgp_adj_in_remove (adj_in->rn, adj_in) ;
+ assert(adj_in != *adj_in_head) ;
+ } ;
+
+ adj_out_head = &(peer->adj_out_head[afi][safi]) ;
+ while ((adj_out = *adj_out_head) != NULL)
+ {
+ assert(adj_out->route_prev == NULL) ;
+ bgp_adj_out_remove (adj_out->rn, adj_out, peer, afi, safi) ;
+ assert(adj_out != *adj_out_head) ;
+ } ;
+
+ return true ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Normal clearing of given peer for all AFI/SAFI -- respecting NSF if required.
+ *
+ * NB: in the latest scheme of things this is completed immediately...
+ *
+ * ...however, retain the ability to run this in the background with the
+ * peer in bgp_peer_pClearing.
+ *
+ * Returns: true <=> all clearing completed
+ * so false => something running in the background.
+ */
+extern bool
+bgp_clear_all_routes (struct peer *peer, bool nsf)
+{
+ bool completed ;
+ afi_t afi;
+ safi_t safi;
+
+ assert(peer->state == bgp_peer_pClearing) ;
+
+ UNSET_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT) ;
+
+ completed = true ;
+ for (afi = AFI_IP; afi < AFI_MAX; afi++)
+ for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++)
+ if (!bgp_clear_routes(peer, afi, safi, nsf))
+ completed = false ;
+
+ return completed ;
+} ;
+
+/*------------------------------------------------------------------------------
+ * Clear Route Server RIB for given AFI/SAFI -- unconditionally
+ *
+ * This is used to dismantle a Route Server Client's RIB -- this is removing
+ * all the routes from all *other* Route Server Clients that have been placed
+ * in this Clients RIB.
+ *
+ * Walks all the nodes in the table and discards all routes, all adj_in and
+ * all adj_out.
+ *
+ * Does nothing if there is no RIB for that AFI/SAFI.
+ */
+extern void
+bgp_clear_rsclient_rib(struct peer* rsclient, afi_t afi, safi_t safi)
+{
+ struct bgp_node *rn ;
+ struct bgp_table* table ;
+
+ table = rsclient->rib[afi][safi] ;
+
+ if (table == NULL)
+ return ; /* Ignore unconfigured afi/safi or similar */
+
+ /* TODO: fix bgp_clear_rsclient_rib() so that will clear an MPLS VPN table. */
+ passert(table->safi != SAFI_MPLS_VPN) ;
+
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+ {
+ struct bgp_info *ri;
+ struct bgp_info *next_ri ;
+ struct bgp_adj_in *ain;
+ struct bgp_adj_out *aout;
+
+ next_ri = rn->info ;
+ while(next_ri != NULL)
+ {
+ ri = next_ri ;
+ next_ri = ri->info_next ; /* bank this */
+
+ bgp_rib_remove (rn, ri, rsclient, table->afi, table->safi);
+ } ;
+
+ while ((ain = rn->adj_in) != NULL)
+ {
+ assert(ain->adj_prev == NULL) ;
+ bgp_adj_in_remove (rn, ain);
+ assert(ain != rn->adj_in) ;
+ } ;
+
+ while ((aout = rn->adj_out) != NULL)
+ {
+ assert(aout->adj_prev == NULL) ;
+ bgp_adj_out_remove (rn, aout, aout->peer, table->afi, table->safi) ;
+ assert(aout != rn->adj_out) ;
+ } ;
+ }
+ return ;
+}
+
+/*------------------------------------------------------------------------------
+ * Walk main RIB and remove any adj_in for given peer.
+ *
+ * TODO: walk peer->bgp_adj_in_head[afi][safi] -- but check which table ?
+ */
+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;
+
+ 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->adj_next)
+ if (ain->peer == peer)
+ {
+ bgp_adj_in_remove (rn, ain);
+ break;
+ }
+} ;
+
+/*------------------------------------------------------------------------------
+ * Walk main RIB and remove all stale routes for the given peer.
+ *
+ * NB: is required to complete immediately !
+ *
+ * TODO: walk peer->routes_head[afi][safi]
+ */
+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;
+
+ table = peer->bgp->rib[afi][safi];
+
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+ {
+ for (ri = rn->info; ri; ri = ri->info_next)
+ if (ri->peer == peer)
+ {
+ if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
+ bgp_rib_remove (rn, ri, peer, afi, safi);
+ break;
+ }
+ }
+}
+
+#if 0
struct bgp_clear_node_queue
{
@@ -2627,19 +3510,21 @@ struct bgp_clear_node_queue
enum bgp_clear_route_type purpose;
};
+WQ_ARGS_SIZE_OK(bgp_clear_node_queue) ;
+
static wq_item_status
-bgp_clear_route_node (struct work_queue *wq, void *data)
+bgp_clear_route_node (struct work_queue *wq, work_queue_item item)
{
- struct bgp_clear_node_queue *cnq = data;
+ struct bgp_clear_node_queue *cnq = work_queue_item_args(item) ;
struct bgp_node *rn = cnq->rn;
struct peer *peer = wq->spec.data;
struct bgp_info *ri;
afi_t afi = rn->table->afi;
safi_t safi = rn->table->safi;
-
+
assert (rn && peer);
-
- for (ri = rn->info; ri; ri = ri->next)
+
+ for (ri = rn->info; ri; ri = ri->info_next)
if (ri->peer == peer || cnq->purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
{
/* graceful restart STALE flag set. */
@@ -2656,33 +3541,39 @@ bgp_clear_route_node (struct work_queue *wq, void *data)
}
static void
-bgp_clear_node_queue_del (struct work_queue *wq, void *data)
+bgp_clear_node_queue_del (struct work_queue *wq, work_queue_item item)
{
- struct bgp_clear_node_queue *cnq = data;
+ struct bgp_clear_node_queue *cnq = work_queue_item_args(item) ;
struct bgp_node *rn = cnq->rn;
struct bgp_table *table = rn->table;
-
- bgp_unlock_node (rn);
+
+ bgp_unlock_node (rn);
bgp_table_unlock (table);
- XFREE (MTYPE_BGP_CLEAR_NODE_QUEUE, cnq);
}
static void
bgp_clear_node_complete (struct work_queue *wq)
{
struct peer *peer = wq->spec.data;
-
- /* Tickle FSM to start moving again */
- BGP_EVENT_ADD (peer, Clearing_Completed);
- peer_unlock (peer); /* bgp_clear_route */
+ /* Flush the event queue and ensure the peer is shut down */
+ bgp_peer_stop(peer);
+ BGP_EVENT_FLUSH (peer);
+ if (peer->state == bgp_peer_pClearing)
+ {
+ peer_change_status (peer, bgp_peer_pIdle);
+ /* enable peer if required */
+ bgp_peer_enable(peer);
+ }
+
+ bgp_peer_unlock (peer); /* bgp_clear_route */
}
static void
bgp_clear_node_queue_init (struct peer *peer)
{
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
@@ -2696,112 +3587,22 @@ bgp_clear_node_queue_init (struct peer *peer)
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;
}
-static void
-bgp_clear_route_table (struct peer *peer, afi_t afi, safi_t safi,
- struct bgp_table *table, struct peer *rsclient,
- enum bgp_clear_route_type purpose)
-{
- struct bgp_node *rn;
-
-
- if (! table)
- table = (rsclient) ? rsclient->rib[afi][safi] : 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;
- struct bgp_adj_in *ain;
- struct bgp_adj_out *aout;
-
- if (rn->info == NULL)
- continue;
-
- /* 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,
- */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == peer || purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
- {
- struct bgp_clear_node_queue *cnq;
-
- /* both unlocked in bgp_clear_node_queue_del */
- bgp_table_lock (rn->table);
- bgp_lock_node (rn);
- cnq = XCALLOC (MTYPE_BGP_CLEAR_NODE_QUEUE,
- sizeof (struct bgp_clear_node_queue));
- cnq->rn = rn;
- cnq->purpose = purpose;
- work_queue_add (peer->clear_node_queue, cnq);
- break;
- }
-
- for (ain = rn->adj_in; ain; ain = ain->next)
- if (ain->peer == peer || purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
- {
- bgp_adj_in_remove (rn, ain);
- bgp_unlock_node (rn);
- break;
- }
- for (aout = rn->adj_out; aout; aout = aout->next)
- if (aout->peer == peer || purpose == BGP_CLEAR_ROUTE_MY_RSCLIENT)
- {
- bgp_adj_out_remove (rn, aout, peer, afi, safi);
- bgp_unlock_node (rn);
- break;
- }
- }
- return;
-}
-
void
-bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi,
- enum bgp_clear_route_type purpose)
+bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi)
{
- struct bgp_node *rn;
- struct bgp_table *table;
- struct peer *rsclient;
- struct listnode *node, *nnode;
+//struct bgp_node *rn;
+//struct bgp_table *table;
+//struct peer *rsclient;
+//struct listnode *node, *nnode;
+
+//if (peer->clear_node_queue == NULL)
+// bgp_clear_node_queue_init (peer);
- 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
@@ -2814,37 +3615,45 @@ bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi,
* on the process_main queue. Fast-flapping could cause that queue
* to grow and grow.
*/
- if (!peer->clear_node_queue->thread)
- peer_lock (peer); /* bgp_clear_node_complete */
+//if (!peer->clear_node_queue->thread)
+ bgp_peer_lock (peer); /* bgp_clear_node_complete */
switch (purpose)
{
case BGP_CLEAR_ROUTE_NORMAL:
+ if (peer->routes_head[afi][safi] == NULL)
+ break ;
+
if (safi != SAFI_MPLS_VPN)
- bgp_clear_route_table (peer, afi, safi, NULL, NULL, purpose);
+ bgp_clear_route_normal(peer, afi, safi) ;
else
+/* TODO: how to deal with SAFI_MPLS_VPN in bgp_clear_route ?? */
+ passert(0) ;
+#if 0
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, NULL, purpose);
-
+#endif
+#if 0
for (ALL_LIST_ELEMENTS (peer->bgp->rsclient, node, nnode, rsclient))
if (CHECK_FLAG(rsclient->af_flags[afi][safi],
PEER_FLAG_RSERVER_CLIENT))
bgp_clear_route_table (peer, afi, safi, NULL, rsclient, purpose);
+#endif
break;
case BGP_CLEAR_ROUTE_MY_RSCLIENT:
- bgp_clear_route_table (peer, afi, safi, NULL, peer, purpose);
+ bgp_clear_route_table (peer, peer->rib[afi][safi]) ;
break;
default:
assert (0);
break;
}
-
+
/* If no routes were cleared, nothing was added to workqueue, the
- * completion function won't be run by workqueue code - call it here.
+ * completion function won't be run by workqueue code - call it here.
* XXX: Actually, this assumption doesn't hold, see
* bgp_clear_route_table(), we queue all non-empty nodes.
*
@@ -2862,62 +3671,17 @@ bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi,
* pre-Established, avoiding above list and table scans. Once we're
* sure it is safe..
*/
- if (!peer->clear_node_queue->thread)
- bgp_clear_node_complete (peer->clear_node_queue);
-}
-
-void
-bgp_clear_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_clear_route (peer, afi, safi, BGP_CLEAR_ROUTE_NORMAL);
-}
+ /* The following was in bgp_clear_node_complete */
-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;
-
- 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)
- {
- bgp_adj_in_remove (rn, ain);
- bgp_unlock_node (rn);
- break;
- }
+ bgp_peer_unlock (peer); /* bgp_clear_route */
}
+#endif
-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;
-
- table = peer->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 == peer)
- {
- if (CHECK_FLAG (ri->flags, BGP_INFO_STALE))
- bgp_rib_remove (rn, ri, peer, afi, safi);
- break;
- }
- }
-}
-
-/* Delete all kernel routes. */
+#if 0
+/* Delete all kernel routes. */
void
bgp_cleanup_routes (void)
{
@@ -2932,32 +3696,32 @@ bgp_cleanup_routes (void)
table = bgp->rib[AFI_IP][SAFI_UNICAST];
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
- && ri->type == ZEBRA_ROUTE_BGP
+ && ri->type == ZEBRA_ROUTE_BGP
&& ri->sub_type == BGP_ROUTE_NORMAL)
bgp_zebra_withdraw (&rn->p, ri);
table = bgp->rib[AFI_IP6][SAFI_UNICAST];
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED)
- && ri->type == ZEBRA_ROUTE_BGP
+ && ri->type == ZEBRA_ROUTE_BGP
&& ri->sub_type == BGP_ROUTE_NORMAL)
bgp_zebra_withdraw (&rn->p, ri);
}
}
+#endif
void
bgp_reset (void)
{
- vty_reset ();
bgp_zclient_reset ();
access_list_reset ();
prefix_list_reset ();
}
-
+
/* Parse NLRI stream. Withdraw NLRI is recognized by NULL attr
value. */
int
@@ -2970,9 +3734,9 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
int ret;
/* Check peer status. */
- if (peer->status != Established)
+ if (peer->state != bgp_peer_pEstablished)
return 0;
-
+
pnt = packet->nlri;
lim = pnt + packet->length;
@@ -2984,7 +3748,7 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
/* Fetch prefix length. */
p.prefixlen = *pnt++;
p.family = afi2family (packet->afi);
-
+
/* Already checked in nlri_sanity_check(). We do double check
here. */
if ((packet->afi == AFI_IP && p.prefixlen > 32)
@@ -3006,16 +3770,16 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
{
if (IN_CLASSD (ntohl (p.u.prefix4.s_addr)))
{
- /*
- * From draft-ietf-idr-bgp4-22, Section 6.3:
+ /*
+ * From draft-ietf-idr-bgp4-22, Section 6.3:
* If a BGP router receives an UPDATE message with a
* semantically incorrect NLRI field, in which a prefix is
* semantically incorrect (eg. an unexpected multicast IP
* address), it should ignore the prefix.
*/
- zlog (peer->log, LOG_ERR,
+ zlog (peer->log, LOG_ERR,
"IPv4 unicast NLRI is multicast address %s",
- inet_ntoa (p.u.prefix4));
+ safe_inet_ntoa (p.u.prefix4));
return -1;
}
@@ -3029,7 +3793,7 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
{
char buf[BUFSIZ];
- zlog (peer->log, LOG_WARNING,
+ zlog (peer->log, LOG_WARNING,
"IPv6 link-local NLRI received %s ignore this NLRI",
inet_ntop (AF_INET6, &p.u.prefix6, buf, BUFSIZ));
@@ -3040,10 +3804,10 @@ bgp_nlri_parse (struct peer *peer, struct attr *attr, struct bgp_nlri *packet)
/* Normal process. */
if (attr)
- ret = bgp_update (peer, &p, attr, packet->afi, packet->safi,
+ ret = bgp_update (peer, &p, attr, packet->afi, packet->safi,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL, 0);
else
- ret = bgp_withdraw (peer, &p, attr, packet->afi, packet->safi,
+ ret = bgp_withdraw (peer, &p, attr, packet->afi, packet->safi,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL);
/* Address family configuration mismatch or maximum-prefix count
@@ -3077,16 +3841,16 @@ bgp_nlri_sanity_check (struct peer *peer, int afi, u_char *pnt,
while (pnt < end)
{
prefixlen = *pnt++;
-
+
/* Prefix length check. */
if ((afi == AFI_IP && prefixlen > 32)
|| (afi == AFI_IP6 && prefixlen > 128))
{
- plog_err (peer->log,
+ plog_err (peer->log,
"%s [Error] Update packet error (wrong prefix length %d)",
peer->host, prefixlen);
- bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_INVAL_NETWORK);
+ bgp_peer_down_error(peer, BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_INVAL_NETWORK);
return -1;
}
@@ -3095,12 +3859,12 @@ bgp_nlri_sanity_check (struct peer *peer, int afi, u_char *pnt,
if (pnt + psize > end)
{
- plog_err (peer->log,
+ plog_err (peer->log,
"%s [Error] Update packet error"
" (prefix data overflow prefix size is %d)",
peer->host, psize);
- bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_INVAL_NETWORK);
+ bgp_peer_down_error(peer, BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_INVAL_NETWORK);
return -1;
}
@@ -3114,13 +3878,13 @@ bgp_nlri_sanity_check (struct peer *peer, int afi, u_char *pnt,
"%s [Error] Update packet error"
" (prefix length mismatch with total length)",
peer->host);
- bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_INVAL_NETWORK);
+ bgp_peer_down_error(peer, BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_INVAL_NETWORK);
return -1;
}
return 0;
}
-
+
static struct bgp_static *
bgp_static_new (void)
{
@@ -3145,7 +3909,7 @@ bgp_static_withdraw_rsclient (struct bgp *bgp, struct peer *rsclient,
rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, NULL);
/* Check selected route and self inserted route. */
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
if (ri->peer == bgp->peer_self
&& ri->type == ZEBRA_ROUTE_BGP
&& ri->sub_type == BGP_ROUTE_STATIC)
@@ -3169,13 +3933,11 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
{
struct bgp_node *rn;
struct bgp_info *ri;
- struct bgp_info *new;
- struct bgp_info info;
- struct attr *attr_new;
- struct attr attr = {0 };
- struct attr new_attr = { .extra = 0 };
+ struct attr static_attr_s ;
+ struct attr* static_attr ;
+ struct attr* client_attr ;
+ struct rs_route rt_s ;
struct bgp *bgp;
- int ret;
char buf[SU_ADDRSTRLEN];
bgp = rsclient->bgp;
@@ -3186,135 +3948,152 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p,
rn = bgp_afi_node_get (rsclient->rib[afi][safi], afi, safi, p, NULL);
- bgp_attr_default_set (&attr, BGP_ORIGIN_IGP);
+ /* Construct the static route attributes.
+ *
+ * Starts with an empty aspath, which is interned. No other elements are
+ * interned and the object itself is not interned.
+ */
+ static_attr = &static_attr_s ;
+ bgp_attr_default_set (static_attr, BGP_ORIGIN_IGP);
+
+ static_attr->nexthop = bgp_static->igpnexthop;
+ static_attr->med = bgp_static->igpmetric;
+ static_attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
- attr.nexthop = bgp_static->igpnexthop;
- attr.med = bgp_static->igpmetric;
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC);
-
if (bgp_static->atomic)
- attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
-
- /* Apply network route-map for export to this rsclient. */
+ static_attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE);
+
+ /* Apply network route-map for export to this rsclient.
+ *
+ * Create interned attributes client_attr, either from route-map result, or
+ * from the static_attr.
+ */
if (bgp_static->rmap.name)
{
- struct attr attr_tmp = attr;
- info.peer = rsclient;
- info.attr = &attr_tmp;
-
+ struct bgp_info info_s = { 0 } ;
+ struct attr rmap_attr_s ;
+ struct attr* rmap_attr ;
+ route_map_result_t ret;
+
+ rmap_attr = &rmap_attr_s ;
+ bgp_attr_dup(rmap_attr, static_attr) ;
+
+ info_s.peer = rsclient ;
+ info_s.attr = rmap_attr ;
+
SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_EXPORT);
SET_FLAG (rsclient->rmap_type, PEER_RMAP_TYPE_NETWORK);
- ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
+ ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info_s);
rsclient->rmap_type = 0;
if (ret == RMAP_DENYMATCH)
{
- /* Free uninterned attribute. */
- bgp_attr_flush (&attr_tmp);
+ /* Free uninterned attribute. */
+ bgp_attr_flush (rmap_attr) ;
+ bgp_attr_extra_free (rmap_attr);
+
+ /* Unintern original. */
+ aspath_unintern (&static_attr->aspath);
+ bgp_attr_extra_free (static_attr);
- /* Unintern original. */
- aspath_unintern (&attr.aspath);
bgp_static_withdraw_rsclient (bgp, rsclient, p, afi, safi);
- bgp_attr_extra_free (&attr);
-
+
return;
- }
- attr_new = bgp_attr_intern (&attr_tmp);
+ } ;
+
+ client_attr = bgp_attr_intern(rmap_attr) ;
+ bgp_attr_extra_free (rmap_attr) ;
}
else
- attr_new = bgp_attr_intern (&attr);
-
- bgp_attr_dup(&new_attr, attr_new);
-
+ client_attr = bgp_attr_intern (static_attr) ;
+
+ /* Have now finished with the static_attr */
+ aspath_unintern (&static_attr->aspath);
+ bgp_attr_extra_free (static_attr);
+
+ /* run the import route-map for the rsclient. */
+ bgp_rs_route_init(&rt_s, afi, safi, NULL, bgp->peer_self, p,
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, NULL) ;
+
SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
- if (bgp_import_modifier (rsclient, bgp->peer_self, p, &new_attr, afi, safi)
- == RMAP_DENY)
+ client_attr = bgp_import_modifier (rsclient, &rt_s, client_attr) ;
+
+ bgp->peer_self->rmap_type = 0;
+
+ if (client_attr == NULL)
{
/* This BGP update is filtered. Log the reason then update BGP entry. */
if (BGP_DEBUG (update, UPDATE_IN))
- zlog (rsclient->log, LOG_DEBUG,
- "Static UPDATE about %s/%d -- DENIED for RS-client %s due to: import-policy",
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- p->prefixlen, rsclient->host);
+ zlog (rsclient->log, LOG_DEBUG,
+ "Static UPDATE about %s/%d -- DENIED for RS-client %s due to: "
+ "import-policy",
+ inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ p->prefixlen, rsclient->host);
bgp->peer_self->rmap_type = 0;
- bgp_attr_unintern (&attr_new);
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
-
bgp_static_withdraw_rsclient (bgp, rsclient, p, afi, safi);
-
+
return;
}
- bgp->peer_self->rmap_type = 0;
-
- bgp_attr_unintern (&attr_new);
- attr_new = bgp_attr_intern (&new_attr);
- bgp_attr_extra_free (&new_attr);
+ /* Apply the client_attr */
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_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))
+ if (attrhash_cmp (ri->attr, client_attr) &&
+ !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;
- }
+ /* No point duplicating */
+ bgp_attr_unintern (&client_attr);
+ }
else
{
- /* The attribute is changed. */
+ /* The attribute is changed. */
bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED);
- /* Rewrite BGP route information. */
+ /* Rewrite BGP route information. */
if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED))
bgp_info_restore(rn, ri);
+
bgp_attr_unintern (&ri->attr);
- ri->attr = attr_new;
+ ri->attr = client_attr ;
ri->uptime = bgp_clock ();
- /* Process change. */
+ /* Process change. */
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 = bgp_info_new ();
- new->type = ZEBRA_ROUTE_BGP;
- new->sub_type = BGP_ROUTE_STATIC;
- new->peer = bgp->peer_self;
- SET_FLAG (new->flags, BGP_INFO_VALID);
- new->attr = attr_new;
- new->uptime = bgp_clock ();
- /* Register new BGP information. */
- bgp_info_add (rn, new);
-
- /* route_node_get lock */
- bgp_unlock_node (rn);
-
- /* Process change. */
+ bgp_unlock_node (rn);
+ return ;
+ } ;
+
+ /* Make new BGP info. */
+ ri = bgp_info_new ();
+ ri->type = rt_s.type ;
+ ri->sub_type = rt_s.sub_type ;
+ ri->peer = rt_s.peer ;
+ ri->attr = client_attr ;
+ ri->uptime = bgp_clock ();
+
+ SET_FLAG (ri->flags, BGP_INFO_VALID);
+
+ /* Register new BGP information. */
+ bgp_info_add (rn, ri);
+
+ /* Process change. */
bgp_process (bgp, rn, afi, safi);
- /* Unintern original. */
- aspath_unintern (&attr.aspath);
- bgp_attr_extra_free (&attr);
+ /* route_node_get lock */
+ bgp_unlock_node (rn);
}
static void
@@ -3324,10 +4103,8 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
struct bgp_node *rn;
struct bgp_info *ri;
struct bgp_info *new;
- struct bgp_info info;
struct attr attr = { 0 };
struct attr *attr_new;
- int ret;
assert (bgp_static);
if (!bgp_static)
@@ -3336,7 +4113,7 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
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);
@@ -3348,17 +4125,20 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
if (bgp_static->rmap.name)
{
struct attr attr_tmp = attr;
- info.peer = bgp->peer_self;
- info.attr = &attr_tmp;
+ struct bgp_info info_s = { 0 } ;
+ route_map_result_t ret;
+
+ info_s.peer = bgp->peer_self;
+ info_s.attr = &attr_tmp;
SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
- ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info);
+ ret = route_map_apply (bgp_static->rmap.map, p, RMAP_BGP, &info_s);
bgp->peer_self->rmap_type = 0;
if (ret == RMAP_DENYMATCH)
- {
+ {
/* Free uninterned attribute. */
bgp_attr_flush (&attr_tmp);
@@ -3373,7 +4153,7 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
else
attr_new = bgp_attr_intern (&attr);
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP
&& ri->sub_type == BGP_ROUTE_STATIC)
break;
@@ -3424,13 +4204,13 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p,
/* 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);
@@ -3461,7 +4241,7 @@ bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
{
struct bgp_node *rn;
struct bgp_info *new;
-
+
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, prd);
/* Make new BGP info. */
@@ -3477,13 +4257,13 @@ bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
/* 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);
}
@@ -3498,8 +4278,8 @@ bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi,
rn = bgp_afi_node_get (bgp->rib[afi][safi], afi, safi, p, NULL);
/* Check selected route and self inserted route. */
- for (ri = rn->info; ri; ri = ri->next)
- if (ri->peer == bgp->peer_self
+ for (ri = rn->info; ri; ri = ri->info_next)
+ if (ri->peer == bgp->peer_self
&& ri->type == ZEBRA_ROUTE_BGP
&& ri->sub_type == BGP_ROUTE_STATIC)
break;
@@ -3546,8 +4326,8 @@ bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
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
+ for (ri = rn->info; ri; ri = ri->info_next)
+ if (ri->peer == bgp->peer_self
&& ri->type == ZEBRA_ROUTE_BGP
&& ri->sub_type == BGP_ROUTE_STATIC)
break;
@@ -3567,7 +4347,7 @@ bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi,
/* 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, struct bgp *bgp, const char *ip_str,
+bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str,
afi_t afi, safi_t safi, const char *rmap, int backdoor)
{
int ret;
@@ -3603,11 +4383,11 @@ bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str,
bgp_static = rn->info;
/* Check previous routes are installed into BGP. */
- if (bgp_static->valid && bgp_static->backdoor != backdoor)
+ if (bgp_static->valid && (bgp_static->backdoor != backdoor))
need_update = 1;
-
+
bgp_static->backdoor = backdoor;
-
+
if (rmap)
{
if (bgp_static->rmap.name)
@@ -3633,7 +4413,7 @@ bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str,
bgp_static->valid = 0;
bgp_static->igpmetric = 0;
bgp_static->igpnexthop.s_addr = 0;
-
+
if (rmap)
{
if (bgp_static->rmap.name)
@@ -3696,7 +4476,7 @@ bgp_static_unset (struct vty *vty, struct bgp *bgp, const char *ip_str,
}
bgp_static = rn->info;
-
+
/* Update BGP RIB. */
if (! bgp_static->backdoor)
bgp_static_withdraw (bgp, &p, afi, safi);
@@ -3726,7 +4506,7 @@ bgp_static_delete (struct bgp *bgp)
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)
{
table = rn->info;
@@ -3823,7 +4603,7 @@ bgp_static_set_vpnv4 (struct vty *vty, const char *ip_str, const char *rd_str,
/* Configure static BGP network. */
int
-bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str,
+bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str,
const char *rd_str, const char *tag_str)
{
int ret;
@@ -3886,7 +4666,7 @@ bgp_static_unset_vpnv4 (struct vty *vty, const char *ip_str,
return CMD_SUCCESS;
}
-
+
DEFUN (bgp_network,
bgp_network_cmd,
"network A.B.C.D/M",
@@ -3930,7 +4710,7 @@ DEFUN (bgp_network_mask,
{
int ret;
char prefix_str[BUFSIZ];
-
+
ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
if (! ret)
{
@@ -3954,7 +4734,7 @@ DEFUN (bgp_network_mask_route_map,
{
int ret;
char prefix_str[BUFSIZ];
-
+
ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
if (! ret)
{
@@ -3977,7 +4757,7 @@ DEFUN (bgp_network_mask_backdoor,
{
int ret;
char prefix_str[BUFSIZ];
-
+
ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str);
if (! ret)
{
@@ -4059,7 +4839,7 @@ DEFUN (no_bgp_network,
"Specify a network to announce via BGP\n"
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n")
{
- return bgp_static_unset (vty, vty->index, argv[0], AFI_IP,
+ return bgp_static_unset (vty, vty->index, argv[0], AFI_IP,
bgp_node_safi (vty));
}
@@ -4099,7 +4879,7 @@ DEFUN (no_bgp_network_mask,
return CMD_WARNING;
}
- return bgp_static_unset (vty, vty->index, prefix_str, AFI_IP,
+ return bgp_static_unset (vty, vty->index, prefix_str, AFI_IP,
bgp_node_safi (vty));
}
@@ -4141,7 +4921,7 @@ DEFUN (no_bgp_network_mask_natural,
return CMD_WARNING;
}
- return bgp_static_unset (vty, vty->index, prefix_str, AFI_IP,
+ return bgp_static_unset (vty, vty->index, prefix_str, AFI_IP,
bgp_node_safi (vty));
}
@@ -4230,6 +5010,7 @@ ALIAS_DEPRECATED (bgp_network,
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
+
ALIAS_DEPRECATED (bgp_network_backdoor,
bgp_network_backdoor_ttl_cmd,
"network A.B.C.D/M backdoor pathlimit <0-255>",
@@ -4238,6 +5019,7 @@ ALIAS_DEPRECATED (bgp_network_backdoor,
"Specify a BGP backdoor route\n"
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
+
ALIAS_DEPRECATED (bgp_network_mask,
bgp_network_mask_ttl_cmd,
"network A.B.C.D mask A.B.C.D pathlimit <0-255>",
@@ -4247,6 +5029,7 @@ ALIAS_DEPRECATED (bgp_network_mask,
"Network mask\n"
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
+
ALIAS_DEPRECATED (bgp_network_mask_backdoor,
bgp_network_mask_backdoor_ttl_cmd,
"network A.B.C.D mask A.B.C.D backdoor pathlimit <0-255>",
@@ -4257,6 +5040,7 @@ ALIAS_DEPRECATED (bgp_network_mask_backdoor,
"Specify a BGP backdoor route\n"
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
+
ALIAS_DEPRECATED (bgp_network_mask_natural,
bgp_network_mask_natural_ttl_cmd,
"network A.B.C.D pathlimit <0-255>",
@@ -4264,14 +5048,16 @@ ALIAS_DEPRECATED (bgp_network_mask_natural,
"Network number\n"
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
+
ALIAS_DEPRECATED (bgp_network_mask_natural_backdoor,
bgp_network_mask_natural_backdoor_ttl_cmd,
- "network A.B.C.D backdoor pathlimit (1-255>",
+ "network A.B.C.D backdoor pathlimit <1-255>",
"Specify a network to announce via BGP\n"
"Network number\n"
"Specify a BGP backdoor route\n"
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
+
ALIAS_DEPRECATED (no_bgp_network,
no_bgp_network_ttl_cmd,
"no network A.B.C.D/M pathlimit <0-255>",
@@ -4280,6 +5066,7 @@ ALIAS_DEPRECATED (no_bgp_network,
"IP prefix <network>/<length>, e.g., 35.0.0.0/8\n"
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
+
ALIAS_DEPRECATED (no_bgp_network,
no_bgp_network_backdoor_ttl_cmd,
"no network A.B.C.D/M backdoor pathlimit <0-255>",
@@ -4289,6 +5076,7 @@ ALIAS_DEPRECATED (no_bgp_network,
"Specify a BGP backdoor route\n"
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
+
ALIAS_DEPRECATED (no_bgp_network,
no_bgp_network_mask_ttl_cmd,
"no network A.B.C.D mask A.B.C.D pathlimit <0-255>",
@@ -4299,6 +5087,7 @@ ALIAS_DEPRECATED (no_bgp_network,
"Network mask\n"
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
+
ALIAS_DEPRECATED (no_bgp_network_mask,
no_bgp_network_mask_backdoor_ttl_cmd,
"no network A.B.C.D mask A.B.C.D backdoor pathlimit <0-255>",
@@ -4310,6 +5099,7 @@ ALIAS_DEPRECATED (no_bgp_network_mask,
"Specify a BGP backdoor route\n"
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
+
ALIAS_DEPRECATED (no_bgp_network_mask_natural,
no_bgp_network_mask_natural_ttl_cmd,
"no network A.B.C.D pathlimit <0-255>",
@@ -4318,6 +5108,7 @@ ALIAS_DEPRECATED (no_bgp_network_mask_natural,
"Network number\n"
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
+
ALIAS_DEPRECATED (no_bgp_network_mask_natural,
no_bgp_network_mask_natural_backdoor_ttl_cmd,
"no network A.B.C.D backdoor pathlimit <0-255>",
@@ -4327,6 +5118,7 @@ ALIAS_DEPRECATED (no_bgp_network_mask_natural,
"Specify a BGP backdoor route\n"
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
+
#ifdef HAVE_IPV6
ALIAS_DEPRECATED (ipv6_bgp_network,
ipv6_bgp_network_ttl_cmd,
@@ -4335,6 +5127,7 @@ ALIAS_DEPRECATED (ipv6_bgp_network,
"IPv6 prefix <network>/<length>\n"
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
+
ALIAS_DEPRECATED (no_ipv6_bgp_network,
no_ipv6_bgp_network_ttl_cmd,
"no network X:X::X:X/M pathlimit <0-255>",
@@ -4344,8 +5137,8 @@ ALIAS_DEPRECATED (no_ipv6_bgp_network,
"AS-Path hopcount limit attribute\n"
"AS-Pathlimit TTL, in number of AS-Path hops\n")
#endif /* HAVE_IPV6 */
-
-/* Aggreagete address:
+
+/* Aggregate address:
advertise-map Set condition to advertise attribute
as-set Generate AS set path information
@@ -4383,11 +5176,11 @@ static void
bgp_aggregate_free (struct bgp_aggregate *aggregate)
{
XFREE (MTYPE_BGP_AGGREGATE, aggregate);
-}
+}
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,
+ afi_t afi, safi_t safi, struct bgp_info *del,
struct bgp_aggregate *aggregate)
{
struct bgp_table *table;
@@ -4430,7 +5223,7 @@ bgp_aggregate_route (struct bgp *bgp, struct prefix *p, struct bgp_info *rinew,
{
match = 0;
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
{
if (BGP_INFO_HOLDDOWN (ri))
continue;
@@ -4507,7 +5300,7 @@ bgp_aggregate_route (struct bgp *bgp, struct prefix *p, struct bgp_info *rinew,
if (rinew)
{
aggregate->count++;
-
+
if (aggregate->summary_only)
(bgp_info_extra_get (rinew))->suppress++;
@@ -4598,7 +5391,7 @@ bgp_aggregate_increment (struct bgp *bgp, struct prefix *p,
}
void
-bgp_aggregate_decrement (struct bgp *bgp, struct prefix *p,
+bgp_aggregate_decrement (struct bgp *bgp, struct prefix *p,
struct bgp_info *del, afi_t afi, safi_t safi)
{
struct bgp_node *child;
@@ -4647,7 +5440,7 @@ bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi,
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))
@@ -4655,7 +5448,7 @@ bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi,
{
match = 0;
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
{
if (BGP_INFO_HOLDDOWN (ri))
continue;
@@ -4702,7 +5495,7 @@ bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi,
aggregate->count++;
}
}
-
+
/* If this node is suppressed, process the change. */
if (match)
bgp_process (bgp, rn, afi, safi);
@@ -4724,14 +5517,14 @@ bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi,
bgp_info_add (rn, new);
bgp_unlock_node (rn);
-
+
/* Process change. */
bgp_process (bgp, rn, afi, safi);
}
}
void
-bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi,
+bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi,
safi_t safi, struct bgp_aggregate *aggregate)
{
struct bgp_table *table;
@@ -4754,7 +5547,7 @@ bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi,
{
match = 0;
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
{
if (BGP_INFO_HOLDDOWN (ri))
continue;
@@ -4784,8 +5577,8 @@ bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi,
/* 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
+ for (ri = rn->info; ri; ri = ri->info_next)
+ if (ri->peer == bgp->peer_self
&& ri->type == ZEBRA_ROUTE_BGP
&& ri->sub_type == BGP_ROUTE_AGGREGATE)
break;
@@ -4886,7 +5679,7 @@ bgp_aggregate_set (struct vty *vty, const char *prefix_str,
{
vty_out (vty, "Error deleting aggregate.%s", VTY_NEWLINE);
bgp_unlock_node (rn);
- return CMD_WARNING;
+ return CMD_WARNING;
}
}
@@ -5180,7 +5973,7 @@ DEFUN (ipv6_aggregate_address_summary_only,
"Aggregate prefix\n"
"Filter more specific routes from updates\n")
{
- return bgp_aggregate_set (vty, argv[0], AFI_IP6, SAFI_UNICAST,
+ return bgp_aggregate_set (vty, argv[0], AFI_IP6, SAFI_UNICAST,
AGGREGATE_SUMMARY_ONLY, 0);
}
@@ -5241,7 +6034,7 @@ ALIAS (no_ipv6_aggregate_address_summary_only,
"Aggregate prefix\n"
"Filter more specific routes from updates\n")
#endif /* HAVE_IPV6 */
-
+
/* Redistribute route treatment. */
void
bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop,
@@ -5251,13 +6044,11 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop,
struct listnode *node, *nnode;
struct bgp_info *new;
struct bgp_info *bi;
- struct bgp_info info;
struct bgp_node *bn;
struct attr attr = { 0 };
struct attr attr_new = { 0 };
struct attr *new_attr;
afi_t afi;
- int ret;
/* Make default attribute. */
bgp_attr_default_set (&attr, BGP_ORIGIN_INCOMPLETE);
@@ -5282,13 +6073,16 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop,
/* Apply route-map. */
if (bgp->rmap[afi][type].map)
{
- info.peer = bgp->peer_self;
- info.attr = &attr_new;
+ struct bgp_info info_s = { 0 } ;
+ route_map_result_t ret;
+
+ info_s.peer = bgp->peer_self;
+ info_s.attr = &attr_new;
SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_REDISTRIBUTE);
ret = route_map_apply (bgp->rmap[afi][type].map, p, RMAP_BGP,
- &info);
+ &info_s);
bgp->peer_self->rmap_type = 0;
@@ -5297,7 +6091,7 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop,
/* Free uninterned attribute. */
bgp_attr_flush (&attr_new);
bgp_attr_extra_free (&attr_new);
-
+
/* Unintern original. */
aspath_unintern (&attr.aspath);
bgp_attr_extra_free (&attr);
@@ -5306,17 +6100,17 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop,
}
}
- bn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST],
+ bn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST],
afi, SAFI_UNICAST, p, NULL);
-
+
new_attr = bgp_attr_intern (&attr_new);
bgp_attr_extra_free (&attr_new);
-
- for (bi = bn->info; bi; bi = bi->next)
+
+ for (bi = bn->info; bi; bi = bi->info_next)
if (bi->peer == bgp->peer_self
&& bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
break;
-
+
if (bi)
{
if (attrhash_cmp (bi->attr, new_attr) &&
@@ -5332,7 +6126,7 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop,
{
/* 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);
@@ -5341,7 +6135,7 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop,
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);
@@ -5349,7 +6143,7 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop,
aspath_unintern (&attr.aspath);
bgp_attr_extra_free (&attr);
return;
- }
+ }
}
new = bgp_info_new ();
@@ -5389,7 +6183,7 @@ bgp_redistribute_delete (struct prefix *p, u_char type)
{
rn = bgp_afi_node_get (bgp->rib[afi][SAFI_UNICAST], afi, SAFI_UNICAST, p, NULL);
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
if (ri->peer == bgp->peer_self
&& ri->type == type)
break;
@@ -5417,7 +6211,7 @@ bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type)
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
{
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
if (ri->peer == bgp->peer_self
&& ri->type == type)
break;
@@ -5430,13 +6224,13 @@ bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type)
}
}
}
-
+
/* Static function to display route. */
static void
route_vty_out_route (struct prefix *p, struct vty *vty)
{
int len;
- u_int32_t destination;
+ u_int32_t destination;
char buf[BUFSIZ];
if (p->family == AF_INET)
@@ -5500,7 +6294,7 @@ route_vty_short_status_out (struct vty *vty, struct bgp_info *binfo)
if ((binfo->peer->as) && (binfo->peer->as == binfo->peer->local_as))
vty_out (vty, "i");
else
- vty_out (vty, " ");
+ vty_out (vty, " ");
}
/* called from terminal list command */
@@ -5509,10 +6303,10 @@ route_vty_out (struct vty *vty, struct prefix *p,
struct bgp_info *binfo, int display, safi_t safi)
{
struct attr *attr;
-
- /* short status lead text */
+
+ /* short status lead text */
route_vty_short_status_out (vty, binfo);
-
+
/* print prefix and mask */
if (! display)
route_vty_out_route (p, vty);
@@ -5521,23 +6315,23 @@ route_vty_out (struct vty *vty, struct prefix *p,
/* Print attribute */
attr = binfo->attr;
- if (attr)
+ if (attr)
{
if (p->family == AF_INET)
{
if (safi == SAFI_MPLS_VPN)
vty_out (vty, "%-16s",
- inet_ntoa (attr->extra->mp_nexthop_global_in));
+ safe_inet_ntoa (attr->extra->mp_nexthop_global_in));
else
- vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
+ vty_out (vty, "%-16s", safe_inet_ntoa (attr->nexthop));
}
-#ifdef HAVE_IPV6
+#ifdef HAVE_IPV6
else if (p->family == AF_INET6)
{
int len;
char buf[BUFSIZ];
- len = vty_out (vty, "%s",
+ len = vty_out (vty, "%s",
inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
buf, BUFSIZ));
len = 16 - len;
@@ -5559,7 +6353,7 @@ route_vty_out (struct vty *vty, struct prefix *p,
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, " ");
@@ -5568,7 +6362,7 @@ route_vty_out (struct vty *vty, struct prefix *p,
vty_out (vty, "%s", bgp_origin_str[attr->origin]);
}
vty_out (vty, "%s", VTY_NEWLINE);
-}
+}
/* called from terminal list command */
void
@@ -5584,22 +6378,22 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p,
route_vty_out_route (p, vty);
/* Print attribute */
- if (attr)
+ if (attr)
{
if (p->family == AF_INET)
{
if (safi == SAFI_MPLS_VPN)
vty_out (vty, "%-16s",
- inet_ntoa (attr->extra->mp_nexthop_global_in));
+ safe_inet_ntoa (attr->extra->mp_nexthop_global_in));
else
- vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
+ vty_out (vty, "%-16s", safe_inet_ntoa (attr->nexthop));
}
#ifdef HAVE_IPV6
else if (p->family == AF_INET6)
{
int len;
char buf[BUFSIZ];
-
+
assert (attr->extra);
len = vty_out (vty, "%s",
@@ -5622,9 +6416,9 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p,
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, " ");
@@ -5634,7 +6428,7 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p,
}
vty_out (vty, "%s", VTY_NEWLINE);
-}
+}
void
route_vty_out_tag (struct vty *vty, struct prefix *p,
@@ -5642,13 +6436,13 @@ route_vty_out_tag (struct vty *vty, struct prefix *p,
{
struct attr *attr;
u_int32_t label = 0;
-
+
if (!binfo->extra)
return;
-
- /* short status lead text */
+
+ /* short status lead text */
route_vty_short_status_out (vty, binfo);
-
+
/* print prefix and mask */
if (! display)
route_vty_out_route (p, vty);
@@ -5657,24 +6451,24 @@ route_vty_out_tag (struct vty *vty, struct prefix *p,
/* Print attribute */
attr = binfo->attr;
- if (attr)
+ if (attr)
{
if (p->family == AF_INET)
{
if (safi == SAFI_MPLS_VPN)
vty_out (vty, "%-16s",
- inet_ntoa (attr->extra->mp_nexthop_global_in));
+ safe_inet_ntoa (attr->extra->mp_nexthop_global_in));
else
- vty_out (vty, "%-16s", inet_ntoa (attr->nexthop));
+ vty_out (vty, "%-16s", safe_inet_ntoa (attr->nexthop));
}
-#ifdef HAVE_IPV6
+#ifdef HAVE_IPV6
else if (p->family == AF_INET6)
{
assert (attr->extra);
char buf[BUFSIZ];
char buf1[BUFSIZ];
if (attr->extra->mp_nexthop_len == 16)
- vty_out (vty, "%s",
+ vty_out (vty, "%s",
inet_ntop (AF_INET6, &attr->extra->mp_nexthop_global,
buf, BUFSIZ));
else if (attr->extra->mp_nexthop_len == 32)
@@ -5683,7 +6477,7 @@ route_vty_out_tag (struct vty *vty, struct prefix *p,
buf, BUFSIZ),
inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
buf1, BUFSIZ));
-
+
}
#endif /* HAVE_IPV6 */
}
@@ -5693,7 +6487,7 @@ route_vty_out_tag (struct vty *vty, struct prefix *p,
vty_out (vty, "notag/%d", label);
vty_out (vty, "%s", VTY_NEWLINE);
-}
+}
/* dampening route */
static void
@@ -5704,9 +6498,9 @@ damp_route_vty_out (struct vty *vty, struct prefix *p,
int len;
char timebuf[BGP_UPTIME_LEN];
- /* short status lead text */
+ /* short status lead text */
route_vty_short_status_out (vty, binfo);
-
+
/* print prefix and mask */
if (! display)
route_vty_out_route (p, vty);
@@ -5745,15 +6539,15 @@ flap_route_vty_out (struct vty *vty, struct prefix *p,
struct bgp_damp_info *bdi;
char timebuf[BGP_UPTIME_LEN];
int len;
-
+
if (!binfo->extra)
return;
-
+
bdi = binfo->extra->damp_info;
/* short status lead text */
route_vty_short_status_out (vty, binfo);
-
+
/* print prefix and mask */
if (! display)
route_vty_out_route (p, vty);
@@ -5773,7 +6567,7 @@ flap_route_vty_out (struct vty *vty, struct prefix *p,
vty_out (vty, " ");
else
vty_out (vty, "%*s ", len, " ");
-
+
vty_out (vty, "%s ", peer_uptime (bdi->start_time,
timebuf, BGP_UPTIME_LEN));
@@ -5798,17 +6592,14 @@ flap_route_vty_out (struct vty *vty, struct prefix *p,
}
static void
-route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
+route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
struct bgp_info *binfo, afi_t afi, safi_t safi)
{
- char buf[INET6_ADDRSTRLEN];
- char buf1[BUFSIZ];
+ char buf[SU_ADDRSTRLEN];
struct attr *attr;
int sockunion_vty_out (struct vty *, union sockunion *);
-#ifdef HAVE_CLOCK_MONOTONIC
- time_t tbuf;
-#endif
-
+ time_t tbuf ;
+
attr = binfo->attr;
if (attr)
@@ -5828,25 +6619,27 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
if (CHECK_FLAG (binfo->flags, BGP_INFO_STALE))
vty_out (vty, ", (stale)");
if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR)))
- vty_out (vty, ", (aggregated by %u %s)",
+ 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))
+ safe_inet_ntoa (attr->extra->aggregator_addr));
+ if (CHECK_FLAG (binfo->peer->af_flags[afi][safi],
+ PEER_FLAG_REFLECTOR_CLIENT))
vty_out (vty, ", (Received from a RR-client)");
- if (CHECK_FLAG (binfo->peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT))
+ if (CHECK_FLAG (binfo->peer->af_flags[afi][safi],
+ PEER_FLAG_RSERVER_CLIENT))
vty_out (vty, ", (Received from a RS-client)");
if (CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
vty_out (vty, ", (history entry)");
else if (CHECK_FLAG (binfo->flags, BGP_INFO_DAMPED))
vty_out (vty, ", (suppressed due to dampening)");
vty_out (vty, "%s", VTY_NEWLINE);
-
+
/* Line2 display Next-hop, Neighbor, Router-id */
if (p->family == AF_INET)
{
vty_out (vty, " %s", safi == SAFI_MPLS_VPN ?
- inet_ntoa (attr->extra->mp_nexthop_global_in) :
- inet_ntoa (attr->nexthop));
+ safe_inet_ntoa (attr->extra->mp_nexthop_global_in) :
+ safe_inet_ntoa (attr->nexthop));
}
#ifdef HAVE_IPV6
else
@@ -5860,21 +6653,23 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
if (binfo->peer == bgp->peer_self)
{
- vty_out (vty, " from %s ",
+ vty_out (vty, " from %s ",
p->family == AF_INET ? "0.0.0.0" : "::");
- vty_out (vty, "(%s)", inet_ntoa(bgp->router_id));
+ vty_out (vty, "(%s)", safe_inet_ntoa(bgp->router_id));
}
else
{
if (! CHECK_FLAG (binfo->flags, BGP_INFO_VALID))
- vty_out (vty, " (inaccessible)");
+ vty_out (vty, " (inaccessible)");
else if (binfo->extra && binfo->extra->igpmetric)
vty_out (vty, " (metric %d)", binfo->extra->igpmetric);
- vty_out (vty, " from %s", sockunion2str (&binfo->peer->su, buf, SU_ADDRSTRLEN));
+ vty_out (vty, " from %s",
+ sockunion2str (&binfo->peer->su, buf, sizeof(buf)));
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
- vty_out (vty, " (%s)", inet_ntoa (attr->extra->originator_id));
+ vty_out (vty, " (%s)", safe_inet_ntoa (attr->extra->originator_id));
else
- vty_out (vty, " (%s)", inet_ntop (AF_INET, &binfo->peer->remote_id, buf1, BUFSIZ));
+ vty_out (vty, " (%s)",
+ inet_ntop (AF_INET, &binfo->peer->remote_id, buf, sizeof(buf)));
}
vty_out (vty, "%s", VTY_NEWLINE);
@@ -5884,17 +6679,18 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
{
vty_out (vty, " (%s)%s",
inet_ntop (AF_INET6, &attr->extra->mp_nexthop_local,
- buf, INET6_ADDRSTRLEN),
+ buf, sizeof(buf)),
VTY_NEWLINE);
}
#endif /* HAVE_IPV6 */
- /* Line 3 display Origin, Med, Locpref, Weight, valid, Int/Ext/Local, Atomic, best */
+ /* Line 3 display:
+ * Origin, Med, Locpref, Weight, valid, Int/Ext/Local, Atomic, best */
vty_out (vty, " Origin %s", bgp_origin_long_str[attr->origin]);
-
+
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
vty_out (vty, ", metric %u", attr->med);
-
+
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))
vty_out (vty, ", localpref %u", attr->local_pref);
else
@@ -5902,7 +6698,7 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
if (attr->extra && attr->extra->weight != 0)
vty_out (vty, ", weight %u", attr->extra->weight);
-
+
if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
vty_out (vty, ", valid");
@@ -5910,9 +6706,10 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
{
if (binfo->peer->as == binfo->peer->local_as)
vty_out (vty, ", internal");
- else
- vty_out (vty, ", %s",
- (bgp_confederation_peers_check(bgp, binfo->peer->as) ? "confed-external" : "external"));
+ else
+ vty_out (vty, ", %s",
+ (bgp_confederation_peers_check(bgp, binfo->peer->as)
+ ? "confed-external" : "external"));
}
else if (binfo->sub_type == BGP_ROUTE_AGGREGATE)
vty_out (vty, ", aggregated, local");
@@ -5923,56 +6720,52 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
vty_out (vty, ", atomic-aggregate");
-
+
if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED))
vty_out (vty, ", best");
vty_out (vty, "%s", VTY_NEWLINE);
-
+
/* Line 4 display Community */
if (attr->community)
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))
- vty_out (vty, " Extended Community: %s%s",
+ vty_out (vty, " Extended Community: %s%s",
attr->extra->ecommunity->str, VTY_NEWLINE);
-
+
/* Line 6 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))
- vty_out (vty, " Originator: %s",
- inet_ntoa (attr->extra->originator_id));
+ vty_out (vty, " Originator: %s",
+ safe_inet_ntoa (attr->extra->originator_id));
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))
{
int i;
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]));
+ vty_out (vty, "%s ",
+ safe_inet_ntoa (attr->extra->cluster->list[i]));
}
vty_out (vty, "%s", VTY_NEWLINE);
}
-
+
if (binfo->extra && binfo->extra->damp_info)
bgp_damp_info_vty (vty, binfo);
/* Line 7 display Uptime */
-#ifdef HAVE_CLOCK_MONOTONIC
- tbuf = time(NULL) - (bgp_clock() - binfo->uptime);
+ tbuf = bgp_wall_clock(binfo->uptime);
vty_out (vty, " Last update: %s", ctime(&tbuf));
-#else
- vty_out (vty, " Last update: %s", ctime(&binfo->uptime));
-#endif /* HAVE_CLOCK_MONOTONIC */
}
vty_out (vty, "%s", VTY_NEWLINE);
-}
-
+}
+
#define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,%s r RIB-failure, S Stale, R Removed%s"
#define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s"
#define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path%s"
@@ -6022,12 +6815,12 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, struct in_addr *router
output_count = 0;
/* Start processing of routes. */
- for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
if (rn->info != NULL)
{
display = 0;
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
{
if (type == bgp_show_type_flap_statistics
|| type == bgp_show_type_flap_address
@@ -6049,7 +6842,7 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, struct in_addr *router
|| type == bgp_show_type_flap_regexp)
{
regex_t *regex = output_arg;
-
+
if (bgp_regexec (regex, ri->attr->aspath) == REG_NOMATCH)
continue;
}
@@ -6057,7 +6850,7 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, struct in_addr *router
|| type == bgp_show_type_flap_prefix_list)
{
struct prefix_list *plist = output_arg;
-
+
if (prefix_list_apply (plist, &rn->p) != PREFIX_PERMIT)
continue;
}
@@ -6073,18 +6866,19 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, struct in_addr *router
|| type == bgp_show_type_flap_route_map)
{
struct route_map *rmap = output_arg;
- struct bgp_info binfo;
- struct attr dummy_attr = { 0 };
- int ret;
+ struct attr dummy_attr = { 0 };
+ struct bgp_info info_s = { 0 } ;
+ route_map_result_t ret;
bgp_attr_dup (&dummy_attr, ri->attr);
- binfo.peer = ri->peer;
- binfo.attr = &dummy_attr;
+ info_s.peer = ri->peer;
+ info_s.attr = &dummy_attr;
+
+ /* TODO: check if routemap may be setting stuff */
+ ret = route_map_apply (rmap, &rn->p, RMAP_BGP, &info_s);
- ret = route_map_apply (rmap, &rn->p, RMAP_BGP, &binfo);
-
bgp_attr_extra_free (&dummy_attr);
-
+
if (ret == RMAP_DENYMATCH)
continue;
}
@@ -6175,7 +6969,7 @@ bgp_show_table (struct vty *vty, struct bgp_table *table, struct in_addr *router
if (header)
{
- vty_out (vty, "BGP table version is 0, local router ID is %s%s", inet_ntoa (*router_id), VTY_NEWLINE);
+ vty_out (vty, "BGP table version is 0, local router ID is %s%s", safe_inet_ntoa (*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
@@ -6264,8 +7058,8 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
struct prefix *p;
struct peer *peer;
struct listnode *node, *nnode;
- char buf1[INET6_ADDRSTRLEN];
- char buf2[INET6_ADDRSTRLEN];
+ char buf[SU_ADDRSTRLEN];
+ char buf_rd[RD_ADDRSTRLEN];
int count = 0;
int best = 0;
int suppress = 0;
@@ -6277,12 +7071,12 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
p = &rn->p;
vty_out (vty, "BGP routing table entry for %s%s%s/%d%s",
(safi == SAFI_MPLS_VPN ?
- prefix_rd2str (prd, buf1, RD_ADDRSTRLEN) : ""),
+ prefix_rd2str (prd, buf_rd, sizeof(buf_rd)) : ""),
safi == SAFI_MPLS_VPN ? ":" : "",
- inet_ntop (p->family, &p->u.prefix, buf2, INET6_ADDRSTRLEN),
+ inet_ntop (p->family, &p->u.prefix, buf, sizeof(buf)),
p->prefixlen, VTY_NEWLINE);
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
{
count++;
if (CHECK_FLAG (ri->flags, BGP_INFO_SELECTED))
@@ -6327,8 +7121,9 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
if (bgp_adj_out_lookup (peer, p, afi, safi, rn))
{
if (! first)
- vty_out (vty, " Advertised to non peer-group peers:%s ", VTY_NEWLINE);
- vty_out (vty, " %s", sockunion2str (&peer->su, buf1, SU_ADDRSTRLEN));
+ vty_out (vty, " Advertised to non peer-group peers:%s ",
+ VTY_NEWLINE);
+ vty_out (vty, " %s", sutoa(&peer->su).str);
first = 1;
}
}
@@ -6339,7 +7134,7 @@ route_vty_out_detail_header (struct vty *vty, struct bgp *bgp,
/* Display specified route of BGP table. */
static int
-bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
+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)
@@ -6357,7 +7152,7 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
ret = str2prefix (ip_str, &match);
if (! ret)
{
- vty_out (vty, "address is malformed%s", VTY_NEWLINE);
+ vty_out (vty, "%% address is malformed%s", VTY_NEWLINE);
return CMD_WARNING;
}
@@ -6376,23 +7171,22 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
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 (prefix_check && rm->p.prefixlen == match.prefixlen)
{
- if (header)
+ for (ri = rm->info; ri; ri = ri->info_next)
{
- route_vty_out_detail_header (vty, bgp, rm, (struct prefix_rd *)&rn->p,
- AFI_IP, SAFI_MPLS_VPN);
-
- header = 0;
+ if (header)
+ {
+ route_vty_out_detail_header (vty, bgp, rm,
+ (struct prefix_rd *)&rn->p,
+ AFI_IP, SAFI_MPLS_VPN);
+
+ header = 0;
+ }
+ display++;
+ route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP,
+ SAFI_MPLS_VPN);
}
- display++;
- route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, SAFI_MPLS_VPN);
}
bgp_unlock_node (rm);
@@ -6408,7 +7202,7 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp,
{
if (! prefix_check || rn->p.prefixlen == match.prefixlen)
{
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_next)
{
if (header)
{
@@ -6460,8 +7254,8 @@ bgp_show_route (struct vty *vty, const char *view_name, const char *ip_str,
return CMD_WARNING;
}
}
-
- return bgp_show_route_in_table (vty, bgp, bgp->rib[afi][safi], ip_str,
+
+ return bgp_show_route_in_table (vty, bgp, bgp->rib[afi][safi], ip_str,
afi, safi, prd, prefix_check);
}
@@ -6489,7 +7283,7 @@ DEFUN (show_ip_bgp_ipv4,
if (strncmp (argv[0], "m", 1) == 0)
return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST, bgp_show_type_normal,
NULL);
-
+
return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL);
}
@@ -6853,7 +7647,7 @@ DEFUN (show_bgp_view,
vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
-
+
return bgp_show (vty, bgp, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal, NULL);
}
@@ -6861,11 +7655,11 @@ ALIAS (show_bgp_view,
show_bgp_view_ipv6_cmd,
"show bgp view WORD ipv6",
SHOW_STR
- BGP_STR
+ BGP_STR
"BGP view\n"
"View name\n"
"Address family\n")
-
+
DEFUN (show_bgp_view_route,
show_bgp_view_route_cmd,
"show bgp view WORD X:X::X:X",
@@ -6894,10 +7688,10 @@ DEFUN (show_bgp_view_prefix,
SHOW_STR
BGP_STR
"BGP view\n"
- "View name\n"
+ "View name\n"
"IPv6 prefix <network>/<length>\n")
{
- return bgp_show_route (vty, argv[0], argv[1], AFI_IP6, SAFI_UNICAST, NULL, 1);
+ return bgp_show_route (vty, argv[0], argv[1], AFI_IP6, SAFI_UNICAST, NULL, 1);
}
ALIAS (show_bgp_view_prefix,
@@ -6908,7 +7702,7 @@ ALIAS (show_bgp_view_prefix,
"BGP view\n"
"View name\n"
"Address family\n"
- "IPv6 prefix <network>/<length>\n")
+ "IPv6 prefix <network>/<length>\n")
/* old command */
DEFUN (show_ipv6_mbgp,
@@ -6946,10 +7740,10 @@ DEFUN (show_ipv6_mbgp_prefix,
return bgp_show_route (vty, NULL, argv[0], AFI_IP6, SAFI_MULTICAST, NULL, 1);
}
#endif
-
+
static int
-bgp_show_regexp (struct vty *vty, int argc, const char **argv, afi_t afi,
+bgp_show_regexp (struct vty *vty, int argc, argv_t argv, afi_t afi,
safi_t safi, enum bgp_show_type type)
{
int i;
@@ -6958,7 +7752,7 @@ bgp_show_regexp (struct vty *vty, int argc, const char **argv, afi_t afi,
int first;
regex_t *regex;
int rc;
-
+
first = 0;
b = buffer_new (1024);
for (i = 0; i < argc; i++)
@@ -6993,7 +7787,7 @@ bgp_show_regexp (struct vty *vty, int argc, const char **argv, afi_t afi,
return rc;
}
-DEFUN (show_ip_bgp_regexp,
+DEFUN (show_ip_bgp_regexp,
show_ip_bgp_regexp_cmd,
"show ip bgp regexp .LINE",
SHOW_STR
@@ -7006,7 +7800,7 @@ DEFUN (show_ip_bgp_regexp,
bgp_show_type_regexp);
}
-DEFUN (show_ip_bgp_flap_regexp,
+DEFUN (show_ip_bgp_flap_regexp,
show_ip_bgp_flap_regexp_cmd,
"show ip bgp flap-statistics regexp .LINE",
SHOW_STR
@@ -7020,7 +7814,7 @@ DEFUN (show_ip_bgp_flap_regexp,
bgp_show_type_flap_regexp);
}
-DEFUN (show_ip_bgp_ipv4_regexp,
+DEFUN (show_ip_bgp_ipv4_regexp,
show_ip_bgp_ipv4_regexp_cmd,
"show ip bgp ipv4 (unicast|multicast) regexp .LINE",
SHOW_STR
@@ -7041,7 +7835,7 @@ DEFUN (show_ip_bgp_ipv4_regexp,
}
#ifdef HAVE_IPV6
-DEFUN (show_bgp_regexp,
+DEFUN (show_bgp_regexp,
show_bgp_regexp_cmd,
"show bgp regexp .LINE",
SHOW_STR
@@ -7053,7 +7847,7 @@ DEFUN (show_bgp_regexp,
bgp_show_type_regexp);
}
-ALIAS (show_bgp_regexp,
+ALIAS (show_bgp_regexp,
show_bgp_ipv6_regexp_cmd,
"show bgp ipv6 regexp .LINE",
SHOW_STR
@@ -7063,7 +7857,7 @@ ALIAS (show_bgp_regexp,
"A regular-expression to match the BGP AS paths\n")
/* old command */
-DEFUN (show_ipv6_bgp_regexp,
+DEFUN (show_ipv6_bgp_regexp,
show_ipv6_bgp_regexp_cmd,
"show ipv6 bgp regexp .LINE",
SHOW_STR
@@ -7077,7 +7871,7 @@ DEFUN (show_ipv6_bgp_regexp,
}
/* old command */
-DEFUN (show_ipv6_mbgp_regexp,
+DEFUN (show_ipv6_mbgp_regexp,
show_ipv6_mbgp_regexp_cmd,
"show ipv6 mbgp regexp .LINE",
SHOW_STR
@@ -7090,7 +7884,7 @@ DEFUN (show_ipv6_mbgp_regexp,
bgp_show_type_regexp);
}
#endif /* HAVE_IPV6 */
-
+
static int
bgp_show_prefix_list (struct vty *vty, const char *prefix_list_str, afi_t afi,
safi_t safi, enum bgp_show_type type)
@@ -7101,14 +7895,14 @@ bgp_show_prefix_list (struct vty *vty, const char *prefix_list_str, afi_t afi,
if (plist == NULL)
{
vty_out (vty, "%% %s is not a valid prefix-list name%s",
- prefix_list_str, VTY_NEWLINE);
+ prefix_list_str, VTY_NEWLINE);
return CMD_WARNING;
}
return bgp_show (vty, NULL, afi, safi, type, plist);
}
-DEFUN (show_ip_bgp_prefix_list,
+DEFUN (show_ip_bgp_prefix_list,
show_ip_bgp_prefix_list_cmd,
"show ip bgp prefix-list WORD",
SHOW_STR
@@ -7121,7 +7915,7 @@ DEFUN (show_ip_bgp_prefix_list,
bgp_show_type_prefix_list);
}
-DEFUN (show_ip_bgp_flap_prefix_list,
+DEFUN (show_ip_bgp_flap_prefix_list,
show_ip_bgp_flap_prefix_list_cmd,
"show ip bgp flap-statistics prefix-list WORD",
SHOW_STR
@@ -7135,7 +7929,7 @@ DEFUN (show_ip_bgp_flap_prefix_list,
bgp_show_type_flap_prefix_list);
}
-DEFUN (show_ip_bgp_ipv4_prefix_list,
+DEFUN (show_ip_bgp_ipv4_prefix_list,
show_ip_bgp_ipv4_prefix_list_cmd,
"show ip bgp ipv4 (unicast|multicast) prefix-list WORD",
SHOW_STR
@@ -7156,7 +7950,7 @@ DEFUN (show_ip_bgp_ipv4_prefix_list,
}
#ifdef HAVE_IPV6
-DEFUN (show_bgp_prefix_list,
+DEFUN (show_bgp_prefix_list,
show_bgp_prefix_list_cmd,
"show bgp prefix-list WORD",
SHOW_STR
@@ -7168,7 +7962,7 @@ DEFUN (show_bgp_prefix_list,
bgp_show_type_prefix_list);
}
-ALIAS (show_bgp_prefix_list,
+ALIAS (show_bgp_prefix_list,
show_bgp_ipv6_prefix_list_cmd,
"show bgp ipv6 prefix-list WORD",
SHOW_STR
@@ -7178,7 +7972,7 @@ ALIAS (show_bgp_prefix_list,
"IPv6 prefix-list name\n")
/* old command */
-DEFUN (show_ipv6_bgp_prefix_list,
+DEFUN (show_ipv6_bgp_prefix_list,
show_ipv6_bgp_prefix_list_cmd,
"show ipv6 bgp prefix-list WORD",
SHOW_STR
@@ -7192,7 +7986,7 @@ DEFUN (show_ipv6_bgp_prefix_list,
}
/* old command */
-DEFUN (show_ipv6_mbgp_prefix_list,
+DEFUN (show_ipv6_mbgp_prefix_list,
show_ipv6_mbgp_prefix_list_cmd,
"show ipv6 mbgp prefix-list WORD",
SHOW_STR
@@ -7205,7 +7999,7 @@ DEFUN (show_ipv6_mbgp_prefix_list,
bgp_show_type_prefix_list);
}
#endif /* HAVE_IPV6 */
-
+
static int
bgp_show_filter_list (struct vty *vty, const char *filter, afi_t afi,
safi_t safi, enum bgp_show_type type)
@@ -7215,14 +8009,14 @@ bgp_show_filter_list (struct vty *vty, const char *filter, afi_t afi,
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);
+ vty_out (vty, "%% %s is not a valid AS-path access-list name%s", filter, VTY_NEWLINE);
return CMD_WARNING;
}
return bgp_show (vty, NULL, afi, safi, type, as_list);
}
-DEFUN (show_ip_bgp_filter_list,
+DEFUN (show_ip_bgp_filter_list,
show_ip_bgp_filter_list_cmd,
"show ip bgp filter-list WORD",
SHOW_STR
@@ -7235,7 +8029,7 @@ DEFUN (show_ip_bgp_filter_list,
bgp_show_type_filter_list);
}
-DEFUN (show_ip_bgp_flap_filter_list,
+DEFUN (show_ip_bgp_flap_filter_list,
show_ip_bgp_flap_filter_list_cmd,
"show ip bgp flap-statistics filter-list WORD",
SHOW_STR
@@ -7249,7 +8043,7 @@ DEFUN (show_ip_bgp_flap_filter_list,
bgp_show_type_flap_filter_list);
}
-DEFUN (show_ip_bgp_ipv4_filter_list,
+DEFUN (show_ip_bgp_ipv4_filter_list,
show_ip_bgp_ipv4_filter_list_cmd,
"show ip bgp ipv4 (unicast|multicast) filter-list WORD",
SHOW_STR
@@ -7264,13 +8058,13 @@ DEFUN (show_ip_bgp_ipv4_filter_list,
if (strncmp (argv[0], "m", 1) == 0)
return bgp_show_filter_list (vty, argv[1], AFI_IP, SAFI_MULTICAST,
bgp_show_type_filter_list);
-
+
return bgp_show_filter_list (vty, argv[1], AFI_IP, SAFI_UNICAST,
bgp_show_type_filter_list);
}
#ifdef HAVE_IPV6
-DEFUN (show_bgp_filter_list,
+DEFUN (show_bgp_filter_list,
show_bgp_filter_list_cmd,
"show bgp filter-list WORD",
SHOW_STR
@@ -7282,7 +8076,7 @@ DEFUN (show_bgp_filter_list,
bgp_show_type_filter_list);
}
-ALIAS (show_bgp_filter_list,
+ALIAS (show_bgp_filter_list,
show_bgp_ipv6_filter_list_cmd,
"show bgp ipv6 filter-list WORD",
SHOW_STR
@@ -7292,7 +8086,7 @@ ALIAS (show_bgp_filter_list,
"Regular expression access list name\n")
/* old command */
-DEFUN (show_ipv6_bgp_filter_list,
+DEFUN (show_ipv6_bgp_filter_list,
show_ipv6_bgp_filter_list_cmd,
"show ipv6 bgp filter-list WORD",
SHOW_STR
@@ -7306,7 +8100,7 @@ DEFUN (show_ipv6_bgp_filter_list,
}
/* old command */
-DEFUN (show_ipv6_mbgp_filter_list,
+DEFUN (show_ipv6_mbgp_filter_list,
show_ipv6_mbgp_filter_list_cmd,
"show ipv6 mbgp filter-list WORD",
SHOW_STR
@@ -7319,7 +8113,7 @@ DEFUN (show_ipv6_mbgp_filter_list,
bgp_show_type_filter_list);
}
#endif /* HAVE_IPV6 */
-
+
static int
bgp_show_route_map (struct vty *vty, const char *rmap_str, afi_t afi,
safi_t safi, enum bgp_show_type type)
@@ -7330,14 +8124,14 @@ bgp_show_route_map (struct vty *vty, const char *rmap_str, afi_t afi,
if (! rmap)
{
vty_out (vty, "%% %s is not a valid route-map name%s",
- rmap_str, VTY_NEWLINE);
+ rmap_str, VTY_NEWLINE);
return CMD_WARNING;
}
return bgp_show (vty, NULL, afi, safi, type, rmap);
}
-DEFUN (show_ip_bgp_route_map,
+DEFUN (show_ip_bgp_route_map,
show_ip_bgp_route_map_cmd,
"show ip bgp route-map WORD",
SHOW_STR
@@ -7350,7 +8144,7 @@ DEFUN (show_ip_bgp_route_map,
bgp_show_type_route_map);
}
-DEFUN (show_ip_bgp_flap_route_map,
+DEFUN (show_ip_bgp_flap_route_map,
show_ip_bgp_flap_route_map_cmd,
"show ip bgp flap-statistics route-map WORD",
SHOW_STR
@@ -7364,7 +8158,7 @@ DEFUN (show_ip_bgp_flap_route_map,
bgp_show_type_flap_route_map);
}
-DEFUN (show_ip_bgp_ipv4_route_map,
+DEFUN (show_ip_bgp_ipv4_route_map,
show_ip_bgp_ipv4_route_map_cmd,
"show ip bgp ipv4 (unicast|multicast) route-map WORD",
SHOW_STR
@@ -7384,7 +8178,7 @@ DEFUN (show_ip_bgp_ipv4_route_map,
bgp_show_type_route_map);
}
-DEFUN (show_bgp_route_map,
+DEFUN (show_bgp_route_map,
show_bgp_route_map_cmd,
"show bgp route-map WORD",
SHOW_STR
@@ -7396,7 +8190,7 @@ DEFUN (show_bgp_route_map,
bgp_show_type_route_map);
}
-ALIAS (show_bgp_route_map,
+ALIAS (show_bgp_route_map,
show_bgp_ipv6_route_map_cmd,
"show bgp ipv6 route-map WORD",
SHOW_STR
@@ -7404,7 +8198,7 @@ ALIAS (show_bgp_route_map,
"Address family\n"
"Display routes matching the route-map\n"
"A route-map to match on\n")
-
+
DEFUN (show_ip_bgp_cidr_only,
show_ip_bgp_cidr_only_cmd,
"show ip bgp cidr-only",
@@ -7448,7 +8242,7 @@ DEFUN (show_ip_bgp_ipv4_cidr_only,
return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
bgp_show_type_cidr_only, NULL);
}
-
+
DEFUN (show_ip_bgp_community_all,
show_ip_bgp_community_all_cmd,
"show ip bgp community",
@@ -7475,7 +8269,7 @@ DEFUN (show_ip_bgp_ipv4_community_all,
if (strncmp (argv[0], "m", 1) == 0)
return bgp_show (vty, NULL, AFI_IP, SAFI_MULTICAST,
bgp_show_type_community_all, NULL);
-
+
return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
bgp_show_type_community_all, NULL);
}
@@ -7526,10 +8320,11 @@ DEFUN (show_ipv6_mbgp_community_all,
bgp_show_type_community_all, NULL);
}
#endif /* HAVE_IPV6 */
-
+
static int
-bgp_show_community (struct vty *vty, const char *view_name, int argc,
- const char **argv, int exact, afi_t afi, safi_t safi)
+bgp_show_community (struct vty *vty, const char *view_name,
+ int argc, argv_t argv,
+ int exact, afi_t afi, safi_t safi)
{
struct community *com;
struct buffer *b;
@@ -7543,19 +8338,19 @@ bgp_show_community (struct vty *vty, const char *view_name, int argc,
{
bgp = bgp_lookup_by_name (view_name);
if (bgp == NULL)
- {
- vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE);
- return CMD_WARNING;
- }
+ {
+ vty_out (vty, "Can't find BGP view %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;
- }
+ {
+ vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE);
+ return CMD_WARNING;
+ }
}
b = buffer_new (1024);
@@ -7565,11 +8360,12 @@ bgp_show_community (struct vty *vty, const char *view_name, int argc,
buffer_putc (b, ' ');
else
{
- if ((strcmp (argv[i], "unicast") == 0) || (strcmp (argv[i], "multicast") == 0))
+ if ( (strcmp (argv[i], "unicast") == 0)
+ || (strcmp (argv[i], "multicast") == 0) )
continue;
first = 1;
}
-
+
buffer_putstr (b, argv[i]);
}
buffer_putc (b, '\0');
@@ -7620,7 +8416,7 @@ ALIAS (show_ip_bgp_community,
"Do not send outside local AS (well-known community)\n"
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n")
-
+
ALIAS (show_ip_bgp_community,
show_ip_bgp_community3_cmd,
"show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
@@ -7640,7 +8436,7 @@ ALIAS (show_ip_bgp_community,
"Do not send outside local AS (well-known community)\n"
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n")
-
+
ALIAS (show_ip_bgp_community,
show_ip_bgp_community4_cmd,
"show ip bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
@@ -7680,10 +8476,11 @@ DEFUN (show_ip_bgp_ipv4_community,
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n")
{
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_MULTICAST);
-
- return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_UNICAST);
+ safi_t safi ;
+
+ safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST ;
+
+ return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, safi);
}
ALIAS (show_ip_bgp_ipv4_community,
@@ -7704,7 +8501,7 @@ ALIAS (show_ip_bgp_ipv4_community,
"Do not send outside local AS (well-known community)\n"
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n")
-
+
ALIAS (show_ip_bgp_ipv4_community,
show_ip_bgp_ipv4_community3_cmd,
"show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
@@ -7727,7 +8524,7 @@ ALIAS (show_ip_bgp_ipv4_community,
"Do not send outside local AS (well-known community)\n"
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n")
-
+
ALIAS (show_ip_bgp_ipv4_community,
show_ip_bgp_ipv4_community4_cmd,
"show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
@@ -8021,10 +8818,11 @@ DEFUN (show_ip_bgp_ipv4_community_exact,
"Do not export to next AS (well-known community)\n"
"Exact match of the communities")
{
- if (strncmp (argv[0], "m", 1) == 0)
- return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_MULTICAST);
-
- return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_UNICAST);
+ safi_t safi ;
+
+ safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST ;
+
+ return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, safi);
}
ALIAS (show_ip_bgp_ipv4_community_exact,
@@ -8070,7 +8868,7 @@ ALIAS (show_ip_bgp_ipv4_community_exact,
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n"
"Exact match of the communities")
-
+
ALIAS (show_ip_bgp_ipv4_community_exact,
show_ip_bgp_ipv4_community4_exact_cmd,
"show ip bgp ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
@@ -8156,7 +8954,7 @@ ALIAS (show_bgp_community,
"Do not send outside local AS (well-known community)\n"
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n")
-
+
ALIAS (show_bgp_community,
show_bgp_community3_cmd,
"show bgp community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)",
@@ -8447,7 +9245,7 @@ ALIAS (show_bgp_community_exact,
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n"
"Exact match of the communities")
-
+
ALIAS (show_bgp_community_exact,
show_bgp_ipv6_community4_exact_cmd,
"show bgp ipv6 community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export) exact-match",
@@ -8555,7 +9353,7 @@ ALIAS (show_ipv6_bgp_community_exact,
"Do not advertise to any peer (well-known community)\n"
"Do not export to next AS (well-known community)\n"
"Exact match of the communities")
-
+
/* old command */
DEFUN (show_ipv6_mbgp_community,
show_ipv6_mbgp_community_cmd,
@@ -8718,7 +9516,7 @@ ALIAS (show_ipv6_mbgp_community_exact,
"Do not export to next AS (well-known community)\n"
"Exact match of the communities")
#endif /* HAVE_IPV6 */
-
+
static int
bgp_show_community_list (struct vty *vty, const char *com, int exact,
afi_t afi, safi_t safi)
@@ -8766,7 +9564,7 @@ DEFUN (show_ip_bgp_ipv4_community_list,
{
if (strncmp (argv[0], "m", 1) == 0)
return bgp_show_community_list (vty, argv[1], 0, AFI_IP, SAFI_MULTICAST);
-
+
return bgp_show_community_list (vty, argv[1], 0, AFI_IP, SAFI_UNICAST);
}
@@ -8800,7 +9598,7 @@ DEFUN (show_ip_bgp_ipv4_community_list_exact,
{
if (strncmp (argv[0], "m", 1) == 0)
return bgp_show_community_list (vty, argv[1], 1, AFI_IP, SAFI_MULTICAST);
-
+
return bgp_show_community_list (vty, argv[1], 1, AFI_IP, SAFI_UNICAST);
}
@@ -8905,7 +9703,7 @@ DEFUN (show_ipv6_mbgp_community_list_exact,
return bgp_show_community_list (vty, argv[0], 1, AFI_IP6, SAFI_MULTICAST);
}
#endif /* HAVE_IPV6 */
-
+
static int
bgp_show_prefix_longer (struct vty *vty, const char *prefix, afi_t afi,
safi_t safi, enum bgp_show_type type)
@@ -9051,7 +9849,7 @@ DEFUN (show_ipv6_mbgp_prefix_longer,
#endif /* HAVE_IPV6 */
static struct peer *
-peer_lookup_in_view (struct vty *vty, const char *view_name,
+peer_lookup_in_view (struct vty *vty, const char *view_name,
const char *ip_str)
{
int ret;
@@ -9067,7 +9865,7 @@ peer_lookup_in_view (struct vty *vty, const char *view_name,
{
vty_out (vty, "Can't find BGP view %s%s", view_name, VTY_NEWLINE);
return NULL;
- }
+ }
}
else
{
@@ -9079,7 +9877,7 @@ peer_lookup_in_view (struct vty *vty, const char *view_name,
}
}
- /* Get peer sockunion. */
+ /* Get peer sockunion. */
ret = str2sockunion (ip_str, &su);
if (ret < 0)
{
@@ -9094,10 +9892,10 @@ peer_lookup_in_view (struct vty *vty, const char *view_name,
vty_out (vty, "No such neighbor%s", VTY_NEWLINE);
return NULL;
}
-
+
return peer;
}
-
+
enum bgp_stats
{
BGP_STATS_MAXBITLEN = 0,
@@ -9149,7 +9947,7 @@ ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval)
unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG);
unsigned long res = (newtot * TALLY_SIGFIG) / count;
unsigned long ret = newtot / count;
-
+
if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2))
return ret + 1;
else
@@ -9164,7 +9962,7 @@ bgp_table_stats_walker (struct thread *t)
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;
@@ -9177,7 +9975,7 @@ bgp_table_stats_walker (struct thread *t)
space = IPV6_MAX_BITLEN;
break;
}
-
+
ts->counts[BGP_STATS_MAXBITLEN] = space;
for (rn = top; rn; rn = bgp_route_next (rn))
@@ -9185,13 +9983,13 @@ bgp_table_stats_walker (struct thread *t)
struct bgp_info *ri;
struct bgp_node *prn = rn->parent;
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;
@@ -9201,11 +9999,11 @@ 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 = prn->parent;
-
+
if (prn == NULL || prn == top)
{
ts->counts[BGP_STATS_UNAGGREGATEABLE]++;
@@ -9215,36 +10013,36 @@ bgp_table_stats_walker (struct thread *t)
}
else if (prn->info)
ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++;
-
- for (ri = rn->info; ri; ri = ri->next)
+
+ for (ri = rn->info; ri; ri = ri->info_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]
+ ts->counts[BGP_STATS_ASPATH_AVGHOPS]
= ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT],
ts->counts[BGP_STATS_ASPATH_AVGHOPS],
hops);
@@ -9266,25 +10064,25 @@ 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 for the AFI/SAFI%s", 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
@@ -9301,7 +10099,7 @@ bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi)
vty_out (vty, "%-30s: ", table_stats_strs[i]);
vty_out (vty, "%12.2f",
ts.counts[i] ?
- (float)ts.counts[i] /
+ (float)ts.counts[i] /
(float)ts.counts[BGP_STATS_ASPATH_COUNT]
: 0);
break;
@@ -9309,7 +10107,7 @@ bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi)
vty_out (vty, "%-30s: ", table_stats_strs[i]);
vty_out (vty, "%12.2f",
ts.counts[i] ?
- (float)ts.counts[i] /
+ (float)ts.counts[i] /
(float)ts.counts[BGP_STATS_PREFIXES]
: 0);
break;
@@ -9319,27 +10117,27 @@ bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi)
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] /
+ 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] /
+ 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] /
+ 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;
@@ -9352,7 +10150,7 @@ bgp_table_stats_vty (struct vty *vty, const char *name,
struct bgp *bgp;
afi_t afi;
safi_t safi;
-
+
if (name)
bgp = bgp_lookup_by_name (name);
else
@@ -9454,7 +10252,7 @@ ALIAS (show_bgp_statistics_view,
"Address family\n"
"Address Family modifier\n"
"BGP RIB advertisement statistics\n")
-
+
enum bgp_pcounts
{
PCOUNT_ADJ_IN = 0,
@@ -9496,25 +10294,25 @@ 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)
+
+ for (ain = rn->adj_in; ain; ain = ain->adj_next)
if (ain->peer == peer)
pc->count[PCOUNT_ADJ_IN]++;
- for (ri = rn->info; ri; ri = ri->next)
+ for (ri = rn->info; ri; ri = ri->info_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))
@@ -9527,7 +10325,7 @@ bgp_peer_count_walker (struct thread *t)
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]++;
@@ -9561,28 +10359,28 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi)
{
struct peer_pcounts pcounts = { .peer = peer };
unsigned int i;
-
+
if (!peer || !peer->bgp || !peer->afc[afi][safi]
|| !peer->bgp->rib[afi][safi])
{
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);
-
- vty_out (vty, "Prefix counts for %s, %s%s",
+
+ 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_out (vty, "%sCounts from RIB table walk:%s%s",
VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
for (i = 0; i < PCOUNT_MAX; i++)
@@ -9596,7 +10394,7 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi)
vty_out (vty, "Please report this bug, with the above command output%s",
VTY_NEWLINE);
}
-
+
return CMD_SUCCESS;
}
@@ -9613,10 +10411,10 @@ DEFUN (show_ip_bgp_neighbor_prefix_counts,
{
struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
+ peer = peer_lookup_in_view (vty, NULL, argv[0]);
+ if (! peer)
return CMD_WARNING;
-
+
return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST);
}
@@ -9633,10 +10431,10 @@ DEFUN (show_bgp_ipv6_neighbor_prefix_counts,
{
struct peer *peer;
- peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
+ peer = peer_lookup_in_view (vty, NULL, argv[0]);
+ if (! peer)
return CMD_WARNING;
-
+
return bgp_peer_counts (vty, peer, AFI_IP6, SAFI_UNICAST);
}
@@ -9685,7 +10483,7 @@ DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts,
peer = peer_lookup_in_view (vty, NULL, argv[0]);
if (! peer)
return CMD_WARNING;
-
+
return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MPLS_VPN);
}
@@ -9711,11 +10509,11 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
table = bgp->rib[afi][safi];
output_count = 0;
-
+
if (! in && CHECK_FLAG (peer->af_sflags[afi][safi],
PEER_STATUS_DEFAULT_ORIGINATE))
{
- 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 table version is 0, local router ID is %s%s", safe_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);
@@ -9727,12 +10525,12 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
if (in)
{
- for (ain = rn->adj_in; ain; ain = ain->next)
+ for (ain = rn->adj_in; ain; ain = ain->adj_next)
if (ain->peer == peer)
{
if (header1)
{
- 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 table version is 0, local router ID is %s%s", safe_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;
@@ -9743,7 +10541,7 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
header2 = 0;
}
if (ain->attr)
- {
+ {
route_vty_out_tmp (vty, &rn->p, ain->attr, safi);
output_count++;
}
@@ -9751,12 +10549,12 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
}
else
{
- for (adj = rn->adj_out; adj; adj = adj->next)
+ for (adj = rn->adj_out; adj; adj = adj->adj_next)
if (adj->peer == peer)
{
if (header1)
{
- 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 table version is 0, local router ID is %s%s", safe_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;
@@ -9767,13 +10565,13 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
header2 = 0;
}
if (adj->attr)
- {
+ {
route_vty_out_tmp (vty, &rn->p, adj->attr, safi);
output_count++;
}
}
}
-
+
if (output_count != 0)
vty_out (vty, "%sTotal number of prefixes %ld%s",
VTY_NEWLINE, output_count, VTY_NEWLINE);
@@ -9781,7 +10579,7 @@ show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi,
static int
peer_adj_routes (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, int in)
-{
+{
if (! peer || ! peer->afc[afi][safi])
{
vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE);
@@ -9820,9 +10618,9 @@ DEFUN (show_ip_bgp_view_neighbor_advertised_route,
else
peer = peer_lookup_in_view (vty, NULL, argv[0]);
- if (! peer)
+ if (! peer)
return CMD_WARNING;
-
+
return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 0);
}
@@ -9884,7 +10682,7 @@ DEFUN (show_bgp_view_neighbor_advertised_route,
peer = peer_lookup_in_view (vty, NULL, argv[0]);
if (! peer)
- return CMD_WARNING;
+ return CMD_WARNING;
return peer_adj_routes (vty, peer, AFI_IP6, SAFI_UNICAST, 0);
}
@@ -9949,7 +10747,7 @@ ALIAS (show_bgp_view_neighbor_advertised_route,
"Neighbor to display information about\n"
"Neighbor to display information about\n"
"Display the routes advertised to a BGP neighbor\n")
-
+
ALIAS (show_bgp_view_neighbor_advertised_route,
show_bgp_ipv6_neighbor_advertised_route_cmd,
"show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) advertised-routes",
@@ -9972,7 +10770,7 @@ ALIAS (show_bgp_view_neighbor_advertised_route,
"Neighbor to display information about\n"
"Neighbor to display information about\n"
"Display the routes advertised to a BGP neighbor\n")
-
+
/* old command */
DEFUN (ipv6_mbgp_neighbor_advertised_route,
ipv6_mbgp_neighbor_advertised_route_cmd,
@@ -9989,12 +10787,12 @@ DEFUN (ipv6_mbgp_neighbor_advertised_route,
peer = peer_lookup_in_view (vty, NULL, argv[0]);
if (! peer)
- return CMD_WARNING;
+ return CMD_WARNING;
return peer_adj_routes (vty, peer, AFI_IP6, SAFI_MULTICAST, 0);
}
#endif /* HAVE_IPV6 */
-
+
DEFUN (show_ip_bgp_view_neighbor_received_routes,
show_ip_bgp_view_neighbor_received_routes_cmd,
"show ip bgp view WORD neighbors (A.B.C.D|X:X::X:X) received-routes",
@@ -10051,7 +10849,7 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_routes,
peer = peer_lookup_in_view (vty, NULL, argv[1]);
if (! peer)
return CMD_WARNING;
-
+
if (strncmp (argv[0], "m", 1) == 0)
return peer_adj_routes (vty, peer, AFI_IP, SAFI_MULTICAST, 1);
@@ -10182,7 +10980,7 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_prefix_filter,
prefix_bgp_show_prefix_list (vty, AFI_IP, name);
}
}
- else
+ else
{
sprintf (name, "%s.%d.%d", peer->host, AFI_IP, SAFI_UNICAST);
count = prefix_bgp_show_prefix_list (NULL, AFI_IP, name);
@@ -10321,11 +11119,11 @@ DEFUN (show_bgp_view_neighbor_received_prefix_filter,
/* BGP structure lookup. */
bgp = bgp_lookup_by_name (argv[0]);
if (bgp == NULL)
- {
+ {
vty_out (vty, "Can't find BGP view %s%s", argv[0], VTY_NEWLINE);
return CMD_WARNING;
}
-
+
su = sockunion_str2su (argv[1]);
if (su == NULL)
return CMD_WARNING;
@@ -10359,7 +11157,7 @@ ALIAS (show_bgp_view_neighbor_received_prefix_filter,
"Display information received from a BGP neighbor\n"
"Display the prefixlist filter\n")
#endif /* HAVE_IPV6 */
-
+
static int
bgp_show_neighbor_route (struct vty *vty, struct peer *peer, afi_t afi,
safi_t safi, enum bgp_show_type type)
@@ -10369,7 +11167,7 @@ bgp_show_neighbor_route (struct vty *vty, struct peer *peer, afi_t afi,
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);
}
@@ -10389,7 +11187,7 @@ DEFUN (show_ip_bgp_neighbor_routes,
peer = peer_lookup_in_view (vty, NULL, argv[0]);
if (! peer)
return CMD_WARNING;
-
+
return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
bgp_show_type_neighbor);
}
@@ -10410,7 +11208,7 @@ DEFUN (show_ip_bgp_neighbor_flap,
peer = peer_lookup_in_view (vty, NULL, argv[0]);
if (! peer)
return CMD_WARNING;
-
+
return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
bgp_show_type_flap_neighbor);
}
@@ -10431,7 +11229,7 @@ DEFUN (show_ip_bgp_neighbor_damp,
peer = peer_lookup_in_view (vty, NULL, argv[0]);
if (! peer)
return CMD_WARNING;
-
+
return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_UNICAST,
bgp_show_type_damp_neighbor);
}
@@ -10455,7 +11253,7 @@ DEFUN (show_ip_bgp_ipv4_neighbor_routes,
peer = peer_lookup_in_view (vty, NULL, argv[1]);
if (! peer)
return CMD_WARNING;
-
+
if (strncmp (argv[0], "m", 1) == 0)
return bgp_show_neighbor_route (vty, peer, AFI_IP, SAFI_MULTICAST,
bgp_show_type_neighbor);
@@ -10631,8 +11429,8 @@ DEFUN (show_ip_bgp_view_rsclient_route,
VTY_NEWLINE);
return CMD_WARNING;
}
-
- return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP][SAFI_UNICAST],
+
+ return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP][SAFI_UNICAST],
(argc == 3) ? argv[2] : argv[1],
AFI_IP, SAFI_UNICAST, NULL, 0);
}
@@ -10770,7 +11568,7 @@ DEFUN (show_ip_bgp_view_rsclient_prefix,
if (! peer)
return CMD_WARNING;
-
+
if (! peer->afc[AFI_IP][SAFI_UNICAST])
{
vty_out (vty, "%% Activate the neighbor for the address family first%s",
@@ -10785,8 +11583,8 @@ DEFUN (show_ip_bgp_view_rsclient_prefix,
VTY_NEWLINE);
return CMD_WARNING;
}
-
- return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP][SAFI_UNICAST],
+
+ return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP][SAFI_UNICAST],
(argc == 3) ? argv[2] : argv[1],
AFI_IP, SAFI_UNICAST, NULL, 1);
}
@@ -10901,7 +11699,7 @@ DEFUN (show_bgp_view_neighbor_routes,
peer = peer_lookup_in_view (vty, argv[0], argv[1]);
else
peer = peer_lookup_in_view (vty, NULL, argv[0]);
-
+
if (! peer)
return CMD_WARNING;
@@ -10999,7 +11797,7 @@ ALIAS (show_bgp_view_neighbor_flap,
"Neighbor to display information about\n"
"Neighbor to display information about\n"
"Display flap statistics of the routes learned from neighbor\n")
-
+
ALIAS (show_bgp_view_neighbor_routes,
show_bgp_neighbor_routes_cmd,
"show bgp neighbors (A.B.C.D|X:X::X:X) routes",
@@ -11051,7 +11849,7 @@ DEFUN (ipv6_mbgp_neighbor_routes,
peer = peer_lookup_in_view (vty, NULL, argv[0]);
if (! peer)
return CMD_WARNING;
-
+
return bgp_show_neighbor_route (vty, peer, AFI_IP6, SAFI_MULTICAST,
bgp_show_type_neighbor);
}
@@ -11511,7 +12309,7 @@ ALIAS (show_bgp_view_ipv6_safi_rsclient_prefix,
"IP prefix <network>/<length>, e.g., 3ffe::/16\n")
#endif /* HAVE_IPV6 */
-
+
struct bgp_table *bgp_distance_table;
struct bgp_distance
@@ -11536,7 +12334,7 @@ bgp_distance_free (struct bgp_distance *bdistance)
}
static int
-bgp_distance_set (struct vty *vty, const char *distance_str,
+bgp_distance_set (struct vty *vty, const char *distance_str,
const char *ip_str, const char *access_list_str)
{
int ret;
@@ -11583,7 +12381,7 @@ bgp_distance_set (struct vty *vty, const char *distance_str,
}
static int
-bgp_distance_unset (struct vty *vty, const char *distance_str,
+bgp_distance_unset (struct vty *vty, const char *distance_str,
const char *ip_str, const char *access_list_str)
{
int ret;
@@ -11788,7 +12586,7 @@ DEFUN (no_bgp_distance_source_access_list,
bgp_distance_unset (vty, argv[0], argv[1], argv[2]);
return CMD_SUCCESS;
}
-
+
DEFUN (bgp_damp_set,
bgp_damp_set_cmd,
"bgp dampening <1-45> <1-20000> <1-20000> <1-255>",
@@ -11883,11 +12681,11 @@ DEFUN (show_ip_bgp_flap_statistics,
return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST,
bgp_show_type_flap_statistics, NULL);
}
-
+
/* 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,
+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;
@@ -11931,14 +12729,15 @@ bgp_clear_damp_route (struct vty *vty, const char *view_name,
if (safi == SAFI_MPLS_VPN)
{
- for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); rn; rn = bgp_route_next (rn))
+ for (rn = bgp_table_top (bgp->rib[AFI_IP][SAFI_MPLS_VPN]); 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;
@@ -11946,17 +12745,16 @@ bgp_clear_damp_route (struct vty *vty, const char *view_name,
{
if (ri->extra && ri->extra->damp_info)
{
- ri_temp = ri->next;
+ ri_temp = ri->info_next;
bgp_damp_info_free (ri->extra->damp_info, 1);
ri = ri_temp;
}
else
- ri = ri->next;
+ ri = ri->info_next;
}
}
-
bgp_unlock_node (rm);
- }
+ }
}
}
else
@@ -11970,15 +12768,14 @@ bgp_clear_damp_route (struct vty *vty, const char *view_name,
{
if (ri->extra && ri->extra->damp_info)
{
- ri_temp = ri->next;
+ ri_temp = ri->info_next;
bgp_damp_info_free (ri->extra->damp_info, 1);
ri = ri_temp;
}
else
- ri = ri->next;
+ ri = ri->info_next;
}
}
-
bgp_unlock_node (rn);
}
}
@@ -12047,7 +12844,7 @@ DEFUN (clear_ip_bgp_dampening_address_mask,
return bgp_clear_damp_route (vty, NULL, prefix_str, AFI_IP,
SAFI_UNICAST, NULL, 0);
}
-
+
static int
bgp_config_write_network_vpnv4 (struct vty *vty, struct bgp *bgp,
afi_t afi, safi_t safi, int *write)
@@ -12061,11 +12858,11 @@ bgp_config_write_network_vpnv4 (struct vty *vty, struct bgp *bgp,
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))
+ for (rn = bgp_table_top (table); rn; rn = bgp_route_next (rn))
if ((bgp_static = rn->info) != NULL)
{
p = &rn->p;
@@ -12079,7 +12876,7 @@ bgp_config_write_network_vpnv4 (struct vty *vty, struct bgp *bgp,
label = decode_label (bgp_static->tag);
vty_out (vty, " network %s/%d rd %s tag %d",
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
p->prefixlen,
rdbuf, label);
vty_out (vty, "%s", VTY_NEWLINE);
@@ -12098,12 +12895,12 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp,
struct bgp_static *bgp_static;
struct bgp_aggregate *bgp_aggregate;
char buf[SU_ADDRSTRLEN];
-
+
if (afi == AFI_IP && safi == SAFI_MPLS_VPN)
return bgp_config_write_network_vpnv4 (vty, bgp, afi, safi, write);
/* Network configuration. */
- for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
+ for (rn = bgp_table_top (bgp->route[afi][safi]); rn; rn = bgp_route_next (rn))
if ((bgp_static = rn->info) != NULL)
{
p = &rn->p;
@@ -12114,7 +12911,7 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp,
/* "network" configuration display. */
if (bgp_option_check (BGP_OPT_CONFIG_CISCO) && afi == AFI_IP)
{
- u_int32_t destination;
+ u_int32_t destination;
struct in_addr netmask;
destination = ntohl (p->u.prefix4.s_addr);
@@ -12130,18 +12927,18 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp,
/* Natural mask is not display. */
}
else
- vty_out (vty, " mask %s", inet_ntoa (netmask));
+ vty_out (vty, " mask %s", safe_inet_ntoa (netmask));
}
else
{
vty_out (vty, " network %s/%d",
- inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
+ 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
+ else
{
if (bgp_static->backdoor)
vty_out (vty, " backdoor");
@@ -12166,7 +12963,7 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp,
masklen2ip (p->prefixlen, &netmask);
vty_out (vty, " aggregate-address %s %s",
inet_ntop (p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
- inet_ntoa (netmask));
+ safe_inet_ntoa (netmask));
}
else
{
@@ -12177,7 +12974,7 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp,
if (bgp_aggregate->as_set)
vty_out (vty, " as-set");
-
+
if (bgp_aggregate->summary_only)
vty_out (vty, " summary-only");
@@ -12203,12 +13000,12 @@ bgp_config_write_distance (struct vty *vty, struct bgp *bgp)
vty_out (vty, " distance bgp %d %d %d%s",
bgp->distance_ebgp, bgp->distance_ibgp, bgp->distance_local,
VTY_NEWLINE);
-
+
for (rn = bgp_table_top (bgp_distance_table); rn; rn = bgp_route_next (rn))
if ((bdistance = rn->info) != NULL)
{
vty_out (vty, " distance %d %s/%d %s%s", bdistance->distance,
- inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
+ safe_inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
bdistance->access_list ? bdistance->access_list : "",
VTY_NEWLINE);
}
@@ -12277,7 +13074,7 @@ bgp_route_init (void)
install_element (BGP_IPV4_NODE, &no_bgp_network_route_map_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_route_map_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_route_map_cmd);
-
+
install_element (BGP_IPV4_NODE, &aggregate_address_cmd);
install_element (BGP_IPV4_NODE, &aggregate_address_mask_cmd);
install_element (BGP_IPV4_NODE, &aggregate_address_summary_only_cmd);
@@ -12312,6 +13109,7 @@ bgp_route_init (void)
install_element (BGP_IPV4M_NODE, &no_bgp_network_route_map_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_route_map_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_route_map_cmd);
+
install_element (BGP_IPV4M_NODE, &aggregate_address_cmd);
install_element (BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
install_element (BGP_IPV4M_NODE, &aggregate_address_summary_only_cmd);
@@ -12423,7 +13221,7 @@ bgp_route_init (void)
install_element (VIEW_NODE, &show_bgp_view_ipv4_safi_rsclient_route_cmd);
install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_prefix_cmd);
install_element (VIEW_NODE, &show_bgp_view_ipv4_safi_rsclient_prefix_cmd);
-
+
/* Restricted node: VIEW_NODE - (set of dangerous commands) */
install_element (RESTRICTED_NODE, &show_ip_bgp_route_cmd);
install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_route_cmd);
@@ -12666,16 +13464,16 @@ bgp_route_init (void)
install_element (VIEW_NODE, &show_bgp_view_neighbor_flap_cmd);
install_element (VIEW_NODE, &show_bgp_view_ipv6_neighbor_flap_cmd);
install_element (VIEW_NODE, &show_bgp_view_neighbor_damp_cmd);
- install_element (VIEW_NODE, &show_bgp_view_ipv6_neighbor_damp_cmd);
+ install_element (VIEW_NODE, &show_bgp_view_ipv6_neighbor_damp_cmd);
install_element (VIEW_NODE, &show_bgp_view_rsclient_cmd);
install_element (VIEW_NODE, &show_bgp_view_ipv6_safi_rsclient_cmd);
install_element (VIEW_NODE, &show_bgp_view_rsclient_route_cmd);
install_element (VIEW_NODE, &show_bgp_view_ipv6_safi_rsclient_route_cmd);
install_element (VIEW_NODE, &show_bgp_view_rsclient_prefix_cmd);
install_element (VIEW_NODE, &show_bgp_view_ipv6_safi_rsclient_prefix_cmd);
-
+
/* Restricted:
- * VIEW_NODE - (set of dangerous commands) - (commands dependent on prev)
+ * VIEW_NODE - (set of dangerous commands) - (commands dependent on prev)
*/
install_element (RESTRICTED_NODE, &show_bgp_route_cmd);
install_element (RESTRICTED_NODE, &show_bgp_ipv6_route_cmd);
@@ -12797,13 +13595,13 @@ bgp_route_init (void)
install_element (ENABLE_NODE, &show_bgp_view_ipv6_safi_rsclient_route_cmd);
install_element (ENABLE_NODE, &show_bgp_view_rsclient_prefix_cmd);
install_element (ENABLE_NODE, &show_bgp_view_ipv6_safi_rsclient_prefix_cmd);
-
+
/* Statistics */
install_element (ENABLE_NODE, &show_bgp_statistics_cmd);
install_element (ENABLE_NODE, &show_bgp_statistics_vpnv4_cmd);
install_element (ENABLE_NODE, &show_bgp_statistics_view_cmd);
install_element (ENABLE_NODE, &show_bgp_statistics_view_vpnv4_cmd);
-
+
/* old command */
install_element (VIEW_NODE, &show_ipv6_bgp_cmd);
install_element (VIEW_NODE, &show_ipv6_bgp_route_cmd);
@@ -12841,7 +13639,7 @@ bgp_route_init (void)
install_element (VIEW_NODE, &show_ipv6_mbgp_community_list_cmd);
install_element (VIEW_NODE, &show_ipv6_mbgp_community_list_exact_cmd);
install_element (VIEW_NODE, &show_ipv6_mbgp_prefix_longer_cmd);
-
+
/* old command */
install_element (ENABLE_NODE, &show_ipv6_bgp_cmd);
install_element (ENABLE_NODE, &show_ipv6_bgp_route_cmd);
@@ -12917,7 +13715,7 @@ bgp_route_init (void)
install_element (BGP_IPV4_NODE, &bgp_damp_set3_cmd);
install_element (BGP_IPV4_NODE, &bgp_damp_unset_cmd);
install_element (BGP_IPV4_NODE, &bgp_damp_unset2_cmd);
-
+
/* Deprecated AS-Pathlimit commands */
install_element (BGP_NODE, &bgp_network_ttl_cmd);
install_element (BGP_NODE, &bgp_network_mask_ttl_cmd);
@@ -12925,35 +13723,35 @@ bgp_route_init (void)
install_element (BGP_NODE, &bgp_network_backdoor_ttl_cmd);
install_element (BGP_NODE, &bgp_network_mask_backdoor_ttl_cmd);
install_element (BGP_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd);
-
+
install_element (BGP_NODE, &no_bgp_network_ttl_cmd);
install_element (BGP_NODE, &no_bgp_network_mask_ttl_cmd);
install_element (BGP_NODE, &no_bgp_network_mask_natural_ttl_cmd);
install_element (BGP_NODE, &no_bgp_network_backdoor_ttl_cmd);
install_element (BGP_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
install_element (BGP_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd);
-
+
install_element (BGP_IPV4_NODE, &bgp_network_ttl_cmd);
install_element (BGP_IPV4_NODE, &bgp_network_mask_ttl_cmd);
install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_ttl_cmd);
install_element (BGP_IPV4_NODE, &bgp_network_backdoor_ttl_cmd);
install_element (BGP_IPV4_NODE, &bgp_network_mask_backdoor_ttl_cmd);
install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd);
-
+
install_element (BGP_IPV4_NODE, &no_bgp_network_ttl_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_ttl_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_ttl_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_backdoor_ttl_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_backdoor_ttl_cmd);
install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd);
-
+
install_element (BGP_IPV4M_NODE, &bgp_network_ttl_cmd);
install_element (BGP_IPV4M_NODE, &bgp_network_mask_ttl_cmd);
install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_ttl_cmd);
install_element (BGP_IPV4M_NODE, &bgp_network_backdoor_ttl_cmd);
install_element (BGP_IPV4M_NODE, &bgp_network_mask_backdoor_ttl_cmd);
install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_backdoor_ttl_cmd);
-
+
install_element (BGP_IPV4M_NODE, &no_bgp_network_ttl_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_ttl_cmd);
install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_ttl_cmd);