diff options
Diffstat (limited to 'bgpd')
-rw-r--r-- | bgpd/bgp_aspath.c | 118 | ||||
-rw-r--r-- | bgpd/bgp_aspath.h | 2 | ||||
-rw-r--r-- | bgpd/bgp_attr.c | 287 | ||||
-rw-r--r-- | bgpd/bgp_attr.h | 6 | ||||
-rw-r--r-- | bgpd/bgp_damp.c | 6 | ||||
-rw-r--r-- | bgpd/bgp_debug.c | 7 | ||||
-rw-r--r-- | bgpd/bgp_dump.c | 4 | ||||
-rw-r--r-- | bgpd/bgp_main.c | 10 | ||||
-rw-r--r-- | bgpd/bgp_network.c | 20 | ||||
-rw-r--r-- | bgpd/bgp_nexthop.c | 22 | ||||
-rw-r--r-- | bgpd/bgp_open.h | 8 | ||||
-rw-r--r-- | bgpd/bgp_packet.c | 140 | ||||
-rw-r--r-- | bgpd/bgp_route.c | 1621 | ||||
-rw-r--r-- | bgpd/bgp_route.h | 3 | ||||
-rw-r--r-- | bgpd/bgp_routemap.c | 128 | ||||
-rw-r--r-- | bgpd/bgp_table.c | 1 | ||||
-rw-r--r-- | bgpd/bgp_vty.c | 225 | ||||
-rw-r--r-- | bgpd/bgpd.c | 173 | ||||
-rw-r--r-- | bgpd/bgpd.h | 8 |
19 files changed, 1875 insertions, 914 deletions
diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index a9602d90..cf930427 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -671,58 +671,80 @@ aspath_hash_alloc (void *arg) return aspath; } -/* parse as-segment byte stream in struct assegment */ +/* parse as-segment byte stream in struct assegment + * + * Returns NULL if the AS_PATH or AS4_PATH is not valid. + */ static struct assegment * -assegments_parse (struct stream *s, size_t length, int use32bit) +assegments_parse (struct stream *s, size_t length, int use32bit, int as4_path) { struct assegment_header segh; struct assegment *seg, *prev = NULL, *head = NULL; - size_t bytes = 0; - /* empty aspath (ie iBGP or somesuch) */ - if (length == 0) - return NULL; + assert (length > 0); /* does not expect empty AS_PATH or AS4_PATH */ if (BGP_DEBUG (as4, AS4_SEGMENT)) zlog_debug ("[AS4SEG] Parse aspath segment: got total byte length %lu", (unsigned long) length); - /* basic checks */ - if ( (STREAM_READABLE(s) < length) - || (STREAM_READABLE(s) < AS_HEADER_SIZE) - || (length % AS16_VALUE_SIZE )) + + /* double check that length does not exceed stream */ + if (STREAM_READABLE(s) < length) return NULL; - while ( (STREAM_READABLE(s) > AS_HEADER_SIZE) - && (bytes < length)) + /* deal with each segment in turn */ + while (length > 0) { int i; - int seg_size; + size_t seg_size; /* softly softly, get the header first on its own */ + if (length < AS_HEADER_SIZE) + { + assegment_free_all (head); + return NULL; + } + segh.type = stream_getc (s); segh.length = stream_getc (s); seg_size = ASSEGMENT_SIZE(segh.length, use32bit); + /* includes the header bytes */ if (BGP_DEBUG (as4, AS4_SEGMENT)) zlog_debug ("[AS4SEG] Parse aspath segment: got type %d, length %d", segh.type, segh.length); - /* check it.. */ - if ( ((bytes + seg_size) > length) - /* 1771bis 4.3b: seg length contains one or more */ - || (segh.length == 0) - /* Paranoia in case someone changes type of segment length. - * Shift both values by 0x10 to make the comparison operate - * on more, than 8 bits (otherwise it's a warning, bug #564). + switch (segh.type) + { + case AS_SEQUENCE: + case AS_SET: + break ; + + case AS_CONFED_SEQUENCE: + case AS_CONFED_SET: + if (!as4_path) + break ; + /* RFC4893 3: "invalid for the AS4_PATH attribute" */ + /* fall through */ + + default: /* reject unknown or invalid AS_PATH segment types */ + seg_size = 0 ; + } + + /* Stop now if segment is not valid (discarding anything collected to date) + * + * RFC4271 4.3, Path Attributes, b) AS_PATH: + * + * "path segment value field contains one or more AS numbers" */ - || ((sizeof segh.length > 1) && (0x10 + segh.length > 0x10 + AS_SEGMENT_MAX)) ) + if ((seg_size == 0) || (seg_size > length) || (segh.length == 0)) { - if (head) - assegment_free_all (head); + assegment_free_all (head); return NULL; } + length -= seg_size ; + /* now its safe to trust lengths */ seg = assegment_new (segh.type, segh.length); @@ -734,11 +756,9 @@ assegments_parse (struct stream *s, size_t length, int use32bit) for (i = 0; i < segh.length; i++) seg->as[i] = (use32bit) ? stream_getl (s) : stream_getw (s); - bytes += seg_size; - if (BGP_DEBUG (as4, AS4_SEGMENT)) - zlog_debug ("[AS4SEG] Parse aspath segment: Bytes now: %lu", - (unsigned long) bytes); + zlog_debug ("[AS4SEG] Parse aspath segment: length left: %lu", + (unsigned long) length); prev = seg; } @@ -746,30 +766,42 @@ assegments_parse (struct stream *s, size_t length, int use32bit) return assegment_normalise (head); } -/* AS path parse function. pnt is a pointer to byte stream and length - is length of byte stream. If there is same AS path in the the AS - path hash then return it else make new AS path structure. */ +/* AS path parse function -- parses AS_PATH and AS4_PATH attributes + * + * Requires: s -- stream, currently positioned before first segment + * of AS_PATH or AS4_PATH (ie after attribute header) + * length -- length of the value of the AS_PATH or AS4_PATH + * use32bit -- true <=> 4Byte ASN, otherwise 2Byte ASN + * as4_path -- true <=> AS4_PATH, otherwise AS_PATH + * + * Returns: if valid: address of struct aspath in the hash of known aspaths, + * with reference count incremented. + * else: NULL + * + * NB: empty AS path (length == 0) is valid. The returned struct aspath will + * have segments == NULL and str == zero length string (unique). + */ struct aspath * -aspath_parse (struct stream *s, size_t length, int use32bit) +aspath_parse (struct stream *s, size_t length, int use32bit, int as4_path) { struct aspath as; struct aspath *find; - /* If length is odd it's malformed AS path. */ - /* Nit-picking: if (use32bit == 0) it is malformed if odd, - * otherwise its malformed when length is larger than 2 and (length-2) - * is not dividable by 4. - * But... this time we're lazy - */ - if (length % AS16_VALUE_SIZE ) - return NULL; - + /* Parse each segment and construct normalised list of struct assegment */ memset (&as, 0, sizeof (struct aspath)); - as.segments = assegments_parse (s, length, use32bit); + if (length != 0) + { + as.segments = assegments_parse (s, length, use32bit, as4_path); + + if (as.segments == NULL) + return NULL ; /* Invalid AS_PATH or AS4_PATH */ + } ; /* If already same aspath exist then return it. */ find = hash_get (ashash, &as, aspath_hash_alloc); + assert(find) ; /* valid aspath, so must find or create */ + /* aspath_hash_alloc dupes segments too. that probably could be * optimised out. */ @@ -777,8 +809,6 @@ aspath_parse (struct stream *s, size_t length, int use32bit) if (as.str) XFREE (MTYPE_AS_STR, as.str); - if (! find) - return NULL; find->refcnt++; return find; @@ -1602,7 +1632,7 @@ aspath_segment_add (struct aspath *as, int type) struct aspath * aspath_empty (void) { - return aspath_parse (NULL, 0, 1); /* 32Bit ;-) */ + return aspath_parse (NULL, 0, 1, 0); /* 32Bit ;-) not AS4_PATH */ } struct aspath * diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h index b8a5dfab..d63b914c 100644 --- a/bgpd/bgp_aspath.h +++ b/bgpd/bgp_aspath.h @@ -65,7 +65,7 @@ struct aspath /* Prototypes. */ extern void aspath_init (void); extern void aspath_finish (void); -extern struct aspath *aspath_parse (struct stream *, size_t, int); +extern struct aspath *aspath_parse (struct stream *, size_t, int, int); extern struct aspath *aspath_dup (struct aspath *); extern struct aspath *aspath_aggregate (struct aspath *, struct aspath *); extern struct aspath *aspath_prepend (struct aspath *, struct aspath *); diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index 5e7536ae..01598c87 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -28,6 +28,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "stream.h" #include "log.h" #include "hash.h" +#include "jhash.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_attr.h" @@ -116,18 +117,9 @@ cluster_loop_check (struct cluster_list *cluster, struct in_addr originator) static unsigned int cluster_hash_key_make (void *p) { - struct cluster_list * cluster = (struct cluster_list *) p; - unsigned int key = 0; - int length; - caddr_t pnt; + const struct cluster_list *cluster = p; - length = cluster->length; - pnt = (caddr_t) cluster->list; - - while (length) - key += pnt[--length]; - - return key; + return jhash(cluster->list, cluster->length, 0); } static int @@ -258,18 +250,9 @@ transit_unintern (struct transit *transit) static unsigned int transit_hash_key_make (void *p) { - struct transit * transit = (struct transit *) p; - unsigned int key = 0; - int length; - caddr_t pnt; + const struct transit * transit = p; - length = transit->length; - pnt = (caddr_t) transit->val; - - while (length) - key += pnt[--length]; - - return key; + return jhash(transit->val, transit->length, 0); } static int @@ -352,51 +335,46 @@ attr_unknown_count (void) unsigned int attrhash_key_make (void *p) { - struct attr * attr = (struct attr *) p; - unsigned int key = 0; + const struct attr * attr = (struct attr *) p; + uint32_t key = 0; +#define MIX(val) key = jhash_1word(val, key) + + MIX(attr->origin); + MIX(attr->nexthop.s_addr); + MIX(attr->med); + MIX(attr->local_pref); key += attr->origin; key += attr->nexthop.s_addr; key += attr->med; key += attr->local_pref; - if (attr->pathlimit.as) - { - key += attr->pathlimit.ttl; - key += attr->pathlimit.as; - } if (attr->extra) { - key += attr->extra->aggregator_as; - key += attr->extra->aggregator_addr.s_addr; - key += attr->extra->weight; - key += attr->extra->mp_nexthop_global_in.s_addr; + MIX(attr->extra->aggregator_as); + MIX(attr->extra->aggregator_addr.s_addr); + MIX(attr->extra->weight); + MIX(attr->extra->mp_nexthop_global_in.s_addr); } if (attr->aspath) - key += aspath_key_make (attr->aspath); + MIX(aspath_key_make (attr->aspath)); if (attr->community) - key += community_hash_make (attr->community); + MIX(community_hash_make (attr->community)); if (attr->extra) { if (attr->extra->ecommunity) - key += ecommunity_hash_make (attr->extra->ecommunity); + MIX(ecommunity_hash_make (attr->extra->ecommunity)); if (attr->extra->cluster) - key += cluster_hash_key_make (attr->extra->cluster); + MIX(cluster_hash_key_make (attr->extra->cluster)); if (attr->extra->transit) - key += transit_hash_key_make (attr->extra->transit); + MIX(transit_hash_key_make (attr->extra->transit)); #ifdef HAVE_IPV6 - { - int i; - - key += attr->extra->mp_nexthop_len; - for (i = 0; i < 16; i++) - key += attr->extra->mp_nexthop_global.s6_addr[i]; - for (i = 0; i < 16; i++) - key += attr->extra->mp_nexthop_local.s6_addr[i]; - } + MIX(attr->extra->mp_nexthop_len); + key = jhash(attr->extra->mp_nexthop_global.s6_addr, 16, key); + key = jhash(attr->extra->mp_nexthop_local.s6_addr, 16, key); #endif /* HAVE_IPV6 */ } @@ -415,9 +393,7 @@ attrhash_cmp (const void *p1, const void *p2) && attr1->aspath == attr2->aspath && attr1->community == attr2->community && attr1->med == attr2->med - && attr1->local_pref == attr2->local_pref - && attr1->pathlimit.ttl == attr2->pathlimit.ttl - && attr1->pathlimit.as == attr2->pathlimit.as) + && attr1->local_pref == attr2->local_pref) { const struct attr_extra *ae1 = attr1->extra; const struct attr_extra *ae2 = attr2->extra; @@ -704,43 +680,6 @@ bgp_attr_flush (struct attr *attr) } } -/* Parse AS_PATHLIMIT attribute in an UPDATE */ -static int -bgp_attr_aspathlimit (struct peer *peer, bgp_size_t length, - struct attr *attr, u_char flag, u_char *startp) -{ - bgp_size_t total; - - total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); - - if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS) - || !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) - { - zlog (peer->log, LOG_ERR, - "AS-Pathlimit attribute flag isn't transitive %d", flag); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } - - if (length != 5) - { - zlog (peer->log, LOG_ERR, - "AS-Pathlimit length, %u, is not 5", length); - bgp_notify_send_with_data (peer, - BGP_NOTIFY_UPDATE_ERR, - BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, - startp, total); - return -1; - } - - attr->pathlimit.ttl = stream_getc (BGP_INPUT(peer)); - attr->pathlimit.as = stream_getl (BGP_INPUT(peer)); - attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT); - return 0; -} /* Get origin attribute of the update message. */ static int bgp_attr_origin (struct peer *peer, bgp_size_t length, @@ -807,54 +746,78 @@ bgp_attr_origin (struct peer *peer, bgp_size_t length, return 0; } - -/* Parse AS path information. This function is wrapper of - aspath_parse. */ -static int +/* Parse AS path information. This function is wrapper of aspath_parse. + * + * Parses AS_PATH or AS4_PATH. + * + * Returns: if valid: address of struct aspath in the hash of known aspaths, + * with reference count incremented. + * else: NULL + * + * NB: empty AS path (length == 0) is valid. The returned struct aspath will + * have segments == NULL and str == zero length string (unique). + */ +static struct aspath * bgp_attr_aspath (struct peer *peer, bgp_size_t length, - struct attr *attr, u_char flag, u_char *startp) + struct attr *attr, u_char flag, u_char *startp, int as4_path) { - bgp_size_t total; + u_char require ; + struct aspath *asp ; - total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); + /* Check the attribute flags */ + require = as4_path ? BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS + : BGP_ATTR_FLAG_TRANS ; - /* Flag check. */ - if (CHECK_FLAG (flag, BGP_ATTR_FLAG_OPTIONAL) - || ! CHECK_FLAG (flag, BGP_ATTR_FLAG_TRANS)) + if ((flag & (BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS)) != require) { + const char* path_type ; + bgp_size_t total; + + path_type = as4_path ? "AS4_PATH" : "AS_PATH" ; + + if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)) zlog (peer->log, LOG_ERR, - "As-Path attribute flag isn't transitive %d", flag); + "%s attribute flag isn't transitive %d", path_type, flag) ; + + if ((flag & BGP_ATTR_FLAG_OPTIONAL) != (require & BGP_ATTR_FLAG_OPTIONAL)) + zlog (peer->log, LOG_ERR, + "%s attribute flag must %sbe optional %d", path_type, + (flag & BGP_ATTR_FLAG_OPTIONAL) ? "not " : "", flag) ; + + total = length + (CHECK_FLAG (flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); + bgp_notify_send_with_data (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, startp, total); - return -1; - } - /* - * peer with AS4 => will get 4Byte ASnums - * otherwise, will get 16 Bit + return NULL ; + } ; + + /* Parse the AS_PATH/AS4_PATH body. + * + * For AS_PATH peer with AS4 => 4Byte ASN otherwise 2Byte ASN + * AS4_PATH 4Byte ASN */ - attr->aspath = aspath_parse (peer->ibuf, length, - CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV)); + asp = aspath_parse (peer->ibuf, length, + as4_path || CHECK_FLAG (peer->cap, PEER_CAP_AS4_RCV), as4_path) ; - /* In case of IBGP, length will be zero. */ - if (! attr->aspath) + if (asp != NULL) + { + attr->flag |= ATTR_FLAG_BIT (as4_path ? BGP_ATTR_AS4_PATH + : BGP_ATTR_AS_PATH) ; + } + else { zlog (peer->log, LOG_ERR, "Malformed AS path length is %d", length); + + /* TODO: should BGP_NOTIFY_UPDATE_MAL_AS_PATH be sent for AS4_PATH ?? */ bgp_notify_send (peer, BGP_NOTIFY_UPDATE_ERR, BGP_NOTIFY_UPDATE_MAL_AS_PATH); - return -1; - } - - /* Forward pointer. */ -/* stream_forward_getp (peer->ibuf, length);*/ - - /* Set aspath attribute flag. */ - attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATH); + } ; - return 0; + return asp ; } static int bgp_attr_aspath_check( struct peer *peer, @@ -912,21 +875,6 @@ static int bgp_attr_aspath_check( struct peer *peer, } -/* Parse AS4 path information. This function is another wrapper of - aspath_parse. */ -static int -bgp_attr_as4_path (struct peer *peer, bgp_size_t length, - struct attr *attr, struct aspath **as4_path) -{ - *as4_path = aspath_parse (peer->ibuf, length, 1); - - /* Set aspath attribute flag. */ - if (as4_path) - attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS4_PATH); - - return 0; -} - /* Nexthop attribute. */ static int bgp_attr_nexthop (struct peer *peer, bgp_size_t length, @@ -1226,13 +1174,16 @@ bgp_attr_community (struct peer *peer, bgp_size_t length, attr->community = NULL; return 0; } - else - { - attr->community = - community_parse ((u_int32_t *)stream_pnt (peer->ibuf), length); - stream_forward_getp (peer->ibuf, length); - } + + attr->community = + community_parse ((u_int32_t *)stream_pnt (peer->ibuf), length); + + /* XXX: fix community_parse to use stream API and remove this */ + stream_forward_getp (peer->ibuf, length); + if (!attr->community) + return -1; + attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES); return 0; @@ -1292,8 +1243,8 @@ int bgp_mp_reach_parse (struct peer *peer, bgp_size_t length, struct attr *attr, struct bgp_nlri *mp_update) { - u_int16_t afi; - u_char safi; + afi_t afi; + safi_t safi; bgp_size_t nlri_len; size_t start; int ret; @@ -1427,8 +1378,8 @@ bgp_mp_unreach_parse (struct peer *peer, bgp_size_t length, struct bgp_nlri *mp_withdraw) { struct stream *s; - u_int16_t afi; - u_char safi; + afi_t afi; + safi_t safi; u_int16_t withdraw_len; int ret; @@ -1469,13 +1420,18 @@ bgp_attr_ext_communities (struct peer *peer, bgp_size_t length, { if (attr->extra) attr->extra->ecommunity = NULL; + /* Empty extcomm doesn't seem to be invalid per se */ + return 0; } - else - { - (bgp_attr_extra_get (attr))->ecommunity = - ecommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length); - stream_forward_getp (peer->ibuf, length); - } + + (bgp_attr_extra_get (attr))->ecommunity = + ecommunity_parse ((u_int8_t *)stream_pnt (peer->ibuf), length); + /* XXX: fix ecommunity_parse to use stream API */ + stream_forward_getp (peer->ibuf, length); + + if (!attr->extra->ecommunity) + return -1; + attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES); return 0; @@ -1657,10 +1613,12 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, ret = bgp_attr_origin (peer, length, attr, flag, startp); break; case BGP_ATTR_AS_PATH: - ret = bgp_attr_aspath (peer, length, attr, flag, startp); + attr->aspath = bgp_attr_aspath (peer, length, attr, flag, startp, 0); + ret = attr->aspath ? 0 : -1 ; break; case BGP_ATTR_AS4_PATH: - ret = bgp_attr_as4_path (peer, length, attr, &as4_path ); + as4_path = bgp_attr_aspath (peer, length, attr, flag, startp, 1); + ret = as4_path ? 0 : -1 ; break; case BGP_ATTR_NEXT_HOP: ret = bgp_attr_nexthop (peer, length, attr, flag, startp); @@ -1698,9 +1656,6 @@ bgp_attr_parse (struct peer *peer, struct attr *attr, bgp_size_t size, case BGP_ATTR_EXT_COMMUNITIES: ret = bgp_attr_ext_communities (peer, length, attr, flag); break; - case BGP_ATTR_AS_PATHLIMIT: - ret = bgp_attr_aspathlimit (peer, length, attr, flag, startp); - break; default: ret = bgp_attr_unknown (peer, attr, flag, type, length, startp); break; @@ -2255,24 +2210,6 @@ bgp_packet_attribute (struct bgp *bgp, struct peer *peer, stream_put_ipv4 (s, attr->extra->aggregator_addr.s_addr); } - /* AS-Pathlimit */ - if (attr->pathlimit.ttl) - { - u_int32_t as = attr->pathlimit.as; - - /* should already have been done in announce_check(), - * but just in case.. - */ - if (!as) - as = peer->local_as; - - stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); - stream_putc (s, BGP_ATTR_AS_PATHLIMIT); - stream_putc (s, 5); - stream_putc (s, attr->pathlimit.ttl); - stream_putl (s, as); - } - /* Unknown transit attribute. */ if (attr->extra && attr->extra->transit) stream_put (s, attr->extra->transit->val, attr->extra->transit->length); @@ -2484,16 +2421,6 @@ bgp_dump_routes_attr (struct stream *s, struct attr *attr, } #endif /* HAVE_IPV6 */ - /* AS-Pathlimit */ - if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT)) - { - stream_putc (s, BGP_ATTR_FLAG_OPTIONAL|BGP_ATTR_FLAG_TRANS); - stream_putc (s, BGP_ATTR_AS_PATHLIMIT); - stream_putc (s, 5); - stream_putc (s, attr->pathlimit.ttl); - stream_putl (s, attr->pathlimit.as); - } - /* Return total size of attribute. */ len = stream_get_endp (s) - cp - 2; stream_putw_at (s, cp, len); diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index ed8753bd..af9dcf5e 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -110,12 +110,6 @@ struct attr u_int32_t med; u_int32_t local_pref; - /* AS-Pathlimit */ - struct { - u_int32_t as; - u_char ttl; - } pathlimit; - /* Path origin attribute */ u_char origin; }; diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index ba059f8c..a5138833 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -407,14 +407,10 @@ bgp_damp_parameter_set (int hlife, int reuse, int sup, int maxsup) damp->reuse_list = XCALLOC (MTYPE_BGP_DAMP_ARRAY, damp->reuse_list_size * sizeof (struct bgp_reuse_node *)); - memset (damp->reuse_list, 0x00, - damp->reuse_list_size * sizeof (struct bgp_reuse_node *)); /* Reuse-array computations */ - damp->reuse_index = XMALLOC (MTYPE_BGP_DAMP_ARRAY, + damp->reuse_index = XCALLOC (MTYPE_BGP_DAMP_ARRAY, sizeof(int) * damp->reuse_index_size); - memset (damp->reuse_index, 0x00, - damp->reuse_list_size * sizeof (int)); reuse_max_ratio = (double)damp->ceiling/damp->reuse_limit; j = (exp((double)damp->max_suppress_time/damp->half_life) * log10(2.0)); diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index c2077a59..26b35dfc 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -331,7 +331,6 @@ ALIAS (no_debug_bgp_as4, undebug_bgp_as4_cmd, "undebug bgp as4", UNDEBUG_STR - DEBUG_STR BGP_STR "BGP AS4 actions\n") @@ -340,6 +339,7 @@ DEFUN (debug_bgp_as4_segment, "debug bgp as4 segment", DEBUG_STR BGP_STR + "BGP AS4 actions\n" "BGP AS4 aspath segment handling\n") { if (vty->node == CONFIG_NODE) @@ -358,6 +358,7 @@ DEFUN (no_debug_bgp_as4_segment, NO_STR DEBUG_STR BGP_STR + "BGP AS4 actions\n" "BGP AS4 aspath segment handling\n") { if (vty->node == CONFIG_NODE) @@ -374,8 +375,8 @@ ALIAS (no_debug_bgp_as4_segment, undebug_bgp_as4_segment_cmd, "undebug bgp as4 segment", UNDEBUG_STR - DEBUG_STR BGP_STR + "BGP AS4 actions\n" "BGP AS4 aspath segment handling\n") DEFUN (debug_bgp_fsm, @@ -417,7 +418,6 @@ ALIAS (no_debug_bgp_fsm, undebug_bgp_fsm_cmd, "undebug bgp fsm", UNDEBUG_STR - DEBUG_STR BGP_STR "Finite State Machine\n") @@ -715,7 +715,6 @@ ALIAS (no_debug_bgp_zebra, undebug_bgp_zebra_cmd, "undebug bgp zebra", UNDEBUG_STR - DEBUG_STR BGP_STR "BGP Zebra messages\n") diff --git a/bgpd/bgp_dump.c b/bgpd/bgp_dump.c index 8087a403..edb725a9 100644 --- a/bgpd/bgp_dump.c +++ b/bgpd/bgp_dump.c @@ -356,7 +356,11 @@ bgp_dump_routes_func (int afi, int first_run, unsigned int seq) stream_putw(obuf, info->peer->table_dump_index); /* Originated */ +#ifdef HAVE_CLOCK_MONOTONIC + stream_putl (obuf, time(NULL) - (bgp_clock() - info->uptime)); +#else stream_putl (obuf, info->uptime); +#endif /* HAVE_CLOCK_MONOTONIC */ /* Dump attribute. */ /* Skip prefix & AFI/SAFI for MP_NLRI */ diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 9d14683c..1a460c6b 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -243,7 +243,15 @@ bgp_exit (int status) if (retain_mode) if_add_hook (IF_DELETE_HOOK, NULL); for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp)) - if_delete (ifp); + { + struct listnode *c_node, *c_nnode; + struct connected *c; + + for (ALL_LIST_ELEMENTS (ifp->connected, c_node, c_nnode, c)) + bgp_connected_delete (c); + + if_delete (ifp); + } list_free (iflist); /* reverse bgp_attr_init */ diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 9e3427d2..570cc3b7 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -30,6 +30,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #include "command.h" #include "privs.h" #include "linklist.h" +#include "network.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_fsm.h" @@ -150,6 +151,7 @@ bgp_accept (struct thread *thread) zlog_err ("[Error] BGP socket accept failed (%s)", safe_strerror (errno)); return -1; } + set_nonblocking (bgp_sock); if (BGP_DEBUG (events, EVENTS)) zlog_debug ("[Event] BGP connection from host %s", inet_sutop (&su, buf)); @@ -172,8 +174,11 @@ bgp_accept (struct thread *thread) } /* In case of peer is EBGP, we should set TTL for this connection. */ - if (peer_sort (peer1) == BGP_PEER_EBGP) + if (peer_sort (peer1) == BGP_PEER_EBGP) { sockopt_ttl (peer1->su.sa.sa_family, bgp_sock, peer1->ttl); + if (peer1->gtsm_hops) + sockopt_minttl (peer1->su.sa.sa_family, bgp_sock, MAXTTL + 1 - peer1->gtsm_hops); + } /* Make dummy peer until read Open packet. */ if (BGP_DEBUG (events, EVENTS)) @@ -313,8 +318,11 @@ bgp_connect (struct peer *peer) return -1; /* If we can get socket for the peer, adjest TTL and make connection. */ - if (peer_sort (peer) == BGP_PEER_EBGP) + if (peer_sort (peer) == BGP_PEER_EBGP) { sockopt_ttl (peer->su.sa.sa_family, peer->fd, peer->ttl); + if (peer->gtsm_hops) + sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - peer->gtsm_hops); + } sockopt_reuseaddr (peer->fd); sockopt_reuseport (peer->fd); @@ -461,7 +469,10 @@ bgp_socket (unsigned short port, const char *address) zlog_err ("socket: %s", safe_strerror (errno)); continue; } - + + /* if we intend to implement ttl-security, this socket needs ttl=255 */ + sockopt_ttl (ainfo->ai_family, sock, MAXTTL); + ret = bgp_listener (sock, ainfo->ai_addr, ainfo->ai_addrlen); if (ret == 0) ++count; @@ -494,6 +505,9 @@ bgp_socket (unsigned short port, const char *address) return sock; } + /* if we intend to implement ttl-security, this socket needs ttl=255 */ + sockopt_ttl (AF_INET, sock, MAXTTL); + memset (&sin, 0, sizeof (struct sockaddr_in)); sin.sin_family = AF_INET; sin.sin_port = htons (port); diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index 0cde665e..719cb966 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -276,6 +276,8 @@ bgp_nexthop_lookup_ipv6 (struct peer *peer, struct bgp_info *ri, int *changed, if (bnc->metric != oldbnc->metric) bnc->metricchanged = 1; + + bgp_unlock_node (oldrn); } } } @@ -365,6 +367,8 @@ bgp_nexthop_lookup (afi_t afi, struct peer *peer, struct bgp_info *ri, if (bnc->metric != oldbnc->metric) bnc->metricchanged = 1; + + bgp_unlock_node (oldrn); } } } @@ -571,7 +575,7 @@ bgp_connected_add (struct connected *ifc) } else { - bc = XCALLOC (0, sizeof (struct bgp_connected_ref)); + bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref)); bc->refcnt = 1; rn->info = bc; } @@ -596,7 +600,7 @@ bgp_connected_add (struct connected *ifc) } else { - bc = XCALLOC (0, sizeof (struct bgp_connected_ref)); + bc = XCALLOC (MTYPE_BGP_CONN, sizeof (struct bgp_connected_ref)); bc->refcnt = 1; rn->info = bc; } @@ -636,7 +640,7 @@ bgp_connected_delete (struct connected *ifc) bc->refcnt--; if (bc->refcnt == 0) { - XFREE (0, bc); + XFREE (MTYPE_BGP_CONN, bc); rn->info = NULL; } bgp_unlock_node (rn); @@ -662,7 +666,7 @@ bgp_connected_delete (struct connected *ifc) bc->refcnt--; if (bc->refcnt == 0) { - XFREE (0, bc); + XFREE (MTYPE_BGP_CONN, bc); rn->info = NULL; } bgp_unlock_node (rn); @@ -1136,11 +1140,15 @@ bgp_multiaccess_check_v4 (struct in_addr nexthop, char *peer) rn1 = bgp_node_match (bgp_connected_table[AFI_IP], &p1); if (! rn1) return 0; + bgp_unlock_node (rn1); rn2 = bgp_node_match (bgp_connected_table[AFI_IP], &p2); if (! rn2) return 0; + bgp_unlock_node (rn2); + /* This is safe, even with above unlocks, since we are just + comparing pointers to the objects, not the objects themselves. */ if (rn1 == rn2) return 1; @@ -1316,6 +1324,9 @@ bgp_scan_init (void) void bgp_scan_finish (void) { + /* Only the current one needs to be reset. */ + bgp_nexthop_cache_reset (bgp_nexthop_cache_table[AFI_IP]); + bgp_table_unlock (cache1_table[AFI_IP]); cache1_table[AFI_IP] = NULL; @@ -1326,6 +1337,9 @@ bgp_scan_finish (void) bgp_connected_table[AFI_IP] = NULL; #ifdef HAVE_IPV6 + /* Only the current one needs to be reset. */ + bgp_nexthop_cache_reset (bgp_nexthop_cache_table[AFI_IP6]); + bgp_table_unlock (cache1_table[AFI_IP6]); cache1_table[AFI_IP6] = NULL; diff --git a/bgpd/bgp_open.h b/bgpd/bgp_open.h index 59265dc9..2b1382d8 100644 --- a/bgpd/bgp_open.h +++ b/bgpd/bgp_open.h @@ -31,9 +31,9 @@ struct capability_header /* Generic MP capability data */ struct capability_mp_data { - u_int16_t afi; + afi_t afi; u_char reserved; - u_char safi; + safi_t safi; }; #pragma pack(1) @@ -55,8 +55,8 @@ struct capability_as4 struct graceful_restart_af { - u_int16_t afi; - u_char safi; + afi_t afi; + safi_t safi; u_char flag; }; diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index b29bc1f0..ed2cb73e 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -177,10 +177,11 @@ bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi) if (rn->prn) prd = (struct prefix_rd *) &rn->prn->p; - if (binfo && binfo->extra) + if (binfo) { - tag = binfo->extra->tag; from = binfo->peer; + if (binfo->extra) + tag = binfo->extra->tag; } bgp_packet_set_marker (s, BGP_MSG_UPDATE); @@ -597,7 +598,6 @@ bgp_write (struct thread *thread) struct stream *s; int num; unsigned int count = 0; - int write_errno; /* Yes first of all get peer pointer. */ peer = THREAD_ARG (thread); @@ -610,46 +610,37 @@ bgp_write (struct thread *thread) return 0; } - /* Nonblocking write until TCP output buffer is full. */ - while (1) + s = bgp_write_packet (peer); + if (!s) + return 0; /* nothing to send */ + + sockopt_cork (peer->fd, 1); + + /* Nonblocking write until TCP output buffer is full. */ + do { int writenum; - int val; - - s = bgp_write_packet (peer); - if (! s) - return 0; - - /* XXX: FIXME, the socket should be NONBLOCK from the start - * status shouldnt need to be toggled on each write - */ - val = fcntl (peer->fd, F_GETFL, 0); - fcntl (peer->fd, F_SETFL, val|O_NONBLOCK); /* Number of bytes to be sent. */ writenum = stream_get_endp (s) - stream_get_getp (s); /* Call write() system call. */ num = write (peer->fd, STREAM_PNT (s), writenum); - write_errno = errno; - fcntl (peer->fd, F_SETFL, val); - if (num <= 0) + if (num < 0) { - /* Partial write. */ - if (write_errno == EWOULDBLOCK || write_errno == EAGAIN) - break; + /* write failed either retry needed or error */ + if (ERRNO_IO_RETRY(errno)) + break; - BGP_EVENT_ADD (peer, TCP_fatal_error); + BGP_EVENT_ADD (peer, TCP_fatal_error); return 0; } + if (num != writenum) { + /* Partial write */ stream_forward_getp (s, num); - - if (write_errno == EAGAIN) - break; - - continue; + break; } /* Retrieve BGP packet type. */ @@ -690,13 +681,14 @@ bgp_write (struct thread *thread) /* OK we send packet so delete it. */ bgp_packet_delete (peer); - - if (++count >= BGP_WRITE_PACKET_MAX) - break; } + while (++count < BGP_WRITE_PACKET_MAX && + (s = bgp_write_packet (peer)) != NULL); if (bgp_write_proceed (peer)) BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd); + else + sockopt_cork (peer->fd, 0); return 0; } @@ -705,7 +697,7 @@ bgp_write (struct thread *thread) static int bgp_write_notify (struct peer *peer) { - int ret; + int ret, val; u_char type; struct stream *s; @@ -715,7 +707,10 @@ bgp_write_notify (struct peer *peer) return 0; assert (stream_get_endp (s) >= BGP_HEADER_SIZE); - /* I'm not sure fd is writable. */ + /* Put socket in blocking mode. */ + val = fcntl (peer->fd, F_GETFL, 0); + fcntl (peer->fd, F_SETFL, val & ~O_NONBLOCK); + ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s)); if (ret <= 0) { @@ -1884,12 +1879,6 @@ bgp_notify_receive (struct peer *peer, bgp_size_t size) bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_PARAM ) UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN); - /* Also apply to Unsupported Capability until remote router support - capability. */ - if (bgp_notify.code == BGP_NOTIFY_OPEN_ERR && - bgp_notify.subcode == BGP_NOTIFY_OPEN_UNSUP_CAPBL) - UNSET_FLAG (peer->sflags, PEER_STATUS_CAPABILITY_OPEN); - BGP_EVENT_ADD (peer, Receive_NOTIFICATION_message); } @@ -2016,8 +2005,14 @@ bgp_route_refresh_receive (struct peer *peer, bgp_size_t size) while (p_pnt < p_end) { + /* If the ORF entry is malformed, want to read as much of it + * as possible without going beyond the bounds of the entry, + * to maximise debug information. + */ + int ok; memset (&orfp, 0, sizeof (struct orf_prefix)); common = *p_pnt++; + /* after ++: p_pnt <= p_end */ if (common & ORF_COMMON_PART_REMOVE_ALL) { if (BGP_DEBUG (normal, NORMAL)) @@ -2025,34 +2020,60 @@ bgp_route_refresh_receive (struct peer *peer, bgp_size_t size) prefix_bgp_orf_remove_all (name); break; } - memcpy (&seq, p_pnt, sizeof (u_int32_t)); - p_pnt += sizeof (u_int32_t); - orfp.seq = ntohl (seq); - orfp.ge = *p_pnt++; - orfp.le = *p_pnt++; - orfp.p.prefixlen = *p_pnt++; - orfp.p.family = afi2family (afi); - psize = PSIZE (orfp.p.prefixlen); - memcpy (&orfp.p.u.prefix, p_pnt, psize); + ok = ((p_end - p_pnt) >= sizeof(u_int32_t)) ; + if (!ok) + { + memcpy (&seq, p_pnt, sizeof (u_int32_t)); + p_pnt += sizeof (u_int32_t); + orfp.seq = ntohl (seq); + } + else + p_pnt = p_end ; + + if ((ok = (p_pnt < p_end))) + orfp.ge = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */ + if ((ok = (p_pnt < p_end))) + orfp.le = *p_pnt++ ; /* value checked in prefix_bgp_orf_set() */ + if ((ok = (p_pnt < p_end))) + orfp.p.prefixlen = *p_pnt++ ; + orfp.p.family = afi2family (afi); /* afi checked already */ + + psize = PSIZE (orfp.p.prefixlen); /* 0 if not ok */ + if (psize > prefix_blen(&orfp.p)) /* valid for family ? */ + { + ok = 0 ; + psize = prefix_blen(&orfp.p) ; + } + if (psize > (p_end - p_pnt)) /* valid for packet ? */ + { + ok = 0 ; + psize = p_end - p_pnt ; + } + + if (psize > 0) + memcpy (&orfp.p.u.prefix, p_pnt, psize); p_pnt += psize; if (BGP_DEBUG (normal, NORMAL)) - zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d", + zlog_debug ("%s rcvd %s %s seq %u %s/%d ge %d le %d%s", peer->host, (common & ORF_COMMON_PART_REMOVE ? "Remove" : "Add"), (common & ORF_COMMON_PART_DENY ? "deny" : "permit"), orfp.seq, inet_ntop (orfp.p.family, &orfp.p.u.prefix, buf, BUFSIZ), - orfp.p.prefixlen, orfp.ge, orfp.le); - - ret = prefix_bgp_orf_set (name, afi, &orfp, - (common & ORF_COMMON_PART_DENY ? 0 : 1 ), - (common & ORF_COMMON_PART_REMOVE ? 0 : 1)); - - if (ret != CMD_SUCCESS) + orfp.p.prefixlen, orfp.ge, orfp.le, + ok ? "" : " MALFORMED"); + + if (ok) + ret = prefix_bgp_orf_set (name, afi, &orfp, + (common & ORF_COMMON_PART_DENY ? 0 : 1 ), + (common & ORF_COMMON_PART_REMOVE ? 0 : 1)); + + if (!ok || (ret != CMD_SUCCESS)) { if (BGP_DEBUG (normal, NORMAL)) - zlog_debug ("%s Received misformatted prefixlist ORF. Remove All pfxlist", peer->host); + zlog_debug ("%s Received misformatted prefixlist ORF." + " Remove All pfxlist", peer->host); prefix_bgp_orf_remove_all (name); break; } @@ -2237,12 +2258,13 @@ bgp_read_packet (struct peer *peer) return 0; /* Read packet from fd. */ - nbytes = stream_read_unblock (peer->ibuf, peer->fd, readsize); + nbytes = stream_read_try (peer->ibuf, peer->fd, readsize); /* If read byte is smaller than zero then error occured. */ if (nbytes < 0) { - if (errno == EAGAIN) + /* Transient error should retry */ + if (nbytes == -2) return -1; plog_err (peer->log, "%s [Error] bgp_read_packet error: %s", diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index a92ca4e2..5c516f02 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -910,19 +910,6 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p, } } - /* AS-Pathlimit check */ - if (ri->attr->pathlimit.ttl && peer_sort (peer) == BGP_PEER_EBGP) - /* Our ASN has not yet been pre-pended, that's done in packet_attribute - * on output. Hence the test here is for >=. - */ - if (aspath_count_hops (ri->attr->aspath) >= ri->attr->pathlimit.ttl) - { - if (BGP_DEBUG (filter, FILTER)) - zlog_info ("%s [Update:SEND] suppressed, AS-Pathlimit TTL %u exceeded", - peer->host, ri->attr->pathlimit.ttl); - return 0; - } - /* For modify attribute, copy it to temporary structure. */ bgp_attr_dup (attr, ri->attr); @@ -1027,39 +1014,6 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p, } #endif /* HAVE_IPV6 */ - /* AS-Pathlimit: Check ASN for private/confed */ - if (attr->pathlimit.ttl) - { - /* locally originated update */ - if (!attr->pathlimit.as) - attr->pathlimit.as = peer->local_as; - - /* if the AS_PATHLIMIT attribute is attached to a prefix by a - member of a confederation, then when the prefix is advertised outside - of the confederation boundary, then the AS number of the - confederation member inside of the AS_PATHLIMIT attribute should be - replaced by the confederation's AS number. */ - if (peer_sort (from) == BGP_PEER_CONFED - && peer_sort (peer) != BGP_PEER_CONFED) - attr->pathlimit.as = peer->local_as; - - /* Private ASN should be updated whenever announcement leaves - * private space. This is deliberately done after simple confed - * based update.. - */ - if (attr->pathlimit.as >= BGP_PRIVATE_AS_MIN - && attr->pathlimit.as <= BGP_PRIVATE_AS_MAX) - { - if (peer->local_as < BGP_PRIVATE_AS_MIN - || peer->local_as > BGP_PRIVATE_AS_MAX) - attr->pathlimit.as = peer->local_as; - /* Ours is private, try using theirs.. */ - else if (peer->as < BGP_PRIVATE_AS_MIN - || peer->local_as > BGP_PRIVATE_AS_MAX) - attr->pathlimit.as = peer->as; - } - } - /* If this is EBGP peer and remove-private-AS is set. */ if (peer_sort (peer) == BGP_PEER_EBGP && peer_af_flag_check (peer, afi, safi, PEER_FLAG_REMOVE_PRIVATE_AS) @@ -1614,14 +1568,13 @@ bgp_process_queue_init (void) } bm->process_main_queue->spec.workfunc = &bgp_process_main; - bm->process_rsclient_queue->spec.workfunc = &bgp_process_rsclient; bm->process_main_queue->spec.del_item_data = &bgp_processq_del; - bm->process_rsclient_queue->spec.del_item_data - = bm->process_main_queue->spec.del_item_data; - bm->process_main_queue->spec.max_retries - = bm->process_main_queue->spec.max_retries = 0; - bm->process_rsclient_queue->spec.hold - = bm->process_main_queue->spec.hold = 50; + 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; } void @@ -3239,14 +3192,6 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p, attr.med = bgp_static->igpmetric; attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); - if (bgp_static->ttl) - { - attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT); - attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE); - attr.pathlimit.as = 0; - attr.pathlimit.ttl = bgp_static->ttl; - } - if (bgp_static->atomic) attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE); @@ -3281,7 +3226,7 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p, else attr_new = bgp_attr_intern (&attr); - new_attr = *attr_new; + bgp_attr_dup(&new_attr, attr_new); SET_FLAG (bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK); @@ -3310,6 +3255,7 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p, bgp_attr_unintern (attr_new); attr_new = bgp_attr_intern (&new_attr); + bgp_attr_extra_free (&new_attr); for (ri = rn->info; ri; ri = ri->next) if (ri->peer == bgp->peer_self && ri->type == ZEBRA_ROUTE_BGP @@ -3395,14 +3341,6 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p, attr.med = bgp_static->igpmetric; attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); - if (bgp_static->ttl) - { - attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT); - attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE); - attr.pathlimit.as = 0; - attr.pathlimit.ttl = bgp_static->ttl; - } - if (bgp_static->atomic) attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE); @@ -3518,8 +3456,8 @@ bgp_static_update (struct bgp *bgp, struct prefix *p, } static void -bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi, - u_char safi, struct prefix_rd *prd, u_char *tag) +bgp_static_update_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi, + safi_t safi, struct prefix_rd *prd, u_char *tag) { struct bgp_node *rn; struct bgp_info *new; @@ -3599,8 +3537,8 @@ bgp_check_local_routes_rsclient (struct peer *rsclient, afi_t afi, safi_t safi) } static void -bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi, - u_char safi, struct prefix_rd *prd, u_char *tag) +bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, afi_t afi, + safi_t safi, struct prefix_rd *prd, u_char *tag) { struct bgp_node *rn; struct bgp_info *ri; @@ -3626,44 +3564,17 @@ bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi, bgp_unlock_node (rn); } -static void -bgp_pathlimit_update_parents (struct bgp *bgp, struct bgp_node *rn, - int ttl_edge) -{ - struct bgp_node *parent = rn; - struct bgp_static *sp; - - /* Existing static changed TTL, search parents and adjust their atomic */ - while ((parent = parent->parent)) - if ((sp = parent->info)) - { - int sp_level = (sp->atomic ? 1 : 0); - ttl_edge ? sp->atomic++ : sp->atomic--; - - /* did we change state of parent whether atomic is set or not? */ - if (sp_level != (sp->atomic ? 1 : 0)) - { - bgp_static_update (bgp, &parent->p, sp, - rn->table->afi, rn->table->safi); - } - } -} - /* 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, - u_int16_t afi, u_char safi, const char *rmap, int backdoor, - u_char ttl) + afi_t afi, safi_t safi, const char *rmap, int backdoor) { int ret; struct prefix p; struct bgp_static *bgp_static; struct bgp_node *rn; u_char need_update = 0; - u_char ttl_change = 0; - u_char ttl_edge = (ttl ? 1 : 0); - u_char new = 0; /* Convert IP prefix string to struct prefix. */ ret = str2prefix (ip_str, &p); @@ -3692,21 +3603,10 @@ 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) - { - if (bgp_static->backdoor != backdoor - || bgp_static->ttl != ttl) - need_update = 1; - } + if (bgp_static->valid && bgp_static->backdoor != backdoor) + need_update = 1; - /* need to catch TTL set/unset transitions for handling of - * ATOMIC_AGGREGATE - */ - if ((bgp_static->ttl ? 1 : 0) != ttl_edge) - ttl_change = 1; - bgp_static->backdoor = backdoor; - bgp_static->ttl = ttl; if (rmap) { @@ -3733,9 +3633,6 @@ 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; - bgp_static->ttl = ttl; - ttl_change = ttl_edge; - new = 1; if (rmap) { @@ -3747,39 +3644,6 @@ bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str, rn->info = bgp_static; } - /* ".. sites that choose to advertise the - * AS_PATHLIMIT path attribute SHOULD advertise the ATOMIC_AGGREGATE on - * all less specific covering prefixes as well as the more specific - * prefixes." - * - * So: - * Prefix that has just had pathlimit set/unset: - * - Must bump ATOMIC refcount on all parents. - * - * To catch less specific prefixes: - * - Must search children for ones with TTL, bump atomic refcount - * (we dont care if we're deleting a less specific prefix..) - */ - if (ttl_change) - { - /* Existing static changed TTL, search parents and adjust their atomic */ - bgp_pathlimit_update_parents (bgp, rn, ttl_edge); - } - - if (new) - { - struct bgp_node *child; - struct bgp_static *sc; - - /* New static, search children and bump this statics atomic.. */ - child = bgp_lock_node (rn); /* route_next_until unlocks it.. */ - while ((child = bgp_route_next_until (child, rn))) - { - if ((sc = child->info) && sc->ttl) - bgp_static->atomic++; - } - } - /* If BGP scan is not enabled, we should install this route here. */ if (! bgp_flag_check (bgp, BGP_FLAG_IMPORT_CHECK)) { @@ -3798,7 +3662,7 @@ bgp_static_set (struct vty *vty, struct bgp *bgp, const char *ip_str, /* Configure static BGP network. */ static int bgp_static_unset (struct vty *vty, struct bgp *bgp, const char *ip_str, - u_int16_t afi, u_char safi) + afi_t afi, safi_t safi) { int ret; struct prefix p; @@ -3833,9 +3697,6 @@ bgp_static_unset (struct vty *vty, struct bgp *bgp, const char *ip_str, bgp_static = rn->info; - /* decrement atomic in parents, see bgp_static_set */ - bgp_pathlimit_update_parents (bgp, rn, 0); - /* Update BGP RIB. */ if (! bgp_static->backdoor) bgp_static_withdraw (bgp, &p, afi, safi); @@ -4032,23 +3893,10 @@ DEFUN (bgp_network, "Specify a network to announce via BGP\n" "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n") { - u_char ttl = 0; - - if (argc == 2) - VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255); - return bgp_static_set (vty, vty->index, argv[0], - AFI_IP, bgp_node_safi (vty), NULL, 0, ttl); + AFI_IP, bgp_node_safi (vty), NULL, 0); } -ALIAS (bgp_network, - bgp_network_ttl_cmd, - "network A.B.C.D/M pathlimit <0-255>", - "Specify a network to announce via BGP\n" - "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") - DEFUN (bgp_network_route_map, bgp_network_route_map_cmd, "network A.B.C.D/M route-map WORD", @@ -4058,7 +3906,7 @@ DEFUN (bgp_network_route_map, "Name of the route map\n") { return bgp_static_set (vty, vty->index, argv[0], - AFI_IP, bgp_node_safi (vty), argv[1], 0, 0); + AFI_IP, bgp_node_safi (vty), argv[1], 0); } DEFUN (bgp_network_backdoor, @@ -4068,24 +3916,10 @@ DEFUN (bgp_network_backdoor, "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n" "Specify a BGP backdoor route\n") { - u_char ttl = 0; - - if (argc == 2) - VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255); - return bgp_static_set (vty, vty->index, argv[0], AFI_IP, SAFI_UNICAST, - NULL, 1, ttl); + NULL, 1); } -ALIAS (bgp_network_backdoor, - bgp_network_backdoor_ttl_cmd, - "network A.B.C.D/M backdoor pathlimit <0-255>", - "Specify a network to announce via BGP\n" - "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n" - "Specify a BGP backdoor route\n" - "AS-Path hopcount limit attribute\n" - "AS-Pathlimit TTL, in number of AS-Path hops\n") - DEFUN (bgp_network_mask, bgp_network_mask_cmd, "network A.B.C.D mask A.B.C.D", @@ -4096,10 +3930,6 @@ DEFUN (bgp_network_mask, { int ret; char prefix_str[BUFSIZ]; - u_char ttl = 0; - - if (argc == 3) - VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[2], 1, 255); ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str); if (! ret) @@ -4109,19 +3939,9 @@ DEFUN (bgp_network_mask, } return bgp_static_set (vty, vty->index, prefix_str, - AFI_IP, bgp_node_safi (vty), NULL, 0, ttl); + AFI_IP, bgp_node_safi (vty), NULL, 0); } -ALIAS (bgp_network_mask, - bgp_network_mask_ttl_cmd, - "network A.B.C.D mask A.B.C.D pathlimit <0-255>", - "Specify a network to announce via BGP\n" - "Network number\n" - "Network mask\n" - "Network mask\n" - "AS-Path hopcount limit attribute\n" - "AS-Pathlimit TTL, in number of AS-Path hops\n") - DEFUN (bgp_network_mask_route_map, bgp_network_mask_route_map_cmd, "network A.B.C.D mask A.B.C.D route-map WORD", @@ -4143,7 +3963,7 @@ DEFUN (bgp_network_mask_route_map, } return bgp_static_set (vty, vty->index, prefix_str, - AFI_IP, bgp_node_safi (vty), argv[2], 0, 0); + AFI_IP, bgp_node_safi (vty), argv[2], 0); } DEFUN (bgp_network_mask_backdoor, @@ -4157,11 +3977,7 @@ DEFUN (bgp_network_mask_backdoor, { int ret; char prefix_str[BUFSIZ]; - u_char ttl = 0; - if (argc == 3) - VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[2], 1, 255); - ret = netmask_str2prefix_str (argv[0], argv[1], prefix_str); if (! ret) { @@ -4170,20 +3986,9 @@ DEFUN (bgp_network_mask_backdoor, } return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST, - NULL, 1, ttl); + NULL, 1); } -ALIAS (bgp_network_mask_backdoor, - bgp_network_mask_backdoor_ttl_cmd, - "network A.B.C.D mask A.B.C.D backdoor pathlimit <0-255>", - "Specify a network to announce via BGP\n" - "Network number\n" - "Network mask\n" - "Network mask\n" - "Specify a BGP backdoor route\n" - "AS-Path hopcount limit attribute\n" - "AS-Pathlimit TTL, in number of AS-Path hops\n") - DEFUN (bgp_network_mask_natural, bgp_network_mask_natural_cmd, "network A.B.C.D", @@ -4192,10 +3997,6 @@ DEFUN (bgp_network_mask_natural, { int ret; char prefix_str[BUFSIZ]; - u_char ttl = 0; - - if (argc == 2) - VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255); ret = netmask_str2prefix_str (argv[0], NULL, prefix_str); if (! ret) @@ -4205,17 +4006,9 @@ DEFUN (bgp_network_mask_natural, } return bgp_static_set (vty, vty->index, prefix_str, - AFI_IP, bgp_node_safi (vty), NULL, 0, ttl); + AFI_IP, bgp_node_safi (vty), NULL, 0); } -ALIAS (bgp_network_mask_natural, - bgp_network_mask_natural_ttl_cmd, - "network A.B.C.D pathlimit <0-255>", - "Specify a network to announce via BGP\n" - "Network number\n" - "AS-Path hopcount limit attribute\n" - "AS-Pathlimit TTL, in number of AS-Path hops\n") - DEFUN (bgp_network_mask_natural_route_map, bgp_network_mask_natural_route_map_cmd, "network A.B.C.D route-map WORD", @@ -4235,7 +4028,7 @@ DEFUN (bgp_network_mask_natural_route_map, } return bgp_static_set (vty, vty->index, prefix_str, - AFI_IP, bgp_node_safi (vty), argv[1], 0, 0); + AFI_IP, bgp_node_safi (vty), argv[1], 0); } DEFUN (bgp_network_mask_natural_backdoor, @@ -4247,10 +4040,6 @@ DEFUN (bgp_network_mask_natural_backdoor, { int ret; char prefix_str[BUFSIZ]; - u_char ttl = 0; - - if (argc == 2) - VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255); ret = netmask_str2prefix_str (argv[0], NULL, prefix_str); if (! ret) @@ -4260,18 +4049,9 @@ DEFUN (bgp_network_mask_natural_backdoor, } return bgp_static_set (vty, vty->index, prefix_str, AFI_IP, SAFI_UNICAST, - NULL, 1, ttl); + NULL, 1); } -ALIAS (bgp_network_mask_natural_backdoor, - bgp_network_mask_natural_backdoor_ttl_cmd, - "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") - DEFUN (no_bgp_network, no_bgp_network_cmd, "no network A.B.C.D/M", @@ -4284,15 +4064,6 @@ DEFUN (no_bgp_network, } ALIAS (no_bgp_network, - no_bgp_network_ttl_cmd, - "no network A.B.C.D/M pathlimit <0-255>", - NO_STR - "Specify a network to announce via BGP\n" - "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 (no_bgp_network, no_bgp_network_route_map_cmd, "no network A.B.C.D/M route-map WORD", NO_STR @@ -4309,16 +4080,6 @@ ALIAS (no_bgp_network, "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n" "Specify a BGP backdoor route\n") -ALIAS (no_bgp_network, - no_bgp_network_backdoor_ttl_cmd, - "no network A.B.C.D/M backdoor pathlimit <0-255>", - NO_STR - "Specify a network to announce via BGP\n" - "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n" - "Specify a BGP backdoor route\n" - "AS-Path hopcount limit attribute\n" - "AS-Pathlimit TTL, in number of AS-Path hops\n") - DEFUN (no_bgp_network_mask, no_bgp_network_mask_cmd, "no network A.B.C.D mask A.B.C.D", @@ -4342,17 +4103,6 @@ DEFUN (no_bgp_network_mask, bgp_node_safi (vty)); } -ALIAS (no_bgp_network, - no_bgp_network_mask_ttl_cmd, - "no network A.B.C.D mask A.B.C.D pathlimit <0-255>", - NO_STR - "Specify a network to announce via BGP\n" - "Network number\n" - "Network mask\n" - "Network mask\n" - "AS-Path hopcount limit attribute\n" - "AS-Pathlimit TTL, in number of AS-Path hops\n") - ALIAS (no_bgp_network_mask, no_bgp_network_mask_route_map_cmd, "no network A.B.C.D mask A.B.C.D route-map WORD", @@ -4374,18 +4124,6 @@ ALIAS (no_bgp_network_mask, "Network mask\n" "Specify a BGP backdoor route\n") -ALIAS (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>", - NO_STR - "Specify a network to announce via BGP\n" - "Network number\n" - "Network mask\n" - "Network mask\n" - "Specify a BGP backdoor route\n" - "AS-Path hopcount limit attribute\n" - "AS-Pathlimit TTL, in number of AS-Path hops\n") - DEFUN (no_bgp_network_mask_natural, no_bgp_network_mask_natural_cmd, "no network A.B.C.D", @@ -4424,25 +4162,6 @@ ALIAS (no_bgp_network_mask_natural, "Network number\n" "Specify a BGP backdoor route\n") -ALIAS (no_bgp_network_mask_natural, - no_bgp_network_mask_natural_ttl_cmd, - "no network A.B.C.D pathlimit <0-255>", - NO_STR - "Specify a network to announce via BGP\n" - "Network number\n" - "AS-Path hopcount limit attribute\n" - "AS-Pathlimit TTL, in number of AS-Path hops\n") - -ALIAS (no_bgp_network_mask_natural, - no_bgp_network_mask_natural_backdoor_ttl_cmd, - "no network A.B.C.D backdoor pathlimit <0-255>", - NO_STR - "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") - #ifdef HAVE_IPV6 DEFUN (ipv6_bgp_network, ipv6_bgp_network_cmd, @@ -4450,23 +4169,10 @@ DEFUN (ipv6_bgp_network, "Specify a network to announce via BGP\n" "IPv6 prefix <network>/<length>\n") { - u_char ttl = 0; - - if (argc == 2) - VTY_GET_INTEGER_RANGE ("Pathlimit TTL", ttl, argv[1], 1, 255); - return bgp_static_set (vty, vty->index, argv[0], AFI_IP6, SAFI_UNICAST, - NULL, 0, ttl); + NULL, 0); } -ALIAS (ipv6_bgp_network, - ipv6_bgp_network_ttl_cmd, - "network X:X::X:X/M pathlimit <0-255>", - "Specify a network to announce via BGP\n" - "IPv6 prefix <network>/<length>\n" - "AS-Path hopcount limit attribute\n" - "AS-Pathlimit TTL, in number of AS-Path hops\n") - DEFUN (ipv6_bgp_network_route_map, ipv6_bgp_network_route_map_cmd, "network X:X::X:X/M route-map WORD", @@ -4476,7 +4182,7 @@ DEFUN (ipv6_bgp_network_route_map, "Name of the route map\n") { return bgp_static_set (vty, vty->index, argv[0], AFI_IP6, - bgp_node_safi (vty), argv[1], 0, 0); + bgp_node_safi (vty), argv[1], 0); } DEFUN (no_ipv6_bgp_network, @@ -4498,15 +4204,6 @@ ALIAS (no_ipv6_bgp_network, "Route-map to modify the attributes\n" "Name of the route map\n") -ALIAS (no_ipv6_bgp_network, - no_ipv6_bgp_network_ttl_cmd, - "no network X:X::X:X/M pathlimit <0-255>", - NO_STR - "Specify a network to announce via BGP\n" - "IPv6 prefix <network>/<length>\n" - "AS-Path hopcount limit attribute\n" - "AS-Pathlimit TTL, in number of AS-Path hops\n") - ALIAS (ipv6_bgp_network, old_ipv6_bgp_network_cmd, "ipv6 bgp network X:X::X:X/M", @@ -4524,6 +4221,129 @@ ALIAS (no_ipv6_bgp_network, "Specify a network to announce via BGP\n" "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n") #endif /* HAVE_IPV6 */ + +/* stubs for removed AS-Pathlimit commands, kept for config compatibility */ +ALIAS_DEPRECATED (bgp_network, + bgp_network_ttl_cmd, + "network A.B.C.D/M pathlimit <0-255>", + "Specify a network to announce via BGP\n" + "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>", + "Specify a network to announce via BGP\n" + "IP prefix <network>/<length>, e.g., 35.0.0.0/8\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 (bgp_network_mask, + bgp_network_mask_ttl_cmd, + "network A.B.C.D mask A.B.C.D pathlimit <0-255>", + "Specify a network to announce via BGP\n" + "Network number\n" + "Network mask\n" + "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>", + "Specify a network to announce via BGP\n" + "Network number\n" + "Network mask\n" + "Network mask\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 (bgp_network_mask_natural, + bgp_network_mask_natural_ttl_cmd, + "network A.B.C.D pathlimit <0-255>", + "Specify a network to announce via BGP\n" + "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>", + "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>", + NO_STR + "Specify a network to announce via BGP\n" + "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>", + NO_STR + "Specify a network to announce via BGP\n" + "IP prefix <network>/<length>, e.g., 35.0.0.0/8\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_mask_ttl_cmd, + "no network A.B.C.D mask A.B.C.D pathlimit <0-255>", + NO_STR + "Specify a network to announce via BGP\n" + "Network number\n" + "Network mask\n" + "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>", + NO_STR + "Specify a network to announce via BGP\n" + "Network number\n" + "Network mask\n" + "Network mask\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_mask_natural, + no_bgp_network_mask_natural_ttl_cmd, + "no network A.B.C.D pathlimit <0-255>", + NO_STR + "Specify a network to announce via BGP\n" + "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>", + NO_STR + "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") +#ifdef HAVE_IPV6 +ALIAS_DEPRECATED (ipv6_bgp_network, + ipv6_bgp_network_ttl_cmd, + "network X:X::X:X/M pathlimit <0-255>", + "Specify a network to announce via BGP\n" + "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>", + NO_STR + "Specify a network to announce via BGP\n" + "IPv6 prefix <network>/<length>\n" + "AS-Path hopcount limit attribute\n" + "AS-Pathlimit TTL, in number of AS-Path hops\n") +#endif /* HAVE_IPV6 */ /* Aggreagete address: @@ -4986,9 +4806,8 @@ bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi, #define AGGREGATE_AS_SET 1 static int -bgp_aggregate_set (struct vty *vty, const char *prefix_str, - afi_t afi, safi_t safi, - u_char summary_only, u_char as_set) +bgp_aggregate_unset (struct vty *vty, const char *prefix_str, + afi_t afi, safi_t safi) { int ret; struct prefix p; @@ -5009,34 +4828,33 @@ bgp_aggregate_set (struct vty *vty, const char *prefix_str, bgp = vty->index; /* Old configuration check. */ - rn = bgp_node_get (bgp->aggregate[afi][safi], &p); - - if (rn->info) + rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p); + if (! rn) { - vty_out (vty, "There is already same aggregate network.%s", VTY_NEWLINE); - bgp_unlock_node (rn); + vty_out (vty, "%% There is no aggregate-address configuration.%s", + VTY_NEWLINE); return CMD_WARNING; } - /* Make aggregate address structure. */ - aggregate = bgp_aggregate_new (); - aggregate->summary_only = summary_only; - aggregate->as_set = as_set; - aggregate->safi = safi; - rn->info = aggregate; + aggregate = rn->info; + if (aggregate->safi & SAFI_UNICAST) + bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate); + if (aggregate->safi & SAFI_MULTICAST) + bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate); - /* Aggregate address insert into BGP routing table. */ - if (safi & SAFI_UNICAST) - bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate); - if (safi & SAFI_MULTICAST) - bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate); + /* Unlock aggregate address configuration. */ + rn->info = NULL; + bgp_aggregate_free (aggregate); + bgp_unlock_node (rn); + bgp_unlock_node (rn); return CMD_SUCCESS; } static int -bgp_aggregate_unset (struct vty *vty, const char *prefix_str, - afi_t afi, safi_t safi) +bgp_aggregate_set (struct vty *vty, const char *prefix_str, + afi_t afi, safi_t safi, + u_char summary_only, u_char as_set) { int ret; struct prefix p; @@ -5057,25 +4875,33 @@ bgp_aggregate_unset (struct vty *vty, const char *prefix_str, bgp = vty->index; /* Old configuration check. */ - rn = bgp_node_lookup (bgp->aggregate[afi][safi], &p); - if (! rn) + rn = bgp_node_get (bgp->aggregate[afi][safi], &p); + + if (rn->info) { - vty_out (vty, "%% There is no aggregate-address configuration.%s", - VTY_NEWLINE); - return CMD_WARNING; + vty_out (vty, "There is already same aggregate network.%s", VTY_NEWLINE); + /* try to remove the old entry */ + ret = bgp_aggregate_unset (vty, prefix_str, afi, safi); + if (ret) + { + vty_out (vty, "Error deleting aggregate.%s", VTY_NEWLINE); + bgp_unlock_node (rn); + return CMD_WARNING; + } } - aggregate = rn->info; - if (aggregate->safi & SAFI_UNICAST) - bgp_aggregate_delete (bgp, &p, afi, SAFI_UNICAST, aggregate); - if (aggregate->safi & SAFI_MULTICAST) - bgp_aggregate_delete (bgp, &p, afi, SAFI_MULTICAST, aggregate); + /* Make aggregate address structure. */ + aggregate = bgp_aggregate_new (); + aggregate->summary_only = summary_only; + aggregate->as_set = as_set; + aggregate->safi = safi; + rn->info = aggregate; - /* Unlock aggregate address configuration. */ - rn->info = NULL; - bgp_aggregate_free (aggregate); - bgp_unlock_node (rn); - bgp_unlock_node (rn); + /* Aggregate address insert into BGP routing table. */ + if (safi & SAFI_UNICAST) + bgp_aggregate_add (bgp, &p, afi, SAFI_UNICAST, aggregate); + if (safi & SAFI_MULTICAST) + bgp_aggregate_add (bgp, &p, afi, SAFI_MULTICAST, aggregate); return CMD_SUCCESS; } @@ -5723,12 +5549,12 @@ route_vty_out (struct vty *vty, struct prefix *p, #endif /* HAVE_IPV6 */ if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)) - vty_out (vty, "%10d", attr->med); + vty_out (vty, "%10u", attr->med); else vty_out (vty, " "); if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) - vty_out (vty, "%7d", attr->local_pref); + vty_out (vty, "%7u", attr->local_pref); else vty_out (vty, " "); @@ -5788,16 +5614,16 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p, #endif /* HAVE_IPV6 */ if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC)) - vty_out (vty, "%10d", attr->med); + vty_out (vty, "%10u", attr->med); else vty_out (vty, " "); if (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)) - vty_out (vty, "%7d", attr->local_pref); + vty_out (vty, "%7u", attr->local_pref); else vty_out (vty, " "); - vty_out (vty, "%7d ", (attr->extra ? attr->extra->weight : 0)); + vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0)); /* Print aspath */ if (attr->aspath) @@ -5979,6 +5805,9 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p, char buf1[BUFSIZ]; struct attr *attr; int sockunion_vty_out (struct vty *, union sockunion *); +#ifdef HAVE_CLOCK_MONOTONIC + time_t tbuf; +#endif attr = binfo->attr; @@ -6064,15 +5893,15 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p, 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 %d", attr->med); + vty_out (vty, ", metric %u", attr->med); if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) - vty_out (vty, ", localpref %d", attr->local_pref); + vty_out (vty, ", localpref %u", attr->local_pref); else - vty_out (vty, ", localpref %d", bgp->default_local_pref); + vty_out (vty, ", localpref %u", bgp->default_local_pref); if (attr->extra && attr->extra->weight != 0) - vty_out (vty, ", weight %d", attr->extra->weight); + vty_out (vty, ", weight %u", attr->extra->weight); if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY)) vty_out (vty, ", valid"); @@ -6130,22 +5959,16 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p, vty_out (vty, "%s", VTY_NEWLINE); } - /* 7: AS Pathlimit */ - if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AS_PATHLIMIT)) - { - - vty_out (vty, " AS-Pathlimit: %u", - attr->pathlimit.ttl); - if (attr->pathlimit.as) - vty_out (vty, " (%u)", attr->pathlimit.as); - vty_out (vty, "%s", VTY_NEWLINE); - } - if (binfo->extra && binfo->extra->damp_info) bgp_damp_info_vty (vty, binfo); /* Line 7 display Uptime */ - vty_out (vty, " Last update: %s", ctime (&binfo->uptime)); +#ifdef HAVE_CLOCK_MONOTONIC + tbuf = time(NULL) - (bgp_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); } @@ -6554,7 +6377,10 @@ 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) - continue; + { + bgp_unlock_node (rm); + continue; + } for (ri = rm->info; ri; ri = ri->next) { @@ -6568,6 +6394,8 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp, display++; route_vty_out_detail (vty, bgp, &rm->p, ri, AFI_IP, SAFI_MPLS_VPN); } + + bgp_unlock_node (rm); } } } @@ -6591,6 +6419,8 @@ bgp_show_route_in_table (struct vty *vty, struct bgp *bgp, route_vty_out_detail (vty, bgp, &rn->p, ri, afi, safi); } } + + bgp_unlock_node (rn); } } @@ -6663,6 +6493,15 @@ DEFUN (show_ip_bgp_ipv4, return bgp_show (vty, NULL, AFI_IP, SAFI_UNICAST, bgp_show_type_normal, NULL); } +ALIAS (show_ip_bgp_ipv4, + show_bgp_ipv4_safi_cmd, + "show bgp ipv4 (unicast|multicast)", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n") + DEFUN (show_ip_bgp_route, show_ip_bgp_route_cmd, "show ip bgp A.B.C.D", @@ -6691,6 +6530,16 @@ DEFUN (show_ip_bgp_ipv4_route, return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 0); } +ALIAS (show_ip_bgp_ipv4_route, + show_bgp_ipv4_safi_route_cmd, + "show bgp ipv4 (unicast|multicast) A.B.C.D", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Network in the BGP routing table to display\n") + DEFUN (show_ip_bgp_vpnv4_all_route, show_ip_bgp_vpnv4_all_route_cmd, "show ip bgp vpnv4 all A.B.C.D", @@ -6755,6 +6604,16 @@ DEFUN (show_ip_bgp_ipv4_prefix, return bgp_show_route (vty, NULL, argv[1], AFI_IP, SAFI_UNICAST, NULL, 1); } +ALIAS (show_ip_bgp_ipv4_prefix, + show_bgp_ipv4_safi_prefix_cmd, + "show bgp ipv4 (unicast|multicast) A.B.C.D/M", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n") + DEFUN (show_ip_bgp_vpnv4_all_prefix, show_ip_bgp_vpnv4_all_prefix_cmd, "show ip bgp vpnv4 all A.B.C.D/M", @@ -6857,6 +6716,22 @@ ALIAS (show_bgp, BGP_STR "Address family\n") +DEFUN (show_bgp_ipv6_safi, + show_bgp_ipv6_safi_cmd, + "show bgp ipv6 (unicast|multicast)", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n") +{ + if (strncmp (argv[0], "m", 1) == 0) + return bgp_show (vty, NULL, AFI_IP6, SAFI_MULTICAST, bgp_show_type_normal, + NULL); + + return bgp_show (vty, NULL, AFI_IP6, SAFI_UNICAST, bgp_show_type_normal, NULL); +} + /* old command */ DEFUN (show_ipv6_bgp, show_ipv6_bgp_cmd, @@ -6887,6 +6762,22 @@ ALIAS (show_bgp_route, "Address family\n" "Network in the BGP routing table to display\n") +DEFUN (show_bgp_ipv6_safi_route, + show_bgp_ipv6_safi_route_cmd, + "show bgp ipv6 (unicast|multicast) X:X::X:X", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Network in the BGP routing table to display\n") +{ + if (strncmp (argv[0], "m", 1) == 0) + return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 0); + + return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 0); +} + /* old command */ DEFUN (show_ipv6_bgp_route, show_ipv6_bgp_route_cmd, @@ -6917,6 +6808,22 @@ ALIAS (show_bgp_prefix, "Address family\n" "IPv6 prefix <network>/<length>\n") +DEFUN (show_bgp_ipv6_safi_prefix, + show_bgp_ipv6_safi_prefix_cmd, + "show bgp ipv6 (unicast|multicast) X:X::X:X/M", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n") +{ + if (strncmp (argv[0], "m", 1) == 0) + return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_MULTICAST, NULL, 1); + + return bgp_show_route (vty, NULL, argv[1], AFI_IP6, SAFI_UNICAST, NULL, 1); +} + /* old command */ DEFUN (show_ipv6_bgp_prefix, show_ipv6_bgp_prefix_cmd, @@ -7621,15 +7528,36 @@ DEFUN (show_ipv6_mbgp_community_all, #endif /* HAVE_IPV6 */ static int -bgp_show_community (struct vty *vty, int argc, const char **argv, int exact, - u_int16_t afi, u_char safi) +bgp_show_community (struct vty *vty, const char *view_name, int argc, + const char **argv, int exact, afi_t afi, safi_t safi) { struct community *com; struct buffer *b; + struct bgp *bgp; int i; char *str; int first = 0; + /* BGP structure lookup */ + if (view_name) + { + 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; + } + } + else + { + bgp = bgp_get_default (); + if (bgp == NULL) + { + vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); + return CMD_WARNING; + } + } + b = buffer_new (1024); for (i = 0; i < argc; i++) { @@ -7657,7 +7585,7 @@ bgp_show_community (struct vty *vty, int argc, const char **argv, int exact, return CMD_WARNING; } - return bgp_show (vty, NULL, afi, safi, + return bgp_show (vty, bgp, afi, safi, (exact ? bgp_show_type_community_exact : bgp_show_type_community), com); } @@ -7674,7 +7602,7 @@ DEFUN (show_ip_bgp_community, "Do not advertise to any peer (well-known community)\n" "Do not export to next AS (well-known community)\n") { - return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_UNICAST); + return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_UNICAST); } ALIAS (show_ip_bgp_community, @@ -7753,9 +7681,9 @@ DEFUN (show_ip_bgp_ipv4_community, "Do not export to next AS (well-known community)\n") { if (strncmp (argv[0], "m", 1) == 0) - return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_MULTICAST); + return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_MULTICAST); - return bgp_show_community (vty, argc, argv, 0, AFI_IP, SAFI_UNICAST); + return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP, SAFI_UNICAST); } ALIAS (show_ip_bgp_ipv4_community, @@ -7827,6 +7755,177 @@ ALIAS (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") +DEFUN (show_bgp_view_afi_safi_community_all, + show_bgp_view_afi_safi_community_all_cmd, +#ifdef HAVE_IPV6 + "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community", +#else + "show bgp view WORD ipv4 (unicast|multicast) community", +#endif + SHOW_STR + BGP_STR + "BGP view\n" + "BGP view name\n" + "Address family\n" +#ifdef HAVE_IPV6 + "Address family\n" +#endif + "Address Family modifier\n" + "Address Family modifier\n" + "Display routes containing communities\n") +{ + int afi; + int safi; + struct bgp *bgp; + + /* 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; + } + +#ifdef HAVE_IPV6 + afi = (strncmp (argv[1], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP; + safi = (strncmp (argv[2], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; +#else + afi = AFI_IP; + safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; +#endif + return bgp_show (vty, bgp, afi, safi, bgp_show_type_community_all, NULL); +} + +DEFUN (show_bgp_view_afi_safi_community, + show_bgp_view_afi_safi_community_cmd, +#ifdef HAVE_IPV6 + "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export)", +#else + "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export)", +#endif + SHOW_STR + BGP_STR + "BGP view\n" + "BGP view name\n" + "Address family\n" +#ifdef HAVE_IPV6 + "Address family\n" +#endif + "Address family modifier\n" + "Address family modifier\n" + "Display routes matching the communities\n" + "community number\n" + "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") +{ + int afi; + int safi; + +#ifdef HAVE_IPV6 + afi = (strncmp (argv[1], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP; + safi = (strncmp (argv[2], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + return bgp_show_community (vty, argv[0], argc-3, &argv[3], 0, afi, safi); +#else + afi = AFI_IP; + safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + return bgp_show_community (vty, argv[0], argc-2, &argv[2], 0, afi, safi); +#endif +} + +ALIAS (show_bgp_view_afi_safi_community, + show_bgp_view_afi_safi_community2_cmd, +#ifdef HAVE_IPV6 + "show bgp view WORD (ipv4|ipv6) (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)", +#else + "show bgp view WORD ipv4 (unicast|multicast) community (AA:NN|local-AS|no-advertise|no-export) (AA:NN|local-AS|no-advertise|no-export)", +#endif + SHOW_STR + BGP_STR + "BGP view\n" + "BGP view name\n" + "Address family\n" +#ifdef HAVE_IPV6 + "Address family\n" +#endif + "Address family modifier\n" + "Address family modifier\n" + "Display routes matching the communities\n" + "community number\n" + "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" + "community number\n" + "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_view_afi_safi_community, + show_bgp_view_afi_safi_community3_cmd, +#ifdef HAVE_IPV6 + "show bgp view WORD (ipv4|ipv6) (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)", +#else + "show bgp view WORD 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)", +#endif + SHOW_STR + BGP_STR + "BGP view\n" + "BGP view name\n" + "Address family\n" +#ifdef HAVE_IPV6 + "Address family\n" +#endif + "Address family modifier\n" + "Address family modifier\n" + "Display routes matching the communities\n" + "community number\n" + "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" + "community number\n" + "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" + "community number\n" + "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_view_afi_safi_community, + show_bgp_view_afi_safi_community4_cmd, +#ifdef HAVE_IPV6 + "show bgp view WORD (ipv4|ipv6) (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)", +#else + "show bgp view WORD 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)", +#endif + SHOW_STR + BGP_STR + "BGP view\n" + "BGP view name\n" + "Address family\n" +#ifdef HAVE_IPV6 + "Address family\n" +#endif + "Address family modifier\n" + "Address family modifier\n" + "Display routes matching the communities\n" + "community number\n" + "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" + "community number\n" + "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" + "community number\n" + "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" + "community number\n" + "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") + DEFUN (show_ip_bgp_community_exact, show_ip_bgp_community_exact_cmd, "show ip bgp community (AA:NN|local-AS|no-advertise|no-export) exact-match", @@ -7840,7 +7939,7 @@ DEFUN (show_ip_bgp_community_exact, "Do not export to next AS (well-known community)\n" "Exact match of the communities") { - return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_UNICAST); + return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_UNICAST); } ALIAS (show_ip_bgp_community_exact, @@ -7923,9 +8022,9 @@ DEFUN (show_ip_bgp_ipv4_community_exact, "Exact match of the communities") { if (strncmp (argv[0], "m", 1) == 0) - return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_MULTICAST); + return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_MULTICAST); - return bgp_show_community (vty, argc, argv, 1, AFI_IP, SAFI_UNICAST); + return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP, SAFI_UNICAST); } ALIAS (show_ip_bgp_ipv4_community_exact, @@ -8012,7 +8111,7 @@ DEFUN (show_bgp_community, "Do not advertise to any peer (well-known community)\n" "Do not export to next AS (well-known community)\n") { - return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_UNICAST); + return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_UNICAST); } ALIAS (show_bgp_community, @@ -8157,7 +8256,7 @@ DEFUN (show_ipv6_bgp_community, "Do not advertise to any peer (well-known community)\n" "Do not export to next AS (well-known community)\n") { - return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_UNICAST); + return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_UNICAST); } /* old command */ @@ -8235,7 +8334,7 @@ DEFUN (show_bgp_community_exact, "Do not export to next AS (well-known community)\n" "Exact match of the communities") { - return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_UNICAST); + return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_UNICAST); } ALIAS (show_bgp_community_exact, @@ -8388,7 +8487,7 @@ DEFUN (show_ipv6_bgp_community_exact, "Do not export to next AS (well-known community)\n" "Exact match of the communities") { - return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_UNICAST); + return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_UNICAST); } /* old command */ @@ -8470,7 +8569,7 @@ DEFUN (show_ipv6_mbgp_community, "Do not advertise to any peer (well-known community)\n" "Do not export to next AS (well-known community)\n") { - return bgp_show_community (vty, argc, argv, 0, AFI_IP6, SAFI_MULTICAST); + return bgp_show_community (vty, NULL, argc, argv, 0, AFI_IP6, SAFI_MULTICAST); } /* old command */ @@ -8550,7 +8649,7 @@ DEFUN (show_ipv6_mbgp_community_exact, "Do not export to next AS (well-known community)\n" "Exact match of the communities") { - return bgp_show_community (vty, argc, argv, 1, AFI_IP6, SAFI_MULTICAST); + return bgp_show_community (vty, NULL, argc, argv, 1, AFI_IP6, SAFI_MULTICAST); } /* old command */ @@ -8622,7 +8721,7 @@ ALIAS (show_ipv6_mbgp_community_exact, static int bgp_show_community_list (struct vty *vty, const char *com, int exact, - u_int16_t afi, u_char safi) + afi_t afi, safi_t safi) { struct community_list *list; @@ -9959,6 +10058,56 @@ DEFUN (show_ip_bgp_ipv4_neighbor_received_routes, return peer_adj_routes (vty, peer, AFI_IP, SAFI_UNICAST, 1); } +DEFUN (show_bgp_view_afi_safi_neighbor_adv_recd_routes, + show_bgp_view_afi_safi_neighbor_adv_recd_routes_cmd, +#ifdef HAVE_IPV6 + "show bgp view WORD (ipv4|ipv6) (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) (advertised-routes|received-routes)", +#else + "show bgp view WORD ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) (advertised-routes|received-routes)", +#endif + SHOW_STR + BGP_STR + "BGP view\n" + "BGP view name\n" + "Address family\n" +#ifdef HAVE_IPV6 + "Address family\n" +#endif + "Address family modifier\n" + "Address family modifier\n" + "Detailed information on TCP and BGP neighbor connections\n" + "Neighbor to display information about\n" + "Neighbor to display information about\n" + "Display the advertised routes to neighbor\n" + "Display the received routes from neighbor\n") +{ + int afi; + int safi; + int in; + struct peer *peer; + +#ifdef HAVE_IPV6 + peer = peer_lookup_in_view (vty, argv[0], argv[3]); +#else + peer = peer_lookup_in_view (vty, argv[0], argv[2]); +#endif + + if (! peer) + return CMD_WARNING; + +#ifdef HAVE_IPV6 + afi = (strncmp (argv[1], "ipv6", 4) == 0) ? AFI_IP6 : AFI_IP; + safi = (strncmp (argv[2], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + in = (strncmp (argv[4], "r", 1) == 0) ? 1 : 0; +#else + afi = AFI_IP; + safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + in = (strncmp (argv[3], "r", 1) == 0) ? 1 : 0; +#endif + + return peer_adj_routes (vty, peer, afi, safi, in); +} + DEFUN (show_ip_bgp_neighbor_received_prefix_filter, show_ip_bgp_neighbor_received_prefix_filter_cmd, "show ip bgp neighbors (A.B.C.D|X:X::X:X) received prefix-filter", @@ -10366,6 +10515,65 @@ ALIAS (show_ip_bgp_view_rsclient, "Information about Route Server Client\n" NEIGHBOR_ADDR_STR) +DEFUN (show_bgp_view_ipv4_safi_rsclient, + show_bgp_view_ipv4_safi_rsclient_cmd, + "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)", + SHOW_STR + BGP_STR + "BGP view\n" + "BGP view name\n" + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Client\n" + NEIGHBOR_ADDR_STR) +{ + struct bgp_table *table; + struct peer *peer; + safi_t safi; + + if (argc == 3) { + peer = peer_lookup_in_view (vty, argv[0], argv[2]); + safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + } else { + peer = peer_lookup_in_view (vty, NULL, argv[1]); + safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + } + + if (! peer) + return CMD_WARNING; + + if (! peer->afc[AFI_IP][safi]) + { + vty_out (vty, "%% Activate the neighbor for the address family first%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][safi], + PEER_FLAG_RSERVER_CLIENT)) + { + vty_out (vty, "%% Neighbor is not a Route-Server client%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + table = peer->rib[AFI_IP][safi]; + + return bgp_show_table (vty, table, &peer->remote_id, bgp_show_type_normal, NULL); +} + +ALIAS (show_bgp_view_ipv4_safi_rsclient, + show_bgp_ipv4_safi_rsclient_cmd, + "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Client\n" + NEIGHBOR_ADDR_STR) + DEFUN (show_ip_bgp_view_rsclient_route, show_ip_bgp_view_rsclient_route_cmd, "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X) A.B.C.D", @@ -10439,6 +10647,87 @@ ALIAS (show_ip_bgp_view_rsclient_route, NEIGHBOR_ADDR_STR "Network in the BGP routing table to display\n") +DEFUN (show_bgp_view_ipv4_safi_rsclient_route, + show_bgp_view_ipv4_safi_rsclient_route_cmd, + "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D", + SHOW_STR + BGP_STR + "BGP view\n" + "BGP view name\n" + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Client\n" + NEIGHBOR_ADDR_STR + "Network in the BGP routing table to display\n") +{ + struct bgp *bgp; + struct peer *peer; + safi_t safi; + + /* BGP structure lookup. */ + if (argc == 4) + { + 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; + } + } + else + { + bgp = bgp_get_default (); + if (bgp == NULL) + { + vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); + return CMD_WARNING; + } + } + + if (argc == 4) { + peer = peer_lookup_in_view (vty, argv[0], argv[2]); + safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + } else { + peer = peer_lookup_in_view (vty, NULL, argv[1]); + safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + } + + if (! peer) + return CMD_WARNING; + + if (! peer->afc[AFI_IP][safi]) + { + vty_out (vty, "%% Activate the neighbor for the address family first%s", + VTY_NEWLINE); + return CMD_WARNING; +} + + if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][safi], + PEER_FLAG_RSERVER_CLIENT)) + { + vty_out (vty, "%% Neighbor is not a Route-Server client%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP][safi], + (argc == 4) ? argv[3] : argv[2], + AFI_IP, safi, NULL, 0); +} + +ALIAS (show_bgp_view_ipv4_safi_rsclient_route, + show_bgp_ipv4_safi_rsclient_route_cmd, + "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Client\n" + NEIGHBOR_ADDR_STR + "Network in the BGP routing table to display\n") + DEFUN (show_ip_bgp_view_rsclient_prefix, show_ip_bgp_view_rsclient_prefix_cmd, "show ip bgp view WORD rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M", @@ -10512,6 +10801,86 @@ ALIAS (show_ip_bgp_view_rsclient_prefix, NEIGHBOR_ADDR_STR "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n") +DEFUN (show_bgp_view_ipv4_safi_rsclient_prefix, + show_bgp_view_ipv4_safi_rsclient_prefix_cmd, + "show bgp view WORD ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M", + SHOW_STR + BGP_STR + "BGP view\n" + "BGP view name\n" + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Client\n" + NEIGHBOR_ADDR_STR + "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n") +{ + struct bgp *bgp; + struct peer *peer; + safi_t safi; + + /* BGP structure lookup. */ + if (argc == 4) + { + 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; + } + } + else + { + bgp = bgp_get_default (); + if (bgp == NULL) + { + vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); + return CMD_WARNING; + } + } + + if (argc == 4) { + peer = peer_lookup_in_view (vty, argv[0], argv[2]); + safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + } else { + peer = peer_lookup_in_view (vty, NULL, argv[1]); + safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + } + + if (! peer) + return CMD_WARNING; + + if (! peer->afc[AFI_IP][safi]) + { + vty_out (vty, "%% Activate the neighbor for the address family first%s", + VTY_NEWLINE); + return CMD_WARNING; +} + + if ( ! CHECK_FLAG (peer->af_flags[AFI_IP][safi], + PEER_FLAG_RSERVER_CLIENT)) +{ + vty_out (vty, "%% Neighbor is not a Route-Server client%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP][safi], + (argc == 4) ? argv[3] : argv[2], + AFI_IP, safi, NULL, 1); +} + +ALIAS (show_bgp_view_ipv4_safi_rsclient_prefix, + show_bgp_ipv4_safi_rsclient_prefix_cmd, + "show bgp ipv4 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) A.B.C.D/M", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Client\n" + NEIGHBOR_ADDR_STR + "IP prefix <network>/<length>, e.g., 35.0.0.0/8\n") #ifdef HAVE_IPV6 DEFUN (show_bgp_view_neighbor_routes, @@ -10778,6 +11147,65 @@ ALIAS (show_bgp_view_rsclient, "Information about Route Server Client\n" NEIGHBOR_ADDR_STR) +DEFUN (show_bgp_view_ipv6_safi_rsclient, + show_bgp_view_ipv6_safi_rsclient_cmd, + "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)", + SHOW_STR + BGP_STR + "BGP view\n" + "BGP view name\n" + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Client\n" + NEIGHBOR_ADDR_STR) +{ + struct bgp_table *table; + struct peer *peer; + safi_t safi; + + if (argc == 3) { + peer = peer_lookup_in_view (vty, argv[0], argv[2]); + safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + } else { + peer = peer_lookup_in_view (vty, NULL, argv[1]); + safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + } + + if (! peer) + return CMD_WARNING; + + if (! peer->afc[AFI_IP6][safi]) + { + vty_out (vty, "%% Activate the neighbor for the address family first%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + if ( ! CHECK_FLAG (peer->af_flags[AFI_IP6][safi], + PEER_FLAG_RSERVER_CLIENT)) + { + vty_out (vty, "%% Neighbor is not a Route-Server client%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + table = peer->rib[AFI_IP6][safi]; + + return bgp_show_table (vty, table, &peer->remote_id, bgp_show_type_normal, NULL); +} + +ALIAS (show_bgp_view_ipv6_safi_rsclient, + show_bgp_ipv6_safi_rsclient_cmd, + "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X)", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Client\n" + NEIGHBOR_ADDR_STR) + DEFUN (show_bgp_view_rsclient_route, show_bgp_view_rsclient_route_cmd, "show bgp view WORD rsclient (A.B.C.D|X:X::X:X) X:X::X:X", @@ -10849,6 +11277,87 @@ ALIAS (show_bgp_view_rsclient_route, NEIGHBOR_ADDR_STR "Network in the BGP routing table to display\n") +DEFUN (show_bgp_view_ipv6_safi_rsclient_route, + show_bgp_view_ipv6_safi_rsclient_route_cmd, + "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X", + SHOW_STR + BGP_STR + "BGP view\n" + "BGP view name\n" + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Client\n" + NEIGHBOR_ADDR_STR + "Network in the BGP routing table to display\n") +{ + struct bgp *bgp; + struct peer *peer; + safi_t safi; + + /* BGP structure lookup. */ + if (argc == 4) + { + 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; + } + } + else + { + bgp = bgp_get_default (); + if (bgp == NULL) + { + vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); + return CMD_WARNING; + } + } + + if (argc == 4) { + peer = peer_lookup_in_view (vty, argv[0], argv[2]); + safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + } else { + peer = peer_lookup_in_view (vty, NULL, argv[1]); + safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + } + + if (! peer) + return CMD_WARNING; + + if (! peer->afc[AFI_IP6][safi]) + { + vty_out (vty, "%% Activate the neighbor for the address family first%s", + VTY_NEWLINE); + return CMD_WARNING; +} + + if ( ! CHECK_FLAG (peer->af_flags[AFI_IP6][safi], + PEER_FLAG_RSERVER_CLIENT)) + { + vty_out (vty, "%% Neighbor is not a Route-Server client%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP6][safi], + (argc == 4) ? argv[3] : argv[2], + AFI_IP6, safi, NULL, 0); +} + +ALIAS (show_bgp_view_ipv6_safi_rsclient_route, + show_bgp_ipv6_safi_rsclient_route_cmd, + "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Client\n" + NEIGHBOR_ADDR_STR + "Network in the BGP routing table to display\n") + DEFUN (show_bgp_view_rsclient_prefix, show_bgp_view_rsclient_prefix_cmd, "show bgp view WORD rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M", @@ -10920,6 +11429,87 @@ ALIAS (show_bgp_view_rsclient_prefix, NEIGHBOR_ADDR_STR "IPv6 prefix <network>/<length>, e.g., 3ffe::/16\n") +DEFUN (show_bgp_view_ipv6_safi_rsclient_prefix, + show_bgp_view_ipv6_safi_rsclient_prefix_cmd, + "show bgp view WORD ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M", + SHOW_STR + BGP_STR + "BGP view\n" + "BGP view name\n" + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Client\n" + NEIGHBOR_ADDR_STR + "IP prefix <network>/<length>, e.g., 3ffe::/16\n") +{ + struct bgp *bgp; + struct peer *peer; + safi_t safi; + + /* BGP structure lookup. */ + if (argc == 4) + { + 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; + } + } + else + { + bgp = bgp_get_default (); + if (bgp == NULL) + { + vty_out (vty, "No BGP process is configured%s", VTY_NEWLINE); + return CMD_WARNING; + } + } + + if (argc == 4) { + peer = peer_lookup_in_view (vty, argv[0], argv[2]); + safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + } else { + peer = peer_lookup_in_view (vty, NULL, argv[1]); + safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + } + + if (! peer) + return CMD_WARNING; + + if (! peer->afc[AFI_IP6][safi]) + { + vty_out (vty, "%% Activate the neighbor for the address family first%s", + VTY_NEWLINE); + return CMD_WARNING; +} + + if ( ! CHECK_FLAG (peer->af_flags[AFI_IP6][safi], + PEER_FLAG_RSERVER_CLIENT)) +{ + vty_out (vty, "%% Neighbor is not a Route-Server client%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + return bgp_show_route_in_table (vty, bgp, peer->rib[AFI_IP6][safi], + (argc == 4) ? argv[3] : argv[2], + AFI_IP6, safi, NULL, 1); +} + +ALIAS (show_bgp_view_ipv6_safi_rsclient_prefix, + show_bgp_ipv6_safi_rsclient_prefix_cmd, + "show bgp ipv6 (unicast|multicast) rsclient (A.B.C.D|X:X::X:X) X:X::X:X/M", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Client\n" + NEIGHBOR_ADDR_STR + "IP prefix <network>/<length>, e.g., 3ffe::/16\n") + #endif /* HAVE_IPV6 */ struct bgp_table *bgp_distance_table; @@ -11348,41 +11938,49 @@ bgp_clear_damp_route (struct vty *vty, const char *view_name, if ((table = rn->info) != NULL) if ((rm = bgp_node_match (table, &match)) != NULL) - if (! prefix_check || rm->p.prefixlen == match.prefixlen) - { - ri = rm->info; - while (ri) - { - if (ri->extra && ri->extra->damp_info) - { - ri_temp = ri->next; - bgp_damp_info_free (ri->extra->damp_info, 1); - ri = ri_temp; - } - else - ri = ri->next; - } - } + { + if (! prefix_check || rm->p.prefixlen == match.prefixlen) + { + ri = rm->info; + while (ri) + { + if (ri->extra && ri->extra->damp_info) + { + ri_temp = ri->next; + bgp_damp_info_free (ri->extra->damp_info, 1); + ri = ri_temp; + } + else + ri = ri->next; + } + } + + bgp_unlock_node (rm); + } } } else { if ((rn = bgp_node_match (bgp->rib[afi][safi], &match)) != NULL) - if (! prefix_check || rn->p.prefixlen == match.prefixlen) - { - ri = rn->info; - while (ri) - { - if (ri->extra && ri->extra->damp_info) - { - ri_temp = ri->next; - bgp_damp_info_free (ri->extra->damp_info, 1); - ri = ri_temp; - } - else - ri = ri->next; - } - } + { + if (! prefix_check || rn->p.prefixlen == match.prefixlen) + { + ri = rn->info; + while (ri) + { + if (ri->extra && ri->extra->damp_info) + { + ri_temp = ri->next; + bgp_damp_info_free (ri->extra->damp_info, 1); + ri = ri_temp; + } + else + ri = ri->next; + } + } + + bgp_unlock_node (rn); + } } return CMD_SUCCESS; @@ -11547,8 +12145,6 @@ bgp_config_write_network (struct vty *vty, struct bgp *bgp, { if (bgp_static->backdoor) vty_out (vty, " backdoor"); - if (bgp_static->ttl) - vty_out (vty, " pathlimit %u", bgp_static->ttl); } vty_out (vty, "%s", VTY_NEWLINE); @@ -11637,12 +12233,6 @@ bgp_route_init (void) install_element (BGP_NODE, &bgp_network_backdoor_cmd); install_element (BGP_NODE, &bgp_network_mask_backdoor_cmd); install_element (BGP_NODE, &bgp_network_mask_natural_backdoor_cmd); - install_element (BGP_NODE, &bgp_network_ttl_cmd); - install_element (BGP_NODE, &bgp_network_mask_ttl_cmd); - install_element (BGP_NODE, &bgp_network_mask_natural_ttl_cmd); - 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_cmd); install_element (BGP_NODE, &no_bgp_network_mask_cmd); install_element (BGP_NODE, &no_bgp_network_mask_natural_cmd); @@ -11652,12 +12242,6 @@ bgp_route_init (void) install_element (BGP_NODE, &no_bgp_network_backdoor_cmd); install_element (BGP_NODE, &no_bgp_network_mask_backdoor_cmd); install_element (BGP_NODE, &no_bgp_network_mask_natural_backdoor_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_NODE, &aggregate_address_cmd); install_element (BGP_NODE, &aggregate_address_mask_cmd); @@ -11687,23 +12271,13 @@ bgp_route_init (void) install_element (BGP_IPV4_NODE, &bgp_network_route_map_cmd); install_element (BGP_IPV4_NODE, &bgp_network_mask_route_map_cmd); install_element (BGP_IPV4_NODE, &bgp_network_mask_natural_route_map_cmd); - install_element (BGP_IPV4_NODE, &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_cmd); + install_element (BGP_IPV4_NODE, &no_bgp_network_cmd); install_element (BGP_IPV4_NODE, &no_bgp_network_mask_cmd); install_element (BGP_IPV4_NODE, &no_bgp_network_mask_natural_cmd); install_element (BGP_IPV4_NODE, &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, &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_IPV4_NODE, &no_bgp_network_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); @@ -11732,24 +12306,12 @@ bgp_route_init (void) install_element (BGP_IPV4M_NODE, &bgp_network_route_map_cmd); install_element (BGP_IPV4M_NODE, &bgp_network_mask_route_map_cmd); install_element (BGP_IPV4M_NODE, &bgp_network_mask_natural_route_map_cmd); - install_element (BGP_IPV4M_NODE, &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_IPV4_NODE, &no_bgp_network_cmd); install_element (BGP_IPV4M_NODE, &no_bgp_network_cmd); install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_cmd); install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_cmd); install_element (BGP_IPV4M_NODE, &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, &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); - install_element (BGP_IPV4M_NODE, &no_bgp_network_backdoor_ttl_cmd); - install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_backdoor_ttl_cmd); - install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd); install_element (BGP_IPV4_NODE, &no_bgp_network_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); @@ -11773,12 +12335,15 @@ bgp_route_init (void) install_element (VIEW_NODE, &show_ip_bgp_cmd); install_element (VIEW_NODE, &show_ip_bgp_ipv4_cmd); + install_element (VIEW_NODE, &show_bgp_ipv4_safi_cmd); install_element (VIEW_NODE, &show_ip_bgp_route_cmd); install_element (VIEW_NODE, &show_ip_bgp_ipv4_route_cmd); + install_element (VIEW_NODE, &show_bgp_ipv4_safi_route_cmd); install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_route_cmd); install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_route_cmd); install_element (VIEW_NODE, &show_ip_bgp_prefix_cmd); install_element (VIEW_NODE, &show_ip_bgp_ipv4_prefix_cmd); + install_element (VIEW_NODE, &show_bgp_ipv4_safi_prefix_cmd); install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd); install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd); install_element (VIEW_NODE, &show_ip_bgp_view_cmd); @@ -11804,6 +12369,11 @@ bgp_route_init (void) install_element (VIEW_NODE, &show_ip_bgp_ipv4_community2_cmd); install_element (VIEW_NODE, &show_ip_bgp_ipv4_community3_cmd); install_element (VIEW_NODE, &show_ip_bgp_ipv4_community4_cmd); + install_element (VIEW_NODE, &show_bgp_view_afi_safi_community_all_cmd); + install_element (VIEW_NODE, &show_bgp_view_afi_safi_community_cmd); + install_element (VIEW_NODE, &show_bgp_view_afi_safi_community2_cmd); + install_element (VIEW_NODE, &show_bgp_view_afi_safi_community3_cmd); + install_element (VIEW_NODE, &show_bgp_view_afi_safi_community4_cmd); install_element (VIEW_NODE, &show_ip_bgp_community_exact_cmd); install_element (VIEW_NODE, &show_ip_bgp_community2_exact_cmd); install_element (VIEW_NODE, &show_ip_bgp_community3_exact_cmd); @@ -11822,6 +12392,7 @@ bgp_route_init (void) install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_cmd); install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_routes_cmd); install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_cmd); + install_element (VIEW_NODE, &show_bgp_view_afi_safi_neighbor_adv_recd_routes_cmd); install_element (VIEW_NODE, &show_ip_bgp_neighbor_routes_cmd); install_element (VIEW_NODE, &show_ip_bgp_ipv4_neighbor_routes_cmd); install_element (VIEW_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd); @@ -11839,20 +12410,28 @@ bgp_route_init (void) install_element (VIEW_NODE, &show_ip_bgp_neighbor_flap_cmd); install_element (VIEW_NODE, &show_ip_bgp_neighbor_damp_cmd); install_element (VIEW_NODE, &show_ip_bgp_rsclient_cmd); + install_element (VIEW_NODE, &show_bgp_ipv4_safi_rsclient_cmd); install_element (VIEW_NODE, &show_ip_bgp_rsclient_route_cmd); + install_element (VIEW_NODE, &show_bgp_ipv4_safi_rsclient_route_cmd); install_element (VIEW_NODE, &show_ip_bgp_rsclient_prefix_cmd); + install_element (VIEW_NODE, &show_bgp_ipv4_safi_rsclient_prefix_cmd); install_element (VIEW_NODE, &show_ip_bgp_view_neighbor_advertised_route_cmd); install_element (VIEW_NODE, &show_ip_bgp_view_neighbor_received_routes_cmd); install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_cmd); + install_element (VIEW_NODE, &show_bgp_view_ipv4_safi_rsclient_cmd); install_element (VIEW_NODE, &show_ip_bgp_view_rsclient_route_cmd); + 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); + install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_route_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_route_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_prefix_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_prefix_cmd); + install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_prefix_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_view_route_cmd); @@ -11865,6 +12444,11 @@ bgp_route_init (void) install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community2_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community3_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community4_cmd); + install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community_all_cmd); + install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community_cmd); + install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community2_cmd); + install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community3_cmd); + install_element (RESTRICTED_NODE, &show_bgp_view_afi_safi_community4_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_community_exact_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_community2_exact_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_community3_exact_cmd); @@ -11874,18 +12458,25 @@ bgp_route_init (void) install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community3_exact_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_community4_exact_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_rsclient_route_cmd); + install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_rsclient_route_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_rsclient_prefix_cmd); + install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_rsclient_prefix_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_view_rsclient_route_cmd); + install_element (RESTRICTED_NODE, &show_bgp_view_ipv4_safi_rsclient_route_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_view_rsclient_prefix_cmd); + install_element (RESTRICTED_NODE, &show_bgp_view_ipv4_safi_rsclient_prefix_cmd); install_element (ENABLE_NODE, &show_ip_bgp_cmd); install_element (ENABLE_NODE, &show_ip_bgp_ipv4_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv4_safi_cmd); install_element (ENABLE_NODE, &show_ip_bgp_route_cmd); install_element (ENABLE_NODE, &show_ip_bgp_ipv4_route_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv4_safi_route_cmd); install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_route_cmd); install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_route_cmd); install_element (ENABLE_NODE, &show_ip_bgp_prefix_cmd); install_element (ENABLE_NODE, &show_ip_bgp_ipv4_prefix_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv4_safi_prefix_cmd); install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_prefix_cmd); install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_prefix_cmd); install_element (ENABLE_NODE, &show_ip_bgp_view_cmd); @@ -11911,6 +12502,11 @@ bgp_route_init (void) install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community2_cmd); install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community3_cmd); install_element (ENABLE_NODE, &show_ip_bgp_ipv4_community4_cmd); + install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community_all_cmd); + install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community_cmd); + install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community2_cmd); + install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community3_cmd); + install_element (ENABLE_NODE, &show_bgp_view_afi_safi_community4_cmd); install_element (ENABLE_NODE, &show_ip_bgp_community_exact_cmd); install_element (ENABLE_NODE, &show_ip_bgp_community2_exact_cmd); install_element (ENABLE_NODE, &show_ip_bgp_community3_exact_cmd); @@ -11929,6 +12525,7 @@ bgp_route_init (void) install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_advertised_route_cmd); install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_routes_cmd); install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_received_routes_cmd); + install_element (ENABLE_NODE, &show_bgp_view_afi_safi_neighbor_adv_recd_routes_cmd); install_element (ENABLE_NODE, &show_ip_bgp_neighbor_routes_cmd); install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_routes_cmd); install_element (ENABLE_NODE, &show_ip_bgp_neighbor_received_prefix_filter_cmd); @@ -11946,13 +12543,19 @@ bgp_route_init (void) install_element (ENABLE_NODE, &show_ip_bgp_neighbor_flap_cmd); install_element (ENABLE_NODE, &show_ip_bgp_neighbor_damp_cmd); install_element (ENABLE_NODE, &show_ip_bgp_rsclient_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv4_safi_rsclient_cmd); install_element (ENABLE_NODE, &show_ip_bgp_rsclient_route_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv4_safi_rsclient_route_cmd); install_element (ENABLE_NODE, &show_ip_bgp_rsclient_prefix_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv4_safi_rsclient_prefix_cmd); install_element (ENABLE_NODE, &show_ip_bgp_view_neighbor_advertised_route_cmd); install_element (ENABLE_NODE, &show_ip_bgp_view_neighbor_received_routes_cmd); install_element (ENABLE_NODE, &show_ip_bgp_view_rsclient_cmd); + install_element (ENABLE_NODE, &show_bgp_view_ipv4_safi_rsclient_cmd); install_element (ENABLE_NODE, &show_ip_bgp_view_rsclient_route_cmd); + install_element (ENABLE_NODE, &show_bgp_view_ipv4_safi_rsclient_route_cmd); install_element (ENABLE_NODE, &show_ip_bgp_view_rsclient_prefix_cmd); + install_element (ENABLE_NODE, &show_bgp_view_ipv4_safi_rsclient_prefix_cmd); /* BGP dampening clear commands */ install_element (ENABLE_NODE, &clear_ip_bgp_dampening_cmd); @@ -11970,10 +12573,8 @@ bgp_route_init (void) /* New config IPv6 BGP commands. */ install_element (BGP_IPV6_NODE, &ipv6_bgp_network_cmd); install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd); - install_element (BGP_IPV6_NODE, &ipv6_bgp_network_ttl_cmd); install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_cmd); install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_route_map_cmd); - install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_ttl_cmd); install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_cmd); install_element (BGP_IPV6_NODE, &ipv6_aggregate_address_summary_only_cmd); @@ -11991,10 +12592,13 @@ bgp_route_init (void) install_element (VIEW_NODE, &show_bgp_cmd); install_element (VIEW_NODE, &show_bgp_ipv6_cmd); + install_element (VIEW_NODE, &show_bgp_ipv6_safi_cmd); install_element (VIEW_NODE, &show_bgp_route_cmd); install_element (VIEW_NODE, &show_bgp_ipv6_route_cmd); + install_element (VIEW_NODE, &show_bgp_ipv6_safi_route_cmd); install_element (VIEW_NODE, &show_bgp_prefix_cmd); install_element (VIEW_NODE, &show_bgp_ipv6_prefix_cmd); + install_element (VIEW_NODE, &show_bgp_ipv6_safi_prefix_cmd); install_element (VIEW_NODE, &show_bgp_regexp_cmd); install_element (VIEW_NODE, &show_bgp_ipv6_regexp_cmd); install_element (VIEW_NODE, &show_bgp_prefix_list_cmd); @@ -12040,8 +12644,11 @@ bgp_route_init (void) install_element (VIEW_NODE, &show_bgp_neighbor_damp_cmd); install_element (VIEW_NODE, &show_bgp_ipv6_neighbor_damp_cmd); install_element (VIEW_NODE, &show_bgp_rsclient_cmd); + install_element (VIEW_NODE, &show_bgp_ipv6_safi_rsclient_cmd); install_element (VIEW_NODE, &show_bgp_rsclient_route_cmd); + install_element (VIEW_NODE, &show_bgp_ipv6_safi_rsclient_route_cmd); install_element (VIEW_NODE, &show_bgp_rsclient_prefix_cmd); + install_element (VIEW_NODE, &show_bgp_ipv6_safi_rsclient_prefix_cmd); install_element (VIEW_NODE, &show_bgp_view_cmd); install_element (VIEW_NODE, &show_bgp_view_ipv6_cmd); install_element (VIEW_NODE, &show_bgp_view_route_cmd); @@ -12061,16 +12668,21 @@ bgp_route_init (void) 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_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) */ install_element (RESTRICTED_NODE, &show_bgp_route_cmd); install_element (RESTRICTED_NODE, &show_bgp_ipv6_route_cmd); + install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_route_cmd); install_element (RESTRICTED_NODE, &show_bgp_prefix_cmd); install_element (RESTRICTED_NODE, &show_bgp_ipv6_prefix_cmd); + install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_prefix_cmd); install_element (RESTRICTED_NODE, &show_bgp_community_cmd); install_element (RESTRICTED_NODE, &show_bgp_ipv6_community_cmd); install_element (RESTRICTED_NODE, &show_bgp_community2_cmd); @@ -12088,7 +12700,9 @@ bgp_route_init (void) install_element (RESTRICTED_NODE, &show_bgp_community4_exact_cmd); install_element (RESTRICTED_NODE, &show_bgp_ipv6_community4_exact_cmd); install_element (RESTRICTED_NODE, &show_bgp_rsclient_route_cmd); + install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_rsclient_route_cmd); install_element (RESTRICTED_NODE, &show_bgp_rsclient_prefix_cmd); + install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_rsclient_prefix_cmd); install_element (RESTRICTED_NODE, &show_bgp_view_route_cmd); install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_route_cmd); install_element (RESTRICTED_NODE, &show_bgp_view_prefix_cmd); @@ -12096,14 +12710,19 @@ bgp_route_init (void) install_element (RESTRICTED_NODE, &show_bgp_view_neighbor_received_prefix_filter_cmd); install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_neighbor_received_prefix_filter_cmd); install_element (RESTRICTED_NODE, &show_bgp_view_rsclient_route_cmd); + install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_safi_rsclient_route_cmd); install_element (RESTRICTED_NODE, &show_bgp_view_rsclient_prefix_cmd); + install_element (RESTRICTED_NODE, &show_bgp_view_ipv6_safi_rsclient_prefix_cmd); install_element (ENABLE_NODE, &show_bgp_cmd); install_element (ENABLE_NODE, &show_bgp_ipv6_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv6_safi_cmd); install_element (ENABLE_NODE, &show_bgp_route_cmd); install_element (ENABLE_NODE, &show_bgp_ipv6_route_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv6_safi_route_cmd); install_element (ENABLE_NODE, &show_bgp_prefix_cmd); install_element (ENABLE_NODE, &show_bgp_ipv6_prefix_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv6_safi_prefix_cmd); install_element (ENABLE_NODE, &show_bgp_regexp_cmd); install_element (ENABLE_NODE, &show_bgp_ipv6_regexp_cmd); install_element (ENABLE_NODE, &show_bgp_prefix_list_cmd); @@ -12149,8 +12768,11 @@ bgp_route_init (void) install_element (ENABLE_NODE, &show_bgp_neighbor_damp_cmd); install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_damp_cmd); install_element (ENABLE_NODE, &show_bgp_rsclient_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv6_safi_rsclient_cmd); install_element (ENABLE_NODE, &show_bgp_rsclient_route_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv6_safi_rsclient_route_cmd); install_element (ENABLE_NODE, &show_bgp_rsclient_prefix_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv6_safi_rsclient_prefix_cmd); install_element (ENABLE_NODE, &show_bgp_view_cmd); install_element (ENABLE_NODE, &show_bgp_view_ipv6_cmd); install_element (ENABLE_NODE, &show_bgp_view_route_cmd); @@ -12170,8 +12792,11 @@ bgp_route_init (void) install_element (ENABLE_NODE, &show_bgp_view_neighbor_damp_cmd); install_element (ENABLE_NODE, &show_bgp_view_ipv6_neighbor_damp_cmd); install_element (ENABLE_NODE, &show_bgp_view_rsclient_cmd); + install_element (ENABLE_NODE, &show_bgp_view_ipv6_safi_rsclient_cmd); install_element (ENABLE_NODE, &show_bgp_view_rsclient_route_cmd); + 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); @@ -12292,6 +12917,54 @@ 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); + install_element (BGP_NODE, &bgp_network_mask_natural_ttl_cmd); + 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); + install_element (BGP_IPV4M_NODE, &no_bgp_network_backdoor_ttl_cmd); + install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_backdoor_ttl_cmd); + install_element (BGP_IPV4M_NODE, &no_bgp_network_mask_natural_backdoor_ttl_cmd); + +#ifdef HAVE_IPV6 + install_element (BGP_IPV6_NODE, &ipv6_bgp_network_ttl_cmd); + install_element (BGP_IPV6_NODE, &no_ipv6_bgp_network_ttl_cmd); +#endif } void diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 5eed3486..3e528596 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -116,9 +116,6 @@ struct bgp_static /* MPLS label. */ u_char tag[3]; - - /* AS-Pathlimit TTL */ - u_char ttl; }; /* Flags which indicate a route is unuseable in some form */ diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index aa7dbce1..255b25ae 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -92,107 +92,15 @@ o Cisco route-map origin : Done tag : (This will not be implemented by bgpd) weight : Done - pathlimit : Done o Local extention set ipv6 next-hop global: Done set ipv6 next-hop local : Done - set pathlimit ttl : Done set as-path exclude : Done - match pathlimit as : Done */ -/* Compiles either AS or TTL argument. It is amused the VTY code - * has already range-checked the values to be suitable as TTL or ASN - */ -static void * -route_pathlimit_compile (const char *arg) -{ - unsigned long tmp; - u_int32_t *val; - char *endptr = NULL; - - /* TTL or AS value shoud be integer. */ - if (! all_digit (arg)) - return NULL; - - tmp = strtoul (arg, &endptr, 10); - if (*endptr != '\0' || tmp == ULONG_MAX || tmp > UINT32_MAX) - return NULL; - - if (!(val = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)))) - return NULL; - - *val = tmp; - - return val; -} - -static void -route_pathlimit_free (void *rule) -{ - XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); -} - -static route_map_result_t -route_match_pathlimit_as (void *rule, struct prefix *prefix, route_map_object_t type, - void *object) -{ - struct bgp_info *info = object; - struct attr *attr = info->attr; - uint32_t as = *(uint32_t *)rule; - - if (type != RMAP_BGP) - return RMAP_NOMATCH; - - if (!attr->pathlimit.as) - return RMAP_NOMATCH; - - if (as == attr->pathlimit.as) - return RMAP_MATCH; - - return RMAP_NOMATCH; -} - -/* 'match pathlimit as' */ -struct route_map_rule_cmd route_match_pathlimit_as_cmd = -{ - "pathlimit as", - route_match_pathlimit_as, - route_pathlimit_compile, - route_pathlimit_free -}; - -/* Set pathlimit TTL. */ -static route_map_result_t -route_set_pathlimit_ttl (void *rule, struct prefix *prefix, - route_map_object_t type, void *object) -{ - struct bgp_info *info = object; - struct attr *attr = info->attr; - u_char ttl = *(uint32_t *)rule; - - if (type == RMAP_BGP) - { - attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_AS_PATHLIMIT); - attr->pathlimit.ttl = ttl; - attr->pathlimit.as = 0; - } - - return RMAP_OKAY; -} - -/* Set local preference rule structure. */ -struct route_map_rule_cmd route_set_pathlimit_ttl_cmd = -{ - "pathlimit ttl", - route_set_pathlimit_ttl, - route_pathlimit_compile, - route_pathlimit_free, -}; - /* 'match peer (A.B.C.D|X:X::X:X)' */ /* Compares the peer specified in the 'match peer' clause with the peer @@ -1485,6 +1393,13 @@ route_set_community_delete (void *rule, struct prefix *prefix, new = community_uniq_sort (merge); community_free (merge); + /* HACK: if the old community is not intern'd, + * we should free it here, or all reference to it may be lost. + * Really need to cleanup attribute caching sometime. + */ + if (old->refcnt == 0) + community_free (old); + if (new->size == 0) { binfo->attr->community = NULL; @@ -3743,17 +3658,17 @@ ALIAS (no_set_originator_id, "BGP originator ID attribute\n" "IP address of originator\n") -DEFUN (set_pathlimit_ttl, +DEFUN_DEPRECATED (set_pathlimit_ttl, set_pathlimit_ttl_cmd, "set pathlimit ttl <1-255>", SET_STR "BGP AS-Pathlimit attribute\n" "Set AS-Path Hop-count TTL\n") { - return bgp_route_set_add (vty, vty->index, "pathlimit ttl", argv[0]); + return CMD_SUCCESS; } -DEFUN (no_set_pathlimit_ttl, +DEFUN_DEPRECATED (no_set_pathlimit_ttl, no_set_pathlimit_ttl_cmd, "no set pathlimit ttl", NO_STR @@ -3761,10 +3676,7 @@ DEFUN (no_set_pathlimit_ttl, "BGP AS-Pathlimit attribute\n" "Set AS-Path Hop-count TTL\n") { - if (argc == 0) - return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", NULL); - - return bgp_route_set_delete (vty, vty->index, "pathlimit ttl", argv[0]); + return CMD_SUCCESS; } ALIAS (no_set_pathlimit_ttl, @@ -3775,17 +3687,17 @@ ALIAS (no_set_pathlimit_ttl, "BGP AS-Pathlimit attribute\n" "Set AS-Path Hop-count TTL\n") -DEFUN (match_pathlimit_as, +DEFUN_DEPRECATED (match_pathlimit_as, match_pathlimit_as_cmd, "match pathlimit as <1-65535>", MATCH_STR "BGP AS-Pathlimit attribute\n" "Match Pathlimit AS number\n") { - return bgp_route_match_add (vty, vty->index, "pathlimit as", argv[0]); + return CMD_SUCCESS; } -DEFUN (no_match_pathlimit_as, +DEFUN_DEPRECATED (no_match_pathlimit_as, no_match_pathlimit_as_cmd, "no match pathlimit as", NO_STR @@ -3793,10 +3705,7 @@ DEFUN (no_match_pathlimit_as, "BGP AS-Pathlimit attribute\n" "Match Pathlimit AS number\n") { - if (argc == 0) - return bgp_route_match_delete (vty, vty->index, "pathlimit as", NULL); - - return bgp_route_match_delete (vty, vty->index, "pathlimit as", argv[0]); + return CMD_SUCCESS; } ALIAS (no_match_pathlimit_as, @@ -3959,10 +3868,9 @@ bgp_route_map_init (void) install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd); #endif /* HAVE_IPV6 */ - /* AS-Pathlimit */ - route_map_install_match (&route_match_pathlimit_as_cmd); - route_map_install_set (&route_set_pathlimit_ttl_cmd); - + /* AS-Pathlimit: functionality removed, commands kept for + * compatibility. + */ install_element (RMAP_NODE, &set_pathlimit_ttl_cmd); install_element (RMAP_NODE, &no_set_pathlimit_ttl_cmd); install_element (RMAP_NODE, &no_set_pathlimit_ttl_val_cmd); diff --git a/bgpd/bgp_table.c b/bgpd/bgp_table.c index 91cab606..a249c23d 100644 --- a/bgpd/bgp_table.c +++ b/bgpd/bgp_table.c @@ -350,7 +350,6 @@ bgp_node_get (struct bgp_table *const table, struct prefix *p) if (new->p.prefixlen != p->prefixlen) { match = new; - bgp_lock_node (match); new = bgp_node_set (table, p); set_link (match, new); table->count++; diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 88be52e2..e7e7dba1 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -213,6 +213,12 @@ bgp_vty_return (struct vty *vty, int ret) case BGP_ERR_TCPSIG_FAILED: str = "Error while applying TCP-Sig to session(s)"; break; + case BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK: + str = "ebgp-multihop and ttl-security cannot be configured together"; + break; + case BGP_ERR_NO_IBGP_WITH_TTLHACK: + str = "ttl-security only allowed for EBGP peers"; + break; } if (str) { @@ -2636,9 +2642,7 @@ peer_ebgp_multihop_set_vty (struct vty *vty, const char *ip_str, else VTY_GET_INTEGER_RANGE ("TTL", ttl, ttl_str, 1, 255); - peer_ebgp_multihop_set (peer, ttl); - - return CMD_SUCCESS; + return bgp_vty_return (vty, peer_ebgp_multihop_set (peer, ttl)); } static int @@ -2650,9 +2654,7 @@ peer_ebgp_multihop_unset_vty (struct vty *vty, const char *ip_str) if (! peer) return CMD_WARNING; - peer_ebgp_multihop_unset (peer); - - return CMD_SUCCESS; + return bgp_vty_return (vty, peer_ebgp_multihop_unset (peer)); } /* neighbor ebgp-multihop. */ @@ -3954,6 +3956,42 @@ DEFUN (no_neighbor_allowas_in, return bgp_vty_return (vty, ret); } +DEFUN (neighbor_ttl_security, + neighbor_ttl_security_cmd, + NEIGHBOR_CMD2 "ttl-security hops <1-254>", + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Specify the maximum number of hops to the BGP peer\n") +{ + struct peer *peer; + int gtsm_hops; + + peer = peer_and_group_lookup_vty (vty, argv[0]); + if (! peer) + return CMD_WARNING; + + VTY_GET_INTEGER_RANGE ("", gtsm_hops, argv[1], 1, 254); + + return bgp_vty_return (vty, peer_ttl_security_hops_set (peer, gtsm_hops)); +} + +DEFUN (no_neighbor_ttl_security, + no_neighbor_ttl_security_cmd, + NO_NEIGHBOR_CMD2 "ttl-security hops <1-254>", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Specify the maximum number of hops to the BGP peer\n") +{ + struct peer *peer; + + peer = peer_and_group_lookup_vty (vty, argv[0]); + if (! peer) + return CMD_WARNING; + + return bgp_vty_return (vty, peer_ttl_security_hops_unset (peer)); +} + /* Address family configuration. */ DEFUN (address_family_ipv4, address_family_ipv4_cmd, @@ -6864,6 +6902,16 @@ DEFUN (show_ip_bgp_ipv4_summary, return bgp_show_summary_vty (vty, NULL, AFI_IP, SAFI_UNICAST); } +ALIAS (show_ip_bgp_ipv4_summary, + show_bgp_ipv4_safi_summary_cmd, + "show bgp ipv4 (unicast|multicast) summary", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Summary of BGP neighbor status\n") + DEFUN (show_ip_bgp_instance_ipv4_summary, show_ip_bgp_instance_ipv4_summary_cmd, "show ip bgp view WORD ipv4 (unicast|multicast) summary", @@ -6883,6 +6931,18 @@ DEFUN (show_ip_bgp_instance_ipv4_summary, return bgp_show_summary_vty (vty, argv[0], AFI_IP, SAFI_UNICAST); } +ALIAS (show_ip_bgp_instance_ipv4_summary, + show_bgp_instance_ipv4_safi_summary_cmd, + "show bgp view WORD ipv4 (unicast|multicast) summary", + SHOW_STR + BGP_STR + "BGP view\n" + "View name\n" + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Summary of BGP neighbor status\n") + DEFUN (show_ip_bgp_vpnv4_all_summary, show_ip_bgp_vpnv4_all_summary_cmd, "show ip bgp vpnv4 all summary", @@ -6961,6 +7021,40 @@ ALIAS (show_bgp_instance_summary, "Address family\n" "Summary of BGP neighbor status\n") +DEFUN (show_bgp_ipv6_safi_summary, + show_bgp_ipv6_safi_summary_cmd, + "show bgp ipv6 (unicast|multicast) summary", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Summary of BGP neighbor status\n") +{ + if (strncmp (argv[0], "m", 1) == 0) + return bgp_show_summary_vty (vty, NULL, AFI_IP6, SAFI_MULTICAST); + + return bgp_show_summary_vty (vty, NULL, AFI_IP6, SAFI_UNICAST); +} + +DEFUN (show_bgp_instance_ipv6_safi_summary, + show_bgp_instance_ipv6_safi_summary_cmd, + "show bgp view WORD ipv6 (unicast|multicast) summary", + SHOW_STR + BGP_STR + "BGP view\n" + "View name\n" + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Summary of BGP neighbor status\n") +{ + if (strncmp (argv[1], "m", 1) == 0) + return bgp_show_summary_vty (vty, argv[0], AFI_IP6, SAFI_MULTICAST); + + return bgp_show_summary_vty (vty, argv[0], AFI_IP6, SAFI_UNICAST); +} + /* old command */ DEFUN (show_ipv6_bgp_summary, show_ipv6_bgp_summary_cmd, @@ -7552,10 +7646,16 @@ bgp_show_peer (struct vty *vty, struct peer *p) p->host, VTY_NEWLINE); } - /* EBGP Multihop */ - if (peer_sort (p) != BGP_PEER_IBGP && p->ttl > 1) - vty_out (vty, " External BGP neighbor may be up to %d hops away.%s", - p->ttl, VTY_NEWLINE); + /* EBGP Multihop and GTSM */ + if (peer_sort (p) != BGP_PEER_IBGP) + { + if (p->gtsm_hops > 0) + vty_out (vty, " External BGP neighbor may be up to %d hops away.%s", + p->gtsm_hops, VTY_NEWLINE); + else if (p->ttl > 1) + vty_out (vty, " External BGP neighbor may be up to %d hops away.%s", + p->ttl, VTY_NEWLINE); + } /* Local address. */ if (p->su_local) @@ -8162,6 +8262,41 @@ DEFUN (show_ip_bgp_instance_ipv4_rsclient_summary, return bgp_show_rsclient_summary_vty (vty, argv[0], AFI_IP, SAFI_UNICAST); } +DEFUN (show_bgp_instance_ipv4_safi_rsclient_summary, + show_bgp_instance_ipv4_safi_rsclient_summary_cmd, + "show bgp view WORD ipv4 (unicast|multicast) rsclient summary", + SHOW_STR + BGP_STR + "BGP view\n" + "View name\n" + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Clients\n" + "Summary of all Route Server Clients\n") +{ + safi_t safi; + + if (argc == 2) { + safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + return bgp_show_rsclient_summary_vty (vty, argv[0], AFI_IP, safi); + } else { + safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + return bgp_show_rsclient_summary_vty (vty, NULL, AFI_IP, safi); + } +} + +ALIAS (show_bgp_instance_ipv4_safi_rsclient_summary, + show_bgp_ipv4_safi_rsclient_summary_cmd, + "show bgp ipv4 (unicast|multicast) rsclient summary", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Clients\n" + "Summary of all Route Server Clients\n") + #ifdef HAVE_IPV6 DEFUN (show_bgp_rsclient_summary, show_bgp_rsclient_summary_cmd, @@ -8206,6 +8341,42 @@ ALIAS (show_bgp_instance_rsclient_summary, "Address family\n" "Information about Route Server Clients\n" "Summary of all Route Server Clients\n") + +DEFUN (show_bgp_instance_ipv6_safi_rsclient_summary, + show_bgp_instance_ipv6_safi_rsclient_summary_cmd, + "show bgp view WORD ipv6 (unicast|multicast) rsclient summary", + SHOW_STR + BGP_STR + "BGP view\n" + "View name\n" + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Clients\n" + "Summary of all Route Server Clients\n") +{ + safi_t safi; + + if (argc == 2) { + safi = (strncmp (argv[1], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + return bgp_show_rsclient_summary_vty (vty, argv[0], AFI_IP6, safi); + } else { + safi = (strncmp (argv[0], "m", 1) == 0) ? SAFI_MULTICAST : SAFI_UNICAST; + return bgp_show_rsclient_summary_vty (vty, NULL, AFI_IP6, safi); + } +} + +ALIAS (show_bgp_instance_ipv6_safi_rsclient_summary, + show_bgp_ipv6_safi_rsclient_summary_cmd, + "show bgp ipv6 (unicast|multicast) rsclient summary", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Information about Route Server Clients\n" + "Summary of all Route Server Clients\n") + #endif /* HAVE IPV6 */ /* Redistribute VTY commands. */ @@ -9752,38 +9923,50 @@ bgp_vty_init (void) install_element (VIEW_NODE, &show_ip_bgp_summary_cmd); install_element (VIEW_NODE, &show_ip_bgp_instance_summary_cmd); install_element (VIEW_NODE, &show_ip_bgp_ipv4_summary_cmd); + install_element (VIEW_NODE, &show_bgp_ipv4_safi_summary_cmd); install_element (VIEW_NODE, &show_ip_bgp_instance_ipv4_summary_cmd); + install_element (VIEW_NODE, &show_bgp_instance_ipv4_safi_summary_cmd); install_element (VIEW_NODE, &show_ip_bgp_vpnv4_all_summary_cmd); install_element (VIEW_NODE, &show_ip_bgp_vpnv4_rd_summary_cmd); #ifdef HAVE_IPV6 install_element (VIEW_NODE, &show_bgp_summary_cmd); install_element (VIEW_NODE, &show_bgp_instance_summary_cmd); install_element (VIEW_NODE, &show_bgp_ipv6_summary_cmd); + install_element (VIEW_NODE, &show_bgp_ipv6_safi_summary_cmd); install_element (VIEW_NODE, &show_bgp_instance_ipv6_summary_cmd); + install_element (VIEW_NODE, &show_bgp_instance_ipv6_safi_summary_cmd); #endif /* HAVE_IPV6 */ install_element (RESTRICTED_NODE, &show_ip_bgp_summary_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_instance_summary_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_summary_cmd); + install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_summary_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_instance_ipv4_summary_cmd); + install_element (RESTRICTED_NODE, &show_bgp_instance_ipv4_safi_summary_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_all_summary_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_vpnv4_rd_summary_cmd); #ifdef HAVE_IPV6 install_element (RESTRICTED_NODE, &show_bgp_summary_cmd); install_element (RESTRICTED_NODE, &show_bgp_instance_summary_cmd); install_element (RESTRICTED_NODE, &show_bgp_ipv6_summary_cmd); + install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_summary_cmd); install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_summary_cmd); + install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_safi_summary_cmd); #endif /* HAVE_IPV6 */ install_element (ENABLE_NODE, &show_ip_bgp_summary_cmd); install_element (ENABLE_NODE, &show_ip_bgp_instance_summary_cmd); install_element (ENABLE_NODE, &show_ip_bgp_ipv4_summary_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv4_safi_summary_cmd); install_element (ENABLE_NODE, &show_ip_bgp_instance_ipv4_summary_cmd); + install_element (ENABLE_NODE, &show_bgp_instance_ipv4_safi_summary_cmd); install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_all_summary_cmd); install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_rd_summary_cmd); #ifdef HAVE_IPV6 install_element (ENABLE_NODE, &show_bgp_summary_cmd); install_element (ENABLE_NODE, &show_bgp_instance_summary_cmd); install_element (ENABLE_NODE, &show_bgp_ipv6_summary_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv6_safi_summary_cmd); install_element (ENABLE_NODE, &show_bgp_instance_ipv6_summary_cmd); + install_element (ENABLE_NODE, &show_bgp_instance_ipv6_safi_summary_cmd); #endif /* HAVE_IPV6 */ /* "show ip bgp neighbors" commands. */ @@ -9847,28 +10030,40 @@ bgp_vty_init (void) install_element (VIEW_NODE, &show_ip_bgp_instance_rsclient_summary_cmd); install_element (VIEW_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd); install_element (VIEW_NODE, &show_ip_bgp_instance_ipv4_rsclient_summary_cmd); + install_element (VIEW_NODE, &show_bgp_instance_ipv4_safi_rsclient_summary_cmd); + install_element (VIEW_NODE, &show_bgp_ipv4_safi_rsclient_summary_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_rsclient_summary_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_instance_rsclient_summary_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd); install_element (RESTRICTED_NODE, &show_ip_bgp_instance_ipv4_rsclient_summary_cmd); + install_element (RESTRICTED_NODE, &show_bgp_instance_ipv4_safi_rsclient_summary_cmd); + install_element (RESTRICTED_NODE, &show_bgp_ipv4_safi_rsclient_summary_cmd); install_element (ENABLE_NODE, &show_ip_bgp_rsclient_summary_cmd); install_element (ENABLE_NODE, &show_ip_bgp_instance_rsclient_summary_cmd); install_element (ENABLE_NODE, &show_ip_bgp_ipv4_rsclient_summary_cmd); install_element (ENABLE_NODE, &show_ip_bgp_instance_ipv4_rsclient_summary_cmd); + install_element (ENABLE_NODE, &show_bgp_instance_ipv4_safi_rsclient_summary_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv4_safi_rsclient_summary_cmd); #ifdef HAVE_IPV6 install_element (VIEW_NODE, &show_bgp_rsclient_summary_cmd); install_element (VIEW_NODE, &show_bgp_ipv6_rsclient_summary_cmd); install_element (VIEW_NODE, &show_bgp_instance_rsclient_summary_cmd); install_element (VIEW_NODE, &show_bgp_instance_ipv6_rsclient_summary_cmd); + install_element (VIEW_NODE, &show_bgp_instance_ipv6_safi_rsclient_summary_cmd); + install_element (VIEW_NODE, &show_bgp_ipv6_safi_rsclient_summary_cmd); install_element (RESTRICTED_NODE, &show_bgp_rsclient_summary_cmd); install_element (RESTRICTED_NODE, &show_bgp_ipv6_rsclient_summary_cmd); install_element (RESTRICTED_NODE, &show_bgp_instance_rsclient_summary_cmd); install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_rsclient_summary_cmd); + install_element (RESTRICTED_NODE, &show_bgp_instance_ipv6_safi_rsclient_summary_cmd); + install_element (RESTRICTED_NODE, &show_bgp_ipv6_safi_rsclient_summary_cmd); install_element (ENABLE_NODE, &show_bgp_rsclient_summary_cmd); install_element (ENABLE_NODE, &show_bgp_ipv6_rsclient_summary_cmd); install_element (ENABLE_NODE, &show_bgp_instance_rsclient_summary_cmd); install_element (ENABLE_NODE, &show_bgp_instance_ipv6_rsclient_summary_cmd); + install_element (ENABLE_NODE, &show_bgp_instance_ipv6_safi_rsclient_summary_cmd); + install_element (ENABLE_NODE, &show_bgp_ipv6_safi_rsclient_summary_cmd); #endif /* HAVE_IPV6 */ /* "show ip bgp paths" commands. */ @@ -9909,6 +10104,10 @@ bgp_vty_init (void) install_element (BGP_IPV6_NODE, &no_bgp_redistribute_ipv6_metric_rmap_cmd); #endif /* HAVE_IPV6 */ + /* ttl_security commands */ + install_element (BGP_NODE, &neighbor_ttl_security_cmd); + install_element (BGP_NODE, &no_neighbor_ttl_security_cmd); + /* "show bgp memory" commands. */ install_element (VIEW_NODE, &show_bgp_memory_cmd); install_element (RESTRICTED_NODE, &show_bgp_memory_cmd); @@ -9952,7 +10151,7 @@ community_list_perror (struct vty *vty, int ret) switch (ret) { case COMMUNITY_LIST_ERR_CANT_FIND_LIST: - vty_out (vty, "%% Can't find communit-list%s", VTY_NEWLINE); + vty_out (vty, "%% Can't find community-list%s", VTY_NEWLINE); break; case COMMUNITY_LIST_ERR_MALFORMED_VAL: vty_out (vty, "%% Malformed community-list value%s", VTY_NEWLINE); @@ -10313,7 +10512,7 @@ DEFUN (show_ip_community_list_arg, list = community_list_lookup (bgp_clist, argv[0], COMMUNITY_LIST_MASTER); if (! list) { - vty_out (vty, "%% Can't find communit-list%s", VTY_NEWLINE); + vty_out (vty, "%% Can't find community-list%s", VTY_NEWLINE); return CMD_WARNING; } @@ -10663,7 +10862,7 @@ DEFUN (show_ip_extcommunity_list_arg, list = community_list_lookup (bgp_clist, argv[0], EXTCOMMUNITY_LIST_MASTER); if (! list) { - vty_out (vty, "%% Can't find extcommunit-list%s", VTY_NEWLINE); + vty_out (vty, "%% Can't find extcommunity-list%s", VTY_NEWLINE); return CMD_WARNING; } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 882fe37c..ee0cc5da 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1379,6 +1379,7 @@ peer_group_get (struct bgp *bgp, const char *name) group->conf->group = group; group->conf->as = 0; group->conf->ttl = 1; + group->conf->gtsm_hops = 0; group->conf->v_routeadv = BGP_DEFAULT_EBGP_ROUTEADV; UNSET_FLAG (group->conf->config, PEER_CONFIG_TIMER); UNSET_FLAG (group->conf->config, PEER_CONFIG_CONNECT); @@ -1416,6 +1417,9 @@ peer_group2peer_config_copy (struct peer_group *group, struct peer *peer, /* TTL */ peer->ttl = conf->ttl; + /* GTSM hops */ + peer->gtsm_hops = conf->gtsm_hops; + /* Weight */ peer->weight = conf->weight; @@ -2663,10 +2667,36 @@ peer_ebgp_multihop_set (struct peer *peer, int ttl) { struct peer_group *group; struct listnode *node, *nnode; + struct peer *peer1; if (peer_sort (peer) == BGP_PEER_IBGP) return 0; + /* see comment in peer_ttl_security_hops_set() */ + if (ttl != MAXTTL) + { + if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) + { + group = peer->group; + if (group->conf->gtsm_hops != 0) + return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK; + + for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1)) + { + if (peer_sort (peer1) == BGP_PEER_IBGP) + continue; + + if (peer1->gtsm_hops != 0) + return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK; + } + } + else + { + if (peer->gtsm_hops != 0) + return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK; + } + } + peer->ttl = ttl; if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) @@ -2700,6 +2730,9 @@ peer_ebgp_multihop_unset (struct peer *peer) if (peer_sort (peer) == BGP_PEER_IBGP) return 0; + if (peer->gtsm_hops != 0 && peer->ttl != MAXTTL) + return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK; + if (peer_group_active (peer)) peer->ttl = peer->group->conf->ttl; else @@ -4331,6 +4364,137 @@ peer_maximum_prefix_unset (struct peer *peer, afi_t afi, safi_t safi) return 0; } +/* Set # of hops between us and BGP peer. */ +int +peer_ttl_security_hops_set (struct peer *peer, int gtsm_hops) +{ + struct peer_group *group; + struct listnode *node, *nnode; + struct peer *peer1; + int ret; + + zlog_debug ("peer_ttl_security_hops_set: set gtsm_hops to %d for %s", gtsm_hops, peer->host); + + if (peer_sort (peer) == BGP_PEER_IBGP) + return BGP_ERR_NO_IBGP_WITH_TTLHACK; + + /* We cannot configure ttl-security hops when ebgp-multihop is already + set. For non peer-groups, the check is simple. For peer-groups, it's + slightly messy, because we need to check both the peer-group structure + and all peer-group members for any trace of ebgp-multihop configuration + before actually applying the ttl-security rules. Cisco really made a + mess of this configuration parameter, and OpenBGPD got it right. + */ + + if (peer->gtsm_hops == 0) { + if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) + { + group = peer->group; + if (group->conf->ttl != 1) + return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK; + + for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer1)) + { + if (peer_sort (peer1) == BGP_PEER_IBGP) + continue; + + if (peer1->ttl != 1) + return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK; + } + } + else + { + if (peer->ttl != 1) + return BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK; + } + /* specify MAXTTL on outgoing packets */ + ret = peer_ebgp_multihop_set (peer, MAXTTL); + if (ret != 0) + return ret; + } + + peer->gtsm_hops = gtsm_hops; + + if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) + { + if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP) + sockopt_minttl (peer->su.sa.sa_family, peer->fd, MAXTTL + 1 - gtsm_hops); + } + else + { + group = peer->group; + for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer)) + { + if (peer_sort (peer) == BGP_PEER_IBGP) + continue; + + peer->gtsm_hops = group->conf->gtsm_hops; + + /* Change setting of existing peer + * established then change value (may break connectivity) + * not established yet (teardown session and restart) + * no session then do nothing (will get handled by next connection) + */ + if (peer->status == Established) + { + if (peer->fd >= 0 && peer->gtsm_hops != 0) + sockopt_minttl (peer->su.sa.sa_family, peer->fd, + MAXTTL + 1 - peer->gtsm_hops); + } + else if (peer->status < Established) + { + if (BGP_DEBUG (events, EVENTS)) + zlog_debug ("%s Min-ttl changed", peer->host); + BGP_EVENT_ADD (peer, BGP_Stop); + } + } + } + + return 0; +} + +int +peer_ttl_security_hops_unset (struct peer *peer) +{ + struct peer_group *group; + struct listnode *node, *nnode; + struct peer *opeer; + + zlog_debug ("peer_ttl_security_hops_unset: set gtsm_hops to zero for %s", peer->host); + + if (peer_sort (peer) == BGP_PEER_IBGP) + return 0; + + /* if a peer-group member, then reset to peer-group default rather than 0 */ + if (peer_group_active (peer)) + peer->gtsm_hops = peer->group->conf->gtsm_hops; + else + peer->gtsm_hops = 0; + + opeer = peer; + if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) + { + if (peer->fd >= 0 && peer_sort (peer) != BGP_PEER_IBGP) + sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0); + } + else + { + group = peer->group; + for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer)) + { + if (peer_sort (peer) == BGP_PEER_IBGP) + continue; + + peer->gtsm_hops = 0; + + if (peer->fd >= 0) + sockopt_minttl (peer->su.sa.sa_family, peer->fd, 0); + } + } + + return peer_ebgp_multihop_unset (opeer); +} + int peer_clear (struct peer *peer) { @@ -4635,12 +4799,19 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp, vty_out (vty, " neighbor %s passive%s", addr, VTY_NEWLINE); /* EBGP multihop. */ - if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1) + if (peer_sort (peer) != BGP_PEER_IBGP && peer->ttl != 1 && + !(peer->gtsm_hops != 0 && peer->ttl == MAXTTL)) if (! peer_group_active (peer) || g_peer->ttl != peer->ttl) vty_out (vty, " neighbor %s ebgp-multihop %d%s", addr, peer->ttl, VTY_NEWLINE); + /* ttl-security hops */ + if (peer_sort (peer) != BGP_PEER_IBGP && peer->gtsm_hops != 0) + if (! peer_group_active (peer) || g_peer->gtsm_hops != peer->gtsm_hops) + vty_out (vty, " neighbor %s ttl-security hops %d%s", addr, + peer->gtsm_hops, VTY_NEWLINE); + /* disable-connected-check. */ if (CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK)) if (! peer_group_active (peer) || diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index a5afaedc..4da19e71 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -303,6 +303,7 @@ struct peer /* Peer information */ int fd; /* File descriptor */ int ttl; /* TTL of TCP connection to the peer. */ + int gtsm_hops; /* minimum hopcount to peer */ char *desc; /* Description of the peer. */ unsigned short port; /* Destination port for peer */ char *host; /* Printable address of the peer. */ @@ -800,7 +801,9 @@ enum bgp_clear_type #define BGP_ERR_LOCAL_AS_ALLOWED_ONLY_FOR_EBGP -27 #define BGP_ERR_CANNOT_HAVE_LOCAL_AS_SAME_AS -28 #define BGP_ERR_TCPSIG_FAILED -29 -#define BGP_ERR_MAX -30 +#define BGP_ERR_NO_EBGP_MULTIHOP_WITH_TTLHACK -30 +#define BGP_ERR_NO_IBGP_WITH_TTLHACK -31 +#define BGP_ERR_MAX -32 extern struct bgp_master *bm; @@ -953,4 +956,7 @@ extern int peer_maximum_prefix_unset (struct peer *, afi_t, safi_t); extern int peer_clear (struct peer *); extern int peer_clear_soft (struct peer *, afi_t, safi_t, enum bgp_clear_type); +extern int peer_ttl_security_hops_set (struct peer *, int); +extern int peer_ttl_security_hops_unset (struct peer *); + #endif /* _QUAGGA_BGPD_H */ |