2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2002-12-13 21:15:29 +01:00
|
|
|
/* BGP Extended Communities Attribute
|
2017-05-13 10:25:29 +02:00
|
|
|
* Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
|
|
|
|
*/
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "hash.h"
|
|
|
|
#include "memory.h"
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "command.h"
|
2015-05-20 03:03:47 +02:00
|
|
|
#include "queue.h"
|
2016-01-07 16:03:01 +01:00
|
|
|
#include "filter.h"
|
2017-09-04 00:57:30 +02:00
|
|
|
#include "jhash.h"
|
2017-09-07 15:58:18 +02:00
|
|
|
#include "stream.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2020-10-15 21:33:09 +02:00
|
|
|
#include "lib/printfrr.h"
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "bgpd/bgpd.h"
|
|
|
|
#include "bgpd/bgp_ecommunity.h"
|
2016-11-15 11:00:39 +01:00
|
|
|
#include "bgpd/bgp_lcommunity.h"
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
#include "bgpd/bgp_aspath.h"
|
2018-01-15 19:17:02 +01:00
|
|
|
#include "bgpd/bgp_flowspec_private.h"
|
2018-03-08 19:13:44 +01:00
|
|
|
#include "bgpd/bgp_pbr.h"
|
2018-01-15 19:17:02 +01:00
|
|
|
|
|
|
|
/* struct used to dump the rate contained in FS set traffic-rate EC */
|
|
|
|
union traffic_rate {
|
|
|
|
float rate_float;
|
|
|
|
uint8_t rate_byte[4];
|
|
|
|
};
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Hash of community attribute. */
|
2009-05-15 19:28:11 +02:00
|
|
|
static struct hash *ecomhash;
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Allocate a new ecommunities. */
|
2009-02-09 19:14:16 +01:00
|
|
|
struct ecommunity *ecommunity_new(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2019-10-17 16:08:16 +02:00
|
|
|
struct ecommunity *ecom;
|
|
|
|
|
|
|
|
ecom = (struct ecommunity *)XCALLOC(MTYPE_ECOMMUNITY,
|
|
|
|
sizeof(struct ecommunity));
|
|
|
|
ecom->unit_size = ECOMMUNITY_SIZE;
|
|
|
|
return ecom;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2018-05-16 15:54:03 +02:00
|
|
|
void ecommunity_strfree(char **s)
|
|
|
|
{
|
|
|
|
XFREE(MTYPE_ECOMMUNITY_STR, *s);
|
|
|
|
}
|
|
|
|
|
2022-03-26 05:09:27 +01:00
|
|
|
/* Free ecommunities. */
|
bgpd: Try fix extcommunity resource allocation probs, particularly with 'set extcom..'
* Extended communities has some kind of resource allocation problem which
causes a double-free if the 'set extcommunity ...' command is used.
Try fix by properly interning extcommunities.
Also, more generally, make unintern functions take a double pointer
so they can NULL out callers references - a usefully defensive programming
pattern for functions which make refs invalid.
Sadly, this patch doesn't fix the problem entirely - crashes still
occur on session clear.
* bgp_ecommunity.h: (ecommunity_{free,unintern}) take double pointer
args.
* bgp_community.h: (community_unintern) ditto
* bgp_attr.h: (bgp_attr_intern) ditto
* bgp_aspath.h: (bgp_aspath.h) ditto
* (general) update all callers of above
* bgp_routemap.c: (route_set_ecommunity_{rt,soo}) intern the new extcom added
to the attr, and unintern any old one.
(route_set_ecommunity_{rt,soo}_compile) intern the extcom to be used
for the route-map set.
(route_set_ecommunity_*_free) unintern to match, instead of free
(route_set_ecommunity_soo) Do as _rt does and don't just leak
any pre-existing community, add to it (is additive right though?)
2010-11-23 22:28:03 +01:00
|
|
|
void ecommunity_free(struct ecommunity **ecom)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2020-05-05 19:09:14 +02:00
|
|
|
if (!(*ecom))
|
|
|
|
return;
|
|
|
|
|
2019-02-25 21:18:13 +01:00
|
|
|
XFREE(MTYPE_ECOMMUNITY_VAL, (*ecom)->val);
|
|
|
|
XFREE(MTYPE_ECOMMUNITY_STR, (*ecom)->str);
|
bgpd: Try fix extcommunity resource allocation probs, particularly with 'set extcom..'
* Extended communities has some kind of resource allocation problem which
causes a double-free if the 'set extcommunity ...' command is used.
Try fix by properly interning extcommunities.
Also, more generally, make unintern functions take a double pointer
so they can NULL out callers references - a usefully defensive programming
pattern for functions which make refs invalid.
Sadly, this patch doesn't fix the problem entirely - crashes still
occur on session clear.
* bgp_ecommunity.h: (ecommunity_{free,unintern}) take double pointer
args.
* bgp_community.h: (community_unintern) ditto
* bgp_attr.h: (bgp_attr_intern) ditto
* bgp_aspath.h: (bgp_aspath.h) ditto
* (general) update all callers of above
* bgp_routemap.c: (route_set_ecommunity_{rt,soo}) intern the new extcom added
to the attr, and unintern any old one.
(route_set_ecommunity_{rt,soo}_compile) intern the extcom to be used
for the route-map set.
(route_set_ecommunity_*_free) unintern to match, instead of free
(route_set_ecommunity_soo) Do as _rt does and don't just leak
any pre-existing community, add to it (is additive right though?)
2010-11-23 22:28:03 +01:00
|
|
|
XFREE(MTYPE_ECOMMUNITY, *ecom);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2016-12-30 22:48:29 +01:00
|
|
|
static void ecommunity_hash_free(struct ecommunity *ecom)
|
|
|
|
{
|
|
|
|
ecommunity_free(&ecom);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Add a new Extended Communities value to Extended Communities
|
|
|
|
Attribute structure. When the value is already exists in the
|
|
|
|
structure, we don't add the value. Newly added value is sorted by
|
|
|
|
numerical order. When the value is added to the structure return 1
|
2020-03-24 21:50:20 +01:00
|
|
|
else return 0.
|
|
|
|
The additional parameters 'unique' and 'overwrite' ensure a particular
|
|
|
|
extended community (based on type and sub-type) is present only
|
|
|
|
once and whether the new value should replace what is existing or
|
|
|
|
not.
|
|
|
|
*/
|
2020-07-02 08:14:41 +02:00
|
|
|
static bool ecommunity_add_val_internal(struct ecommunity *ecom,
|
|
|
|
const void *eval,
|
|
|
|
bool unique, bool overwrite,
|
|
|
|
uint8_t ecom_size)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2021-01-17 22:08:03 +01:00
|
|
|
uint32_t c, ins_idx;
|
2019-10-17 16:08:16 +02:00
|
|
|
const struct ecommunity_val *eval4 = (struct ecommunity_val *)eval;
|
2020-07-02 08:14:41 +02:00
|
|
|
const struct ecommunity_val_ipv6 *eval6 =
|
|
|
|
(struct ecommunity_val_ipv6 *)eval;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-11-22 01:01:55 +01:00
|
|
|
/* When this is fist value, just add it. */
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ecom->val == NULL) {
|
2019-11-22 01:01:55 +01:00
|
|
|
ecom->size = 1;
|
2019-10-17 16:08:16 +02:00
|
|
|
ecom->val = XMALLOC(MTYPE_ECOMMUNITY_VAL,
|
|
|
|
ecom_length_size(ecom, ecom_size));
|
|
|
|
memcpy(ecom->val, eval, ecom_size);
|
2020-03-20 10:57:54 +01:00
|
|
|
return true;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* If the value already exists in the structure return 0. */
|
2020-03-24 21:50:20 +01:00
|
|
|
/* check also if the extended community itself exists. */
|
2002-12-13 21:15:29 +01:00
|
|
|
c = 0;
|
2019-10-17 16:08:16 +02:00
|
|
|
|
2021-01-17 22:08:03 +01:00
|
|
|
ins_idx = UINT32_MAX;
|
2019-11-22 01:01:55 +01:00
|
|
|
for (uint8_t *p = ecom->val; c < ecom->size;
|
2019-10-17 16:08:16 +02:00
|
|
|
p += ecom_size, c++) {
|
2020-03-24 21:50:20 +01:00
|
|
|
if (unique) {
|
2019-10-17 16:08:16 +02:00
|
|
|
if (ecom_size == ECOMMUNITY_SIZE) {
|
|
|
|
if (p[0] == eval4->val[0] &&
|
|
|
|
p[1] == eval4->val[1]) {
|
|
|
|
if (overwrite) {
|
2020-07-02 08:14:41 +02:00
|
|
|
memcpy(p, eval4->val,
|
|
|
|
ecom_size);
|
2019-10-17 16:08:16 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (p[0] == eval6->val[0] &&
|
|
|
|
p[1] == eval6->val[1]) {
|
|
|
|
if (overwrite) {
|
2020-07-02 08:14:41 +02:00
|
|
|
memcpy(p, eval6->val,
|
|
|
|
ecom_size);
|
2019-10-17 16:08:16 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2020-03-24 21:50:20 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-10-17 16:08:16 +02:00
|
|
|
int ret = memcmp(p, eval, ecom_size);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret == 0)
|
2020-07-02 10:08:29 +02:00
|
|
|
return false;
|
2020-03-24 21:50:20 +01:00
|
|
|
if (ret > 0) {
|
|
|
|
if (!unique)
|
|
|
|
break;
|
2021-01-17 22:08:03 +01:00
|
|
|
if (ins_idx == UINT32_MAX)
|
2020-03-24 21:50:20 +01:00
|
|
|
ins_idx = c;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-01-17 22:08:03 +01:00
|
|
|
if (ins_idx == UINT32_MAX)
|
2020-03-24 21:50:20 +01:00
|
|
|
ins_idx = c;
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Add the value to the structure with numerical sorting. */
|
|
|
|
ecom->size++;
|
2019-11-22 01:01:55 +01:00
|
|
|
ecom->val = XREALLOC(MTYPE_ECOMMUNITY_VAL, ecom->val,
|
2019-10-17 16:08:16 +02:00
|
|
|
ecom_length_size(ecom, ecom_size));
|
|
|
|
|
|
|
|
memmove(ecom->val + ((ins_idx + 1) * ecom_size),
|
|
|
|
ecom->val + (ins_idx * ecom_size),
|
|
|
|
(ecom->size - 1 - ins_idx) * ecom_size);
|
|
|
|
memcpy(ecom->val + (ins_idx * ecom_size),
|
|
|
|
eval, ecom_size);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-03-20 10:57:54 +01:00
|
|
|
return true;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
/* Add a new Extended Communities value to Extended Communities
|
2020-07-02 08:14:41 +02:00
|
|
|
* Attribute structure. When the value is already exists in the
|
|
|
|
* structure, we don't add the value. Newly added value is sorted by
|
|
|
|
* numerical order. When the value is added to the structure return 1
|
|
|
|
* else return 0.
|
|
|
|
*/
|
2019-10-17 16:08:16 +02:00
|
|
|
bool ecommunity_add_val(struct ecommunity *ecom, struct ecommunity_val *eval,
|
|
|
|
bool unique, bool overwrite)
|
|
|
|
{
|
|
|
|
return ecommunity_add_val_internal(ecom, (const void *)eval, unique,
|
|
|
|
overwrite, ECOMMUNITY_SIZE);
|
|
|
|
}
|
|
|
|
|
2020-07-02 08:14:41 +02:00
|
|
|
bool ecommunity_add_val_ipv6(struct ecommunity *ecom,
|
|
|
|
struct ecommunity_val_ipv6 *eval,
|
|
|
|
bool unique, bool overwrite)
|
2019-10-17 16:08:16 +02:00
|
|
|
{
|
|
|
|
return ecommunity_add_val_internal(ecom, (const void *)eval, unique,
|
|
|
|
overwrite, IPV6_ECOMMUNITY_SIZE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct ecommunity *
|
|
|
|
ecommunity_uniq_sort_internal(struct ecommunity *ecom,
|
|
|
|
unsigned short ecom_size)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2021-01-17 22:08:03 +01:00
|
|
|
uint32_t i;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct ecommunity *new;
|
2019-10-17 16:08:16 +02:00
|
|
|
const void *eval;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!ecom)
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2009-02-09 19:14:16 +01:00
|
|
|
new = ecommunity_new();
|
2019-10-17 16:08:16 +02:00
|
|
|
new->unit_size = ecom_size;
|
2021-08-29 20:54:13 +02:00
|
|
|
new->disable_ieee_floating = ecom->disable_ieee_floating;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (i = 0; i < ecom->size; i++) {
|
2019-10-17 16:11:57 +02:00
|
|
|
eval = (void *)(ecom->val + (i * ecom_size));
|
2019-10-17 16:08:16 +02:00
|
|
|
ecommunity_add_val_internal(new, eval, false, false, ecom_size);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2022-04-19 14:19:37 +02:00
|
|
|
/* This function takes pointer to Extended Communites structure then
|
2020-07-02 08:14:41 +02:00
|
|
|
* create a new Extended Communities structure by uniq and sort each
|
|
|
|
* Extended Communities value.
|
|
|
|
*/
|
2019-10-17 16:08:16 +02:00
|
|
|
struct ecommunity *ecommunity_uniq_sort(struct ecommunity *ecom)
|
|
|
|
{
|
|
|
|
return ecommunity_uniq_sort_internal(ecom, ECOMMUNITY_SIZE);
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Parse Extended Communites Attribute in BGP packet. */
|
2019-10-17 16:08:16 +02:00
|
|
|
static struct ecommunity *ecommunity_parse_internal(uint8_t *pnt,
|
2021-08-29 20:54:13 +02:00
|
|
|
unsigned short length,
|
|
|
|
unsigned short size_ecom,
|
|
|
|
bool disable_ieee_floating)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ecommunity tmp;
|
|
|
|
struct ecommunity *new;
|
|
|
|
|
|
|
|
/* Length check. */
|
2019-10-17 16:08:16 +02:00
|
|
|
if (length % size_ecom)
|
2002-12-13 21:15:29 +01:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* Prepare tmporary structure for making a new Extended Communities
|
|
|
|
Attribute. */
|
2019-10-17 16:08:16 +02:00
|
|
|
tmp.size = length / size_ecom;
|
2002-12-13 21:15:29 +01:00
|
|
|
tmp.val = pnt;
|
2021-08-29 20:54:13 +02:00
|
|
|
tmp.disable_ieee_floating = disable_ieee_floating;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Create a new Extended Communities Attribute by uniq and sort each
|
|
|
|
Extended Communities value */
|
2019-10-17 16:08:16 +02:00
|
|
|
new = ecommunity_uniq_sort_internal(&tmp, size_ecom);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return ecommunity_intern(new);
|
|
|
|
}
|
|
|
|
|
2021-08-29 20:54:13 +02:00
|
|
|
struct ecommunity *ecommunity_parse(uint8_t *pnt, unsigned short length,
|
|
|
|
bool disable_ieee_floating)
|
2019-10-17 16:08:16 +02:00
|
|
|
{
|
2021-08-29 20:54:13 +02:00
|
|
|
return ecommunity_parse_internal(pnt, length, ECOMMUNITY_SIZE,
|
|
|
|
disable_ieee_floating);
|
2019-10-17 16:08:16 +02:00
|
|
|
}
|
|
|
|
|
2021-08-29 20:54:13 +02:00
|
|
|
struct ecommunity *ecommunity_parse_ipv6(uint8_t *pnt, unsigned short length,
|
|
|
|
bool disable_ieee_floating)
|
2019-10-17 16:08:16 +02:00
|
|
|
{
|
2021-08-29 20:54:13 +02:00
|
|
|
return ecommunity_parse_internal(pnt, length, IPV6_ECOMMUNITY_SIZE,
|
|
|
|
disable_ieee_floating);
|
2019-10-17 16:08:16 +02:00
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Duplicate the Extended Communities Attribute structure. */
|
|
|
|
struct ecommunity *ecommunity_dup(struct ecommunity *ecom)
|
|
|
|
{
|
|
|
|
struct ecommunity *new;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
new = XCALLOC(MTYPE_ECOMMUNITY, sizeof(struct ecommunity));
|
|
|
|
new->size = ecom->size;
|
2019-10-17 16:08:16 +02:00
|
|
|
new->unit_size = ecom->unit_size;
|
2002-12-13 21:15:29 +01:00
|
|
|
if (new->size) {
|
|
|
|
new->val = XMALLOC(MTYPE_ECOMMUNITY_VAL,
|
2019-10-17 16:08:16 +02:00
|
|
|
ecom->size * ecom->unit_size);
|
2020-09-24 14:07:12 +02:00
|
|
|
memcpy(new->val, ecom->val,
|
|
|
|
(size_t)ecom->size * (size_t)ecom->unit_size);
|
2002-12-13 21:15:29 +01:00
|
|
|
} else
|
|
|
|
new->val = NULL;
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2021-08-05 15:29:52 +02:00
|
|
|
/* Return string representation of ecommunities attribute. */
|
2004-05-20 12:20:02 +02:00
|
|
|
char *ecommunity_str(struct ecommunity *ecom)
|
|
|
|
{
|
|
|
|
if (!ecom->str)
|
2016-08-09 10:47:03 +02:00
|
|
|
ecom->str =
|
|
|
|
ecommunity_ecom2str(ecom, ECOMMUNITY_FORMAT_DISPLAY, 0);
|
2004-05-20 12:20:02 +02:00
|
|
|
return ecom->str;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Merge two Extended Communities Attribute structure. */
|
|
|
|
struct ecommunity *ecommunity_merge(struct ecommunity *ecom1,
|
|
|
|
struct ecommunity *ecom2)
|
|
|
|
{
|
2021-07-13 01:32:42 +02:00
|
|
|
ecom1->val = XREALLOC(MTYPE_ECOMMUNITY_VAL, ecom1->val,
|
|
|
|
(size_t)(ecom1->size + ecom2->size)
|
|
|
|
* (size_t)ecom1->unit_size);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
memcpy(ecom1->val + (ecom1->size * ecom1->unit_size), ecom2->val,
|
2020-09-24 14:07:12 +02:00
|
|
|
(size_t)ecom2->size * (size_t)ecom1->unit_size);
|
2002-12-13 21:15:29 +01:00
|
|
|
ecom1->size += ecom2->size;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
return ecom1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Intern Extended Communities Attribute. */
|
|
|
|
struct ecommunity *ecommunity_intern(struct ecommunity *ecom)
|
|
|
|
{
|
|
|
|
struct ecommunity *find;
|
|
|
|
|
|
|
|
assert(ecom->refcnt == 0);
|
|
|
|
find = (struct ecommunity *)hash_get(ecomhash, ecom, hash_alloc_intern);
|
|
|
|
if (find != ecom)
|
bgpd: Try fix extcommunity resource allocation probs, particularly with 'set extcom..'
* Extended communities has some kind of resource allocation problem which
causes a double-free if the 'set extcommunity ...' command is used.
Try fix by properly interning extcommunities.
Also, more generally, make unintern functions take a double pointer
so they can NULL out callers references - a usefully defensive programming
pattern for functions which make refs invalid.
Sadly, this patch doesn't fix the problem entirely - crashes still
occur on session clear.
* bgp_ecommunity.h: (ecommunity_{free,unintern}) take double pointer
args.
* bgp_community.h: (community_unintern) ditto
* bgp_attr.h: (bgp_attr_intern) ditto
* bgp_aspath.h: (bgp_aspath.h) ditto
* (general) update all callers of above
* bgp_routemap.c: (route_set_ecommunity_{rt,soo}) intern the new extcom added
to the attr, and unintern any old one.
(route_set_ecommunity_{rt,soo}_compile) intern the extcom to be used
for the route-map set.
(route_set_ecommunity_*_free) unintern to match, instead of free
(route_set_ecommunity_soo) Do as _rt does and don't just leak
any pre-existing community, add to it (is additive right though?)
2010-11-23 22:28:03 +01:00
|
|
|
ecommunity_free(&ecom);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
find->refcnt++;
|
|
|
|
|
|
|
|
if (!find->str)
|
2017-02-17 08:57:37 +01:00
|
|
|
find->str =
|
|
|
|
ecommunity_ecom2str(find, ECOMMUNITY_FORMAT_DISPLAY, 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return find;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Unintern Extended Communities Attribute. */
|
bgpd: Try fix extcommunity resource allocation probs, particularly with 'set extcom..'
* Extended communities has some kind of resource allocation problem which
causes a double-free if the 'set extcommunity ...' command is used.
Try fix by properly interning extcommunities.
Also, more generally, make unintern functions take a double pointer
so they can NULL out callers references - a usefully defensive programming
pattern for functions which make refs invalid.
Sadly, this patch doesn't fix the problem entirely - crashes still
occur on session clear.
* bgp_ecommunity.h: (ecommunity_{free,unintern}) take double pointer
args.
* bgp_community.h: (community_unintern) ditto
* bgp_attr.h: (bgp_attr_intern) ditto
* bgp_aspath.h: (bgp_aspath.h) ditto
* (general) update all callers of above
* bgp_routemap.c: (route_set_ecommunity_{rt,soo}) intern the new extcom added
to the attr, and unintern any old one.
(route_set_ecommunity_{rt,soo}_compile) intern the extcom to be used
for the route-map set.
(route_set_ecommunity_*_free) unintern to match, instead of free
(route_set_ecommunity_soo) Do as _rt does and don't just leak
any pre-existing community, add to it (is additive right though?)
2010-11-23 22:28:03 +01:00
|
|
|
void ecommunity_unintern(struct ecommunity **ecom)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ecommunity *ret;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-02 17:20:32 +01:00
|
|
|
if (!*ecom)
|
|
|
|
return;
|
|
|
|
|
bgpd: Try fix extcommunity resource allocation probs, particularly with 'set extcom..'
* Extended communities has some kind of resource allocation problem which
causes a double-free if the 'set extcommunity ...' command is used.
Try fix by properly interning extcommunities.
Also, more generally, make unintern functions take a double pointer
so they can NULL out callers references - a usefully defensive programming
pattern for functions which make refs invalid.
Sadly, this patch doesn't fix the problem entirely - crashes still
occur on session clear.
* bgp_ecommunity.h: (ecommunity_{free,unintern}) take double pointer
args.
* bgp_community.h: (community_unintern) ditto
* bgp_attr.h: (bgp_attr_intern) ditto
* bgp_aspath.h: (bgp_aspath.h) ditto
* (general) update all callers of above
* bgp_routemap.c: (route_set_ecommunity_{rt,soo}) intern the new extcom added
to the attr, and unintern any old one.
(route_set_ecommunity_{rt,soo}_compile) intern the extcom to be used
for the route-map set.
(route_set_ecommunity_*_free) unintern to match, instead of free
(route_set_ecommunity_soo) Do as _rt does and don't just leak
any pre-existing community, add to it (is additive right though?)
2010-11-23 22:28:03 +01:00
|
|
|
if ((*ecom)->refcnt)
|
|
|
|
(*ecom)->refcnt--;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Pull off from hash. */
|
bgpd: Try fix extcommunity resource allocation probs, particularly with 'set extcom..'
* Extended communities has some kind of resource allocation problem which
causes a double-free if the 'set extcommunity ...' command is used.
Try fix by properly interning extcommunities.
Also, more generally, make unintern functions take a double pointer
so they can NULL out callers references - a usefully defensive programming
pattern for functions which make refs invalid.
Sadly, this patch doesn't fix the problem entirely - crashes still
occur on session clear.
* bgp_ecommunity.h: (ecommunity_{free,unintern}) take double pointer
args.
* bgp_community.h: (community_unintern) ditto
* bgp_attr.h: (bgp_attr_intern) ditto
* bgp_aspath.h: (bgp_aspath.h) ditto
* (general) update all callers of above
* bgp_routemap.c: (route_set_ecommunity_{rt,soo}) intern the new extcom added
to the attr, and unintern any old one.
(route_set_ecommunity_{rt,soo}_compile) intern the extcom to be used
for the route-map set.
(route_set_ecommunity_*_free) unintern to match, instead of free
(route_set_ecommunity_soo) Do as _rt does and don't just leak
any pre-existing community, add to it (is additive right though?)
2010-11-23 22:28:03 +01:00
|
|
|
if ((*ecom)->refcnt == 0) {
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Extended community must be in the hash. */
|
bgpd: Try fix extcommunity resource allocation probs, particularly with 'set extcom..'
* Extended communities has some kind of resource allocation problem which
causes a double-free if the 'set extcommunity ...' command is used.
Try fix by properly interning extcommunities.
Also, more generally, make unintern functions take a double pointer
so they can NULL out callers references - a usefully defensive programming
pattern for functions which make refs invalid.
Sadly, this patch doesn't fix the problem entirely - crashes still
occur on session clear.
* bgp_ecommunity.h: (ecommunity_{free,unintern}) take double pointer
args.
* bgp_community.h: (community_unintern) ditto
* bgp_attr.h: (bgp_attr_intern) ditto
* bgp_aspath.h: (bgp_aspath.h) ditto
* (general) update all callers of above
* bgp_routemap.c: (route_set_ecommunity_{rt,soo}) intern the new extcom added
to the attr, and unintern any old one.
(route_set_ecommunity_{rt,soo}_compile) intern the extcom to be used
for the route-map set.
(route_set_ecommunity_*_free) unintern to match, instead of free
(route_set_ecommunity_soo) Do as _rt does and don't just leak
any pre-existing community, add to it (is additive right though?)
2010-11-23 22:28:03 +01:00
|
|
|
ret = (struct ecommunity *)hash_release(ecomhash, *ecom);
|
2002-12-13 21:15:29 +01:00
|
|
|
assert(ret != NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
ecommunity_free(ecom);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Utinity function to make hash key. */
|
2019-05-14 22:19:07 +02:00
|
|
|
unsigned int ecommunity_hash_make(const void *arg)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
const struct ecommunity *ecom = arg;
|
2019-10-17 16:08:16 +02:00
|
|
|
int size = ecom->size * ecom->unit_size;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-09-04 00:57:30 +02:00
|
|
|
return jhash(ecom->val, size, 0x564321ab);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Compare two Extended Communities Attribute structure. */
|
2018-10-17 21:27:12 +02:00
|
|
|
bool ecommunity_cmp(const void *arg1, const void *arg2)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
const struct ecommunity *ecom1 = arg1;
|
|
|
|
const struct ecommunity *ecom2 = arg2;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-11-23 19:05:03 +01:00
|
|
|
if (ecom1 == NULL && ecom2 == NULL)
|
2018-10-17 21:27:12 +02:00
|
|
|
return true;
|
2015-11-23 19:05:03 +01:00
|
|
|
|
|
|
|
if (ecom1 == NULL || ecom2 == NULL)
|
2018-10-17 21:27:12 +02:00
|
|
|
return false;
|
2015-11-23 19:05:03 +01:00
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
if (ecom1->unit_size != ecom2->unit_size)
|
|
|
|
return false;
|
|
|
|
|
2008-08-14 17:25:25 +02:00
|
|
|
return (ecom1->size == ecom2->size
|
2019-10-17 16:08:16 +02:00
|
|
|
&& memcmp(ecom1->val, ecom2->val, ecom1->size *
|
|
|
|
ecom1->unit_size) == 0);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize Extended Comminities related hash. */
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
void ecommunity_init(void)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-09-04 00:57:30 +02:00
|
|
|
ecomhash = hash_create(ecommunity_hash_make, ecommunity_cmp,
|
|
|
|
"BGP ecommunity hash");
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
[bgpd] Stability fixes including bugs 397, 492
I've spent the last several weeks working on stability fixes to bgpd.
These patches fix all of the numerous crashes, assertion failures, memory
leaks and memory stomping I could find. Valgrind was used extensively.
Added new function bgp_exit() to help catch problems. If "debug bgp" is
configured and bgpd exits with status of 0, statistics on remaining
lib/memory.c allocations are printed to stderr. It is my hope that other
developers will use this to stay on top of memory issues.
Example questionable exit:
bgpd: memstats: Current memory utilization in module LIB:
bgpd: memstats: Link List : 6
bgpd: memstats: Link Node : 5
bgpd: memstats: Hash : 8
bgpd: memstats: Hash Bucket : 2
bgpd: memstats: Hash Index : 8
bgpd: memstats: Work queue : 3
bgpd: memstats: Work queue item : 2
bgpd: memstats: Work queue name string : 3
bgpd: memstats: Current memory utilization in module BGP:
bgpd: memstats: BGP instance : 1
bgpd: memstats: BGP peer : 1
bgpd: memstats: BGP peer hostname : 1
bgpd: memstats: BGP attribute : 1
bgpd: memstats: BGP extra attributes : 1
bgpd: memstats: BGP aspath : 1
bgpd: memstats: BGP aspath str : 1
bgpd: memstats: BGP table : 24
bgpd: memstats: BGP node : 1
bgpd: memstats: BGP route : 1
bgpd: memstats: BGP synchronise : 8
bgpd: memstats: BGP Process queue : 1
bgpd: memstats: BGP node clear queue : 1
bgpd: memstats: NOTE: If configuration exists, utilization may be expected.
Example clean exit:
bgpd: memstats: No remaining tracked memory utilization.
This patch fixes bug #397: "Invalid free in bgp_announce_check()".
This patch fixes bug #492: "SIGBUS in bgpd/bgp_route.c:
bgp_clear_route_node()".
My apologies for not separating out these changes into individual patches.
The complexity of doing so boggled what is left of my brain. I hope this
is all still useful to the community.
This code has been production tested, in non-route-server-client mode, on
a linux 32-bit box and a 64-bit box.
Release/reset functions, used by bgp_exit(), added to:
bgpd/bgp_attr.c,h
bgpd/bgp_community.c,h
bgpd/bgp_dump.c,h
bgpd/bgp_ecommunity.c,h
bgpd/bgp_filter.c,h
bgpd/bgp_nexthop.c,h
bgpd/bgp_route.c,h
lib/routemap.c,h
File by file analysis:
* bgpd/bgp_aspath.c: Prevent re-use of ashash after it is released.
* bgpd/bgp_attr.c: #if removed uncalled cluster_dup().
* bgpd/bgp_clist.c,h: Allow community_list_terminate() to be called from
bgp_exit().
* bgpd/bgp_filter.c: Fix aslist->name use without allocation check, and
also fix memory leak.
* bgpd/bgp_main.c: Created bgp_exit() exit routine. This function frees
allocations made as part of bgpd initialization and, to some extent,
configuration. If "debug bgp" is configured, memory stats are printed
as described above.
* bgpd/bgp_nexthop.c: zclient_new() already allocates stream for
ibuf/obuf, so bgp_scan_init() shouldn't do it too. Also, made it so
zlookup is global so bgp_exit() can use it.
* bgpd/bgp_packet.c: bgp_capability_msg_parse() call to bgp_clear_route()
adjusted to use new BGP_CLEAR_ROUTE_NORMAL flag.
* bgpd/bgp_route.h: Correct reference counter "lock" to be signed.
bgp_clear_route() now accepts a bgp_clear_route_type of either
BGP_CLEAR_ROUTE_NORMAL or BGP_CLEAR_ROUTE_MY_RSCLIENT.
* bgpd/bgp_route.c:
- bgp_process_rsclient(): attr was being zero'ed and then
bgp_attr_extra_free() was being called with it, even though it was
never filled with valid data.
- bgp_process_rsclient(): Make sure rsclient->group is not NULL before
use.
- bgp_processq_del(): Add call to bgp_table_unlock().
- bgp_process(): Add call to bgp_table_lock().
- bgp_update_rsclient(): memset clearing of new_attr not needed since
declarationw with "= { 0 }" does it. memset was already commented
out.
- bgp_update_rsclient(): Fix screwed up misleading indentation.
- bgp_withdraw_rsclient(): Fix screwed up misleading indentation.
- bgp_clear_route_node(): Support BGP_CLEAR_ROUTE_MY_RSCLIENT.
- bgp_clear_node_queue_del(): Add call to bgp_table_unlock() and also
free struct bgp_clear_node_queue used for work item.
- bgp_clear_node_complete(): Do peer_unlock() after BGP_EVENT_ADD() in
case peer is released by peer_unlock() call.
- bgp_clear_route_table(): Support BGP_CLEAR_ROUTE_MY_RSCLIENT. Use
struct bgp_clear_node_queue to supply data to worker. Add call to
bgp_table_lock().
- bgp_clear_route(): Add support for BGP_CLEAR_ROUTE_NORMAL or
BGP_CLEAR_ROUTE_MY_RSCLIENT.
- bgp_clear_route_all(): Use BGP_CLEAR_ROUTE_NORMAL.
Bug 397 fixes:
- bgp_default_originate()
- bgp_announce_table()
* bgpd/bgp_table.h:
- struct bgp_table: Added reference count. Changed type of owner to be
"struct peer *" rather than "void *".
- struct bgp_node: Correct reference counter "lock" to be signed.
* bgpd/bgp_table.c:
- Added bgp_table reference counting.
- bgp_table_free(): Fixed cleanup code. Call peer_unlock() on owner if
set.
- bgp_unlock_node(): Added assertion.
- bgp_node_get(): Added call to bgp_lock_node() to code path that it was
missing from.
* bgpd/bgp_vty.c:
- peer_rsclient_set_vty(): Call peer_lock() as part of peer assignment
to owner. Handle failure gracefully.
- peer_rsclient_unset_vty(): Add call to bgp_clear_route() with
BGP_CLEAR_ROUTE_MY_RSCLIENT purpose.
* bgpd/bgp_zebra.c: Made it so zclient is global so bgp_exit() can use it.
* bgpd/bgpd.c:
- peer_lock(): Allow to be called when status is "Deleted".
- peer_deactivate(): Supply BGP_CLEAR_ROUTE_NORMAL purpose to
bgp_clear_route() call.
- peer_delete(): Common variable listnode pn. Fix bug in which rsclient
was only dealt with if not part of a peer group. Call
bgp_clear_route() for rsclient, if appropriate, and do so with
BGP_CLEAR_ROUTE_MY_RSCLIENT purpose.
- peer_group_get(): Use XSTRDUP() instead of strdup() for conf->host.
- peer_group_bind(): Call bgp_clear_route() for rsclient, and do so with
BGP_CLEAR_ROUTE_MY_RSCLIENT purpose.
- bgp_create(): Use XSTRDUP() instead of strdup() for peer_self->host.
- bgp_delete(): Delete peers before groups, rather than after. And then
rather than deleting rsclients, verify that there are none at this
point.
- bgp_unlock(): Add assertion.
- bgp_free(): Call bgp_table_finish() rather than doing XFREE() itself.
* lib/command.c,h: Compiler warning fixes. Add cmd_terminate(). Fixed
massive leak in install_element() in which cmd_make_descvec() was being
called more than once for the same cmd->strvec/string/doc.
* lib/log.c: Make closezlog() check fp before calling fclose().
* lib/memory.c: Catch when alloc count goes negative by using signed
counts. Correct #endif comment. Add log_memstats_stderr().
* lib/memory.h: Add log_memstats_stderr().
* lib/thread.c: thread->funcname was being accessed in thread_call() after
it had been freed. Rearranged things so that thread_call() frees
funcname. Also made it so thread_master_free() cleans up cpu_record.
* lib/vty.c,h: Use global command_cr. Add vty_terminate().
* lib/zclient.c,h: Re-enable zclient_free().
2009-07-18 07:44:03 +02:00
|
|
|
|
|
|
|
void ecommunity_finish(void)
|
|
|
|
{
|
2023-03-21 13:54:21 +01:00
|
|
|
hash_clean_and_free(&ecomhash, (void (*)(void *))ecommunity_hash_free);
|
[bgpd] Stability fixes including bugs 397, 492
I've spent the last several weeks working on stability fixes to bgpd.
These patches fix all of the numerous crashes, assertion failures, memory
leaks and memory stomping I could find. Valgrind was used extensively.
Added new function bgp_exit() to help catch problems. If "debug bgp" is
configured and bgpd exits with status of 0, statistics on remaining
lib/memory.c allocations are printed to stderr. It is my hope that other
developers will use this to stay on top of memory issues.
Example questionable exit:
bgpd: memstats: Current memory utilization in module LIB:
bgpd: memstats: Link List : 6
bgpd: memstats: Link Node : 5
bgpd: memstats: Hash : 8
bgpd: memstats: Hash Bucket : 2
bgpd: memstats: Hash Index : 8
bgpd: memstats: Work queue : 3
bgpd: memstats: Work queue item : 2
bgpd: memstats: Work queue name string : 3
bgpd: memstats: Current memory utilization in module BGP:
bgpd: memstats: BGP instance : 1
bgpd: memstats: BGP peer : 1
bgpd: memstats: BGP peer hostname : 1
bgpd: memstats: BGP attribute : 1
bgpd: memstats: BGP extra attributes : 1
bgpd: memstats: BGP aspath : 1
bgpd: memstats: BGP aspath str : 1
bgpd: memstats: BGP table : 24
bgpd: memstats: BGP node : 1
bgpd: memstats: BGP route : 1
bgpd: memstats: BGP synchronise : 8
bgpd: memstats: BGP Process queue : 1
bgpd: memstats: BGP node clear queue : 1
bgpd: memstats: NOTE: If configuration exists, utilization may be expected.
Example clean exit:
bgpd: memstats: No remaining tracked memory utilization.
This patch fixes bug #397: "Invalid free in bgp_announce_check()".
This patch fixes bug #492: "SIGBUS in bgpd/bgp_route.c:
bgp_clear_route_node()".
My apologies for not separating out these changes into individual patches.
The complexity of doing so boggled what is left of my brain. I hope this
is all still useful to the community.
This code has been production tested, in non-route-server-client mode, on
a linux 32-bit box and a 64-bit box.
Release/reset functions, used by bgp_exit(), added to:
bgpd/bgp_attr.c,h
bgpd/bgp_community.c,h
bgpd/bgp_dump.c,h
bgpd/bgp_ecommunity.c,h
bgpd/bgp_filter.c,h
bgpd/bgp_nexthop.c,h
bgpd/bgp_route.c,h
lib/routemap.c,h
File by file analysis:
* bgpd/bgp_aspath.c: Prevent re-use of ashash after it is released.
* bgpd/bgp_attr.c: #if removed uncalled cluster_dup().
* bgpd/bgp_clist.c,h: Allow community_list_terminate() to be called from
bgp_exit().
* bgpd/bgp_filter.c: Fix aslist->name use without allocation check, and
also fix memory leak.
* bgpd/bgp_main.c: Created bgp_exit() exit routine. This function frees
allocations made as part of bgpd initialization and, to some extent,
configuration. If "debug bgp" is configured, memory stats are printed
as described above.
* bgpd/bgp_nexthop.c: zclient_new() already allocates stream for
ibuf/obuf, so bgp_scan_init() shouldn't do it too. Also, made it so
zlookup is global so bgp_exit() can use it.
* bgpd/bgp_packet.c: bgp_capability_msg_parse() call to bgp_clear_route()
adjusted to use new BGP_CLEAR_ROUTE_NORMAL flag.
* bgpd/bgp_route.h: Correct reference counter "lock" to be signed.
bgp_clear_route() now accepts a bgp_clear_route_type of either
BGP_CLEAR_ROUTE_NORMAL or BGP_CLEAR_ROUTE_MY_RSCLIENT.
* bgpd/bgp_route.c:
- bgp_process_rsclient(): attr was being zero'ed and then
bgp_attr_extra_free() was being called with it, even though it was
never filled with valid data.
- bgp_process_rsclient(): Make sure rsclient->group is not NULL before
use.
- bgp_processq_del(): Add call to bgp_table_unlock().
- bgp_process(): Add call to bgp_table_lock().
- bgp_update_rsclient(): memset clearing of new_attr not needed since
declarationw with "= { 0 }" does it. memset was already commented
out.
- bgp_update_rsclient(): Fix screwed up misleading indentation.
- bgp_withdraw_rsclient(): Fix screwed up misleading indentation.
- bgp_clear_route_node(): Support BGP_CLEAR_ROUTE_MY_RSCLIENT.
- bgp_clear_node_queue_del(): Add call to bgp_table_unlock() and also
free struct bgp_clear_node_queue used for work item.
- bgp_clear_node_complete(): Do peer_unlock() after BGP_EVENT_ADD() in
case peer is released by peer_unlock() call.
- bgp_clear_route_table(): Support BGP_CLEAR_ROUTE_MY_RSCLIENT. Use
struct bgp_clear_node_queue to supply data to worker. Add call to
bgp_table_lock().
- bgp_clear_route(): Add support for BGP_CLEAR_ROUTE_NORMAL or
BGP_CLEAR_ROUTE_MY_RSCLIENT.
- bgp_clear_route_all(): Use BGP_CLEAR_ROUTE_NORMAL.
Bug 397 fixes:
- bgp_default_originate()
- bgp_announce_table()
* bgpd/bgp_table.h:
- struct bgp_table: Added reference count. Changed type of owner to be
"struct peer *" rather than "void *".
- struct bgp_node: Correct reference counter "lock" to be signed.
* bgpd/bgp_table.c:
- Added bgp_table reference counting.
- bgp_table_free(): Fixed cleanup code. Call peer_unlock() on owner if
set.
- bgp_unlock_node(): Added assertion.
- bgp_node_get(): Added call to bgp_lock_node() to code path that it was
missing from.
* bgpd/bgp_vty.c:
- peer_rsclient_set_vty(): Call peer_lock() as part of peer assignment
to owner. Handle failure gracefully.
- peer_rsclient_unset_vty(): Add call to bgp_clear_route() with
BGP_CLEAR_ROUTE_MY_RSCLIENT purpose.
* bgpd/bgp_zebra.c: Made it so zclient is global so bgp_exit() can use it.
* bgpd/bgpd.c:
- peer_lock(): Allow to be called when status is "Deleted".
- peer_deactivate(): Supply BGP_CLEAR_ROUTE_NORMAL purpose to
bgp_clear_route() call.
- peer_delete(): Common variable listnode pn. Fix bug in which rsclient
was only dealt with if not part of a peer group. Call
bgp_clear_route() for rsclient, if appropriate, and do so with
BGP_CLEAR_ROUTE_MY_RSCLIENT purpose.
- peer_group_get(): Use XSTRDUP() instead of strdup() for conf->host.
- peer_group_bind(): Call bgp_clear_route() for rsclient, and do so with
BGP_CLEAR_ROUTE_MY_RSCLIENT purpose.
- bgp_create(): Use XSTRDUP() instead of strdup() for peer_self->host.
- bgp_delete(): Delete peers before groups, rather than after. And then
rather than deleting rsclients, verify that there are none at this
point.
- bgp_unlock(): Add assertion.
- bgp_free(): Call bgp_table_finish() rather than doing XFREE() itself.
* lib/command.c,h: Compiler warning fixes. Add cmd_terminate(). Fixed
massive leak in install_element() in which cmd_make_descvec() was being
called more than once for the same cmd->strvec/string/doc.
* lib/log.c: Make closezlog() check fp before calling fclose().
* lib/memory.c: Catch when alloc count goes negative by using signed
counts. Correct #endif comment. Add log_memstats_stderr().
* lib/memory.h: Add log_memstats_stderr().
* lib/thread.c: thread->funcname was being accessed in thread_call() after
it had been freed. Rearranged things so that thread_call() frees
funcname. Also made it so thread_master_free() cleans up cpu_record.
* lib/vty.c,h: Use global command_cr. Add vty_terminate().
* lib/zclient.c,h: Re-enable zclient_free().
2009-07-18 07:44:03 +02:00
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Extended Communities token enum. */
|
|
|
|
enum ecommunity_token {
|
2015-04-19 15:17:02 +02:00
|
|
|
ecommunity_token_unknown = 0,
|
2002-12-13 21:15:29 +01:00
|
|
|
ecommunity_token_rt,
|
|
|
|
ecommunity_token_soo,
|
|
|
|
ecommunity_token_val,
|
2019-10-17 16:08:16 +02:00
|
|
|
ecommunity_token_rt6,
|
|
|
|
ecommunity_token_val6,
|
2002-12-13 21:15:29 +01:00
|
|
|
};
|
|
|
|
|
bgpd: Add Origin Validation State extended community
```
spine1-debian-11# sh ip bgp 100.100.100.101/32
BGP routing table entry for 100.100.100.101/32, version 21
Paths: (1 available, best #1, table default)
Not advertised to any peer
Local
fe80::ca5d:fd0d:cd8:1bb7 from eth3 (172.17.0.3)
(fe80::ca5d:fd0d:cd8:1bb7) (used)
Origin incomplete, metric 0, localpref 100, valid, internal, best (First path received)
Extended Community: OVS:invalid
Last update: Wed Aug 31 19:31:46 2022
spine1-debian-11# sh ip bgp 100.100.100.100/32
BGP routing table entry for 100.100.100.100/32, version 17
Paths: (1 available, best #1, table default)
Not advertised to any peer
Local
fe80::ca5d:fd0d:cd8:1bb7 from eth3 (172.17.0.3)
(fe80::ca5d:fd0d:cd8:1bb7) (used)
Origin incomplete, metric 0, localpref 100, valid, internal, best (First path received)
Extended Community: OVS:not-found
Last update: Wed Aug 31 19:31:46 2022
spine1-debian-11#
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-08-30 20:25:50 +02:00
|
|
|
static const char *ecommunity_origin_validation_state2str(
|
|
|
|
enum ecommunity_origin_validation_states state)
|
|
|
|
{
|
|
|
|
switch (state) {
|
|
|
|
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_VALID:
|
|
|
|
return "valid";
|
|
|
|
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTFOUND:
|
|
|
|
return "not-found";
|
|
|
|
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_INVALID:
|
|
|
|
return "invalid";
|
|
|
|
case ECOMMUNITY_ORIGIN_VALIDATION_STATE_NOTUSED:
|
|
|
|
return "not-used";
|
|
|
|
}
|
|
|
|
|
|
|
|
return "ERROR";
|
|
|
|
}
|
|
|
|
|
|
|
|
static void ecommunity_origin_validation_state_str(char *buf, size_t bufsz,
|
|
|
|
uint8_t *ptr)
|
|
|
|
{
|
|
|
|
/* Origin Validation State is encoded in the last octet
|
|
|
|
*
|
|
|
|
* 0 1 2 3
|
|
|
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
|
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
* | 0x43 | 0x00 | Reserved |
|
|
|
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
* | Reserved |validationstate|
|
|
|
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
|
|
*/
|
|
|
|
uint8_t state = *(ptr + ECOMMUNITY_SIZE - 3);
|
|
|
|
|
|
|
|
snprintf(buf, bufsz, "OVS:%s",
|
|
|
|
ecommunity_origin_validation_state2str(state));
|
|
|
|
|
|
|
|
(void)ptr; /* consume value */
|
|
|
|
}
|
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
static int ecommunity_encode_internal(uint8_t type, uint8_t sub_type,
|
|
|
|
int trans, as_t as,
|
|
|
|
struct in_addr *ip,
|
|
|
|
struct in6_addr *ip6,
|
|
|
|
uint32_t val,
|
|
|
|
void *eval_ptr)
|
2017-05-15 21:31:01 +02:00
|
|
|
{
|
2019-10-17 16:08:16 +02:00
|
|
|
struct ecommunity_val *eval = (struct ecommunity_val *)eval_ptr;
|
|
|
|
struct ecommunity_val_ipv6 *eval6 =
|
|
|
|
(struct ecommunity_val_ipv6 *)eval_ptr;
|
|
|
|
|
2017-05-15 21:31:01 +02:00
|
|
|
assert(eval);
|
|
|
|
if (type == ECOMMUNITY_ENCODE_AS) {
|
|
|
|
if (as > BGP_AS_MAX)
|
|
|
|
return -1;
|
|
|
|
} else if (type == ECOMMUNITY_ENCODE_IP
|
|
|
|
|| type == ECOMMUNITY_ENCODE_AS4) {
|
|
|
|
if (val > UINT16_MAX)
|
|
|
|
return -1;
|
2019-10-17 16:08:16 +02:00
|
|
|
} else if (type == ECOMMUNITY_ENCODE_TRANS_EXP &&
|
|
|
|
sub_type == ECOMMUNITY_FLOWSPEC_REDIRECT_IPV6 &&
|
|
|
|
(!ip6 || val > UINT16_MAX)) {
|
|
|
|
return -1;
|
2017-05-15 21:31:01 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-15 21:31:01 +02:00
|
|
|
/* Fill in the values. */
|
|
|
|
eval->val[0] = type;
|
|
|
|
if (!trans)
|
|
|
|
eval->val[0] |= ECOMMUNITY_FLAG_NON_TRANSITIVE;
|
|
|
|
eval->val[1] = sub_type;
|
|
|
|
if (type == ECOMMUNITY_ENCODE_AS) {
|
|
|
|
eval->val[2] = (as >> 8) & 0xff;
|
|
|
|
eval->val[3] = as & 0xff;
|
|
|
|
eval->val[4] = (val >> 24) & 0xff;
|
|
|
|
eval->val[5] = (val >> 16) & 0xff;
|
|
|
|
eval->val[6] = (val >> 8) & 0xff;
|
|
|
|
eval->val[7] = val & 0xff;
|
|
|
|
} else if (type == ECOMMUNITY_ENCODE_IP) {
|
2019-10-17 16:08:16 +02:00
|
|
|
memcpy(&eval->val[2], ip, sizeof(struct in_addr));
|
2017-05-15 21:31:01 +02:00
|
|
|
eval->val[6] = (val >> 8) & 0xff;
|
|
|
|
eval->val[7] = val & 0xff;
|
2019-10-17 16:08:16 +02:00
|
|
|
} else if (type == ECOMMUNITY_ENCODE_TRANS_EXP &&
|
|
|
|
sub_type == ECOMMUNITY_FLOWSPEC_REDIRECT_IPV6) {
|
|
|
|
memcpy(&eval6->val[2], ip6, sizeof(struct in6_addr));
|
|
|
|
eval6->val[18] = (val >> 8) & 0xff;
|
|
|
|
eval6->val[19] = val & 0xff;
|
2017-05-15 21:31:01 +02:00
|
|
|
} else {
|
|
|
|
eval->val[2] = (as >> 24) & 0xff;
|
|
|
|
eval->val[3] = (as >> 16) & 0xff;
|
|
|
|
eval->val[4] = (as >> 8) & 0xff;
|
|
|
|
eval->val[5] = as & 0xff;
|
|
|
|
eval->val[6] = (val >> 8) & 0xff;
|
|
|
|
eval->val[7] = val & 0xff;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-15 21:31:01 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
/*
|
|
|
|
* Encode BGP extended community from passed values. Supports types
|
|
|
|
* defined in RFC 4360 and well-known sub-types.
|
|
|
|
*/
|
|
|
|
static int ecommunity_encode(uint8_t type, uint8_t sub_type, int trans, as_t as,
|
|
|
|
struct in_addr ip, uint32_t val,
|
|
|
|
struct ecommunity_val *eval)
|
|
|
|
{
|
|
|
|
return ecommunity_encode_internal(type, sub_type, trans, as,
|
|
|
|
&ip, NULL, val, (void *)eval);
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Get next Extended Communities token from the string. */
|
2004-10-13 07:06:08 +02:00
|
|
|
static const char *ecommunity_gettoken(const char *str,
|
2019-10-17 16:08:16 +02:00
|
|
|
void *eval_ptr,
|
2002-12-13 21:15:29 +01:00
|
|
|
enum ecommunity_token *token)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
int dot = 0;
|
|
|
|
int digit = 0;
|
|
|
|
int separator = 0;
|
2004-10-13 07:06:08 +02:00
|
|
|
const char *p = str;
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
char *endptr;
|
|
|
|
struct in_addr ip;
|
2019-10-17 16:08:16 +02:00
|
|
|
struct in6_addr ip6;
|
2002-12-13 21:15:29 +01:00
|
|
|
as_t as = 0;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t val = 0;
|
|
|
|
uint8_t ecomm_type;
|
2002-12-13 21:15:29 +01:00
|
|
|
char buf[INET_ADDRSTRLEN + 1];
|
2019-10-17 16:08:16 +02:00
|
|
|
struct ecommunity_val *eval = (struct ecommunity_val *)eval_ptr;
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Skip white space. */
|
2019-08-06 16:54:52 +02:00
|
|
|
while (isspace((unsigned char)*p)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
p++;
|
|
|
|
str++;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Check the end of the line. */
|
|
|
|
if (*p == '\0')
|
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* "rt" and "soo" keyword parse. */
|
2019-08-06 16:54:52 +02:00
|
|
|
if (!isdigit((unsigned char)*p)) {
|
2002-12-13 21:15:29 +01:00
|
|
|
/* "rt" match check. */
|
2019-08-06 16:54:52 +02:00
|
|
|
if (tolower((unsigned char)*p) == 'r') {
|
2002-12-13 21:15:29 +01:00
|
|
|
p++;
|
2019-08-06 16:54:52 +02:00
|
|
|
if (tolower((unsigned char)*p) == 't') {
|
2002-12-13 21:15:29 +01:00
|
|
|
p++;
|
2019-10-17 16:08:16 +02:00
|
|
|
if (*p != '\0' && tolower((int)*p) == '6')
|
|
|
|
*token = ecommunity_token_rt6;
|
|
|
|
else
|
|
|
|
*token = ecommunity_token_rt;
|
2002-12-13 21:15:29 +01:00
|
|
|
return p;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2019-08-06 16:54:52 +02:00
|
|
|
if (isspace((unsigned char)*p) || *p == '\0') {
|
2002-12-13 21:15:29 +01:00
|
|
|
*token = ecommunity_token_rt;
|
|
|
|
return p;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
/* "soo" match check. */
|
2019-08-06 16:54:52 +02:00
|
|
|
else if (tolower((unsigned char)*p) == 's') {
|
2017-07-17 14:03:14 +02:00
|
|
|
p++;
|
2019-08-06 16:54:52 +02:00
|
|
|
if (tolower((unsigned char)*p) == 'o') {
|
2017-07-17 14:03:14 +02:00
|
|
|
p++;
|
2019-08-06 16:54:52 +02:00
|
|
|
if (tolower((unsigned char)*p) == 'o') {
|
2017-07-17 14:03:14 +02:00
|
|
|
p++;
|
2002-12-13 21:15:29 +01:00
|
|
|
*token = ecommunity_token_soo;
|
|
|
|
return p;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2019-08-06 16:54:52 +02:00
|
|
|
if (isspace((unsigned char)*p) || *p == '\0') {
|
2002-12-13 21:15:29 +01:00
|
|
|
*token = ecommunity_token_soo;
|
|
|
|
return p;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
goto error;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2019-08-06 16:54:52 +02:00
|
|
|
if (isspace((unsigned char)*p) || *p == '\0') {
|
2002-12-13 21:15:29 +01:00
|
|
|
*token = ecommunity_token_soo;
|
|
|
|
return p;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
goto error;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
/* What a mess, there are several possibilities:
|
|
|
|
*
|
|
|
|
* a) A.B.C.D:MN
|
|
|
|
* b) EF:OPQR
|
|
|
|
* c) GHJK:MN
|
2019-10-17 16:08:16 +02:00
|
|
|
* d) <IPV6>:MN (only with rt6)
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
*
|
|
|
|
* A.B.C.D: Four Byte IP
|
|
|
|
* EF: Two byte ASN
|
|
|
|
* GHJK: Four-byte ASN
|
|
|
|
* MN: Two byte value
|
|
|
|
* OPQR: Four byte value
|
|
|
|
*
|
|
|
|
*/
|
2019-10-17 16:08:16 +02:00
|
|
|
/* IPv6 case : look for last ':' */
|
|
|
|
if (*token == ecommunity_token_rt6 ||
|
|
|
|
*token == ecommunity_token_val6) {
|
|
|
|
char *limit;
|
|
|
|
|
|
|
|
limit = endptr = strrchr(p, ':');
|
|
|
|
if (!endptr)
|
|
|
|
goto error;
|
2019-10-17 16:11:57 +02:00
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
endptr++;
|
|
|
|
as = strtoul(endptr, &endptr, 10);
|
|
|
|
if (*endptr != '\0' || as == BGP_AS4_MAX)
|
|
|
|
goto error;
|
2019-10-17 16:11:57 +02:00
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
memcpy(buf, p, (limit - p));
|
|
|
|
buf[limit - p] = '\0';
|
|
|
|
ret = inet_pton(AF_INET6, buf, &ip6);
|
|
|
|
if (ret == 0)
|
|
|
|
goto error;
|
2019-10-17 16:11:57 +02:00
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
ecomm_type = ECOMMUNITY_ENCODE_TRANS_EXP;
|
|
|
|
if (ecommunity_encode_internal(ecomm_type,
|
2019-10-17 16:11:57 +02:00
|
|
|
ECOMMUNITY_FLOWSPEC_REDIRECT_IPV6,
|
|
|
|
1, 0, NULL, &ip6, as, eval_ptr))
|
2019-10-17 16:08:16 +02:00
|
|
|
goto error;
|
2019-10-17 16:11:57 +02:00
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
*token = ecommunity_token_val6;
|
|
|
|
while (isdigit((int)*p) || *p == ':' || *p == '.') {
|
|
|
|
p++;
|
|
|
|
}
|
|
|
|
return p;
|
|
|
|
}
|
2019-08-06 16:54:52 +02:00
|
|
|
while (isdigit((unsigned char)*p) || *p == ':' || *p == '.') {
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
if (*p == ':') {
|
2002-12-13 21:15:29 +01:00
|
|
|
if (separator)
|
|
|
|
goto error;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
separator = 1;
|
|
|
|
digit = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
if ((p - str) > INET_ADDRSTRLEN)
|
|
|
|
goto error;
|
|
|
|
memset(buf, 0, INET_ADDRSTRLEN + 1);
|
|
|
|
memcpy(buf, str, p - str);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (dot) {
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
/* Parsing A.B.C.D in:
|
|
|
|
* A.B.C.D:MN
|
|
|
|
*/
|
|
|
|
ret = inet_aton(buf, &ip);
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ret == 0)
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
/* ASN */
|
|
|
|
as = strtoul(buf, &endptr, 10);
|
|
|
|
if (*endptr != '\0' || as == BGP_AS4_MAX)
|
|
|
|
goto error;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
} else if (*p == '.') {
|
|
|
|
if (separator)
|
|
|
|
goto error;
|
|
|
|
dot++;
|
|
|
|
if (dot > 4)
|
|
|
|
goto error;
|
|
|
|
} else {
|
|
|
|
digit = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
/* We're past the IP/ASN part */
|
|
|
|
if (separator) {
|
|
|
|
val *= 10;
|
|
|
|
val += (*p - '0');
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
p++;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Low digit part must be there. */
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
if (!digit || !separator)
|
2002-12-13 21:15:29 +01:00
|
|
|
goto error;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-15 21:31:01 +02:00
|
|
|
/* Encode result into extended community. */
|
2002-12-13 21:15:29 +01:00
|
|
|
if (dot)
|
2017-05-15 21:31:01 +02:00
|
|
|
ecomm_type = ECOMMUNITY_ENCODE_IP;
|
[bgpd] Merge AS4 support
2007-10-14 Paul Jakma <paul.jakma@sun.com>
* NEWS: Note that MRT dumps are now version 2
* (general) Merge in Juergen Kammer's AS4 patch.
2007-09-27 Paul Jakma <paul.jakma@sun.com>
* bgp_aspath.c: (assegment_normalise) remove duplicates from
from sets.
(aspath_reconcile_as4) disregard a broken part of the RFC around
error handling in path reconciliation.
* aspath_test.c: Test dupe-weeding from sets.
Test that reconciliation merges AS_PATH and AS4_PATH where
former is shorter than latter.
2007-09-26 Paul Jakma <paul.jakma@sun.com>
* aspath_test.c: Test AS4_PATH reconcilation where length
of AS_PATH and AS4_PATH is same.
2007-09-25 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (peek_for_as4_capability) Fix to work.
* bgp_packet.c: (bgp_open_receive) Fix sanity check of as4.
* tests/bgp_capability_test.c: (general) Extend tests to validate
peek_for_as4_capability.
Add test of full OPEN Option block, with multiple capabilities,
both as a series of Option, and a single option.
Add some crap to beginning of stream, to prevent code depending
on getp == 0.
2007-09-18 Paul Jakma <paul.jakma@sun.com>
* bgp_open.c: (bgp_capability_as4) debug printf inline with others.
(peek_for_as4_capability) There's no need to signal failure, as
failure is better dealt with through full capability parser -
just return the AS4, simpler.
* bgp_packet.c: (bgp_open_receive) Update to match
peek_for_as4_capability change.
Allow use of BGP_AS_TRANS by 2b speakers.
Use NOTIFY_OPEN_ERR rather than CEASE for OPEN parsing errors.
(bgp_capability_msg_parse) missing argument to debug print
(bgp_capability_receive) missing return values.
* tests/bgp_capability_test.c: (parse_test) update for changes to
peek_for_as4_capability
2007-07-25 Paul Jakma <paul.jakma@sun.com>
* Remove 2-byte size macros, just make existing macros take
argument to indicate which size to use.
Adjust all users - typically they want '1'.
* bgp_aspath.c: (aspath_has_as4) New, return 1 if there are any
as4's in a path.
(aspath_put) Return the number of bytes actually written, to
fix the bug Juergen noted: Splitting of segments will change
the number of bytes written from that already written to the
AS_PATH header.
(aspath_snmp_pathseg) Pass 2-byte flag to aspath_put. SNMP
is still defined as 2b.
(aspath_aggregate) fix latent bug.
(aspath_reconcile_as4) AS_PATH+NEW_AS_PATH reconciliation
function.
(aspath_key_make) Hash the AS_PATH string, rather than
just taking the addition of assegment ASes as the hash value,
hopefully sligthly more collision resistant.
(bgp_attr_munge_as4_attrs) Collide the NEW_ attributes
together with the OLD 2-byte forms, code Juergen
had in bgp_attr_parse but re-organised a bit.
(bgp_attr_parse) Bunch of code from Juergen moves
to previous function.
(bgp_packet_attribute) Compact significantly by
just /always/ using extended-length attr header.
Fix bug Juergen noted, by using aspath_put's
(new) returned size value for the attr header rather
than the (guesstimate) of aspath_size() - the two could
differ when aspath_put had to split large segments, unlikely
this bug was ever hit in the 'wild'.
(bgp_dump_routes_attr) Always use extended-len and
use aspath_put return for header length. Output 4b ASN
for AS_PATH and AGGREGATOR.
* bgp_ecommunity.c: (ecommunity_{hash_make,cmp}) fix
hash callback declarations to match prototypes.
(ecommunity_gettoken) Updated for ECOMMUNITY_ENCODE_AS4,
complete rewrite of Juergen's changes (no asdot support)
* bgp_open.c: (bgp_capability_as4) New, does what it says
on the tin.
(peek_for_as4_capability) Rewritten to use streams and
bgp_capability_as4.
* bgp_packet.c: (bgp_open_send) minor edit
checked (in the abstract at least) with Juergen.
Changes are to be more accepting, e.g, allow AS_TRANS on
a 2-byte session.
* (general) Update all commands to use CMD_AS_RANGE.
* bgp_vty.c: (bgp_clear) Fix return vals to use CMD_..
Remove stuff replicated by VTY_GET_LONG
(bgp_clear_vty) Return bgp_clear directly to vty.
* tests/aspath_test.c: Exercise 32bit parsing. Test reconcile
function.
* tests/ecommunity_test.c: New, test AS4 ecommunity changes,
positive test only at this time, error cases not tested yet.
2007-07-25 Juergen Kammer <j.kammer@eurodata.de>
* (general) AS4 support.
* bgpd.h: as_t changes to 4-bytes.
* bgp_aspath.h: Add BGP_AS4_MAX and BGP_AS_TRANS defines.
* bgp_aspath.c: AS_VALUE_SIZE becomes 4-byte, AS16_VALUE_SIZE
added for 2-byte.
Add AS16 versions of length calc macros.
(aspath_count_numas) New, count number of ASes.
(aspath_has_as4) New, return 1 if there are any as4's in a
path.
(assegments_parse) Interpret assegment as 4 or 2 byte,
according to how the caller instructs us, with a new
argument.
(aspath_parse) Add use32bit argument to pass to
assegments_parse. Adjust all its callers to pass 1, unless
otherwise noted.
(assegment_data_put) Adjust to be able to write 2 or 4 byte
AS, according to new use32bit argument.
(aspath_put) Adjust to write 2 or 4.
(aspath_gettoken) Use a long for passed in asno.
* bgp_attr.c: (attr_str) Add BGP_ATTR_AS4_PATH and
BGP_ATTR_AS4_AGGREGATOR.
(bgp_attr_aspath) Call aspath_parse with right 2/4 arg, as
determined by received-capability flag.
(bgp_attr_aspath_check) New, code previously in attr_aspath
but moved to new func so it can be run after NEW_AS_PATH
reconciliation.
(bgp_attr_as4_path) New, handle NEW_AS_PATH.
(bgp_attr_aggregator) Adjust to cope with 2/4 byte ASes.
(bgp_attr_as4_aggregator) New, read NEW_AGGREGATOR.
(bgp_attr_parse) Add handoffs to previous parsers for the two
new AS4 NEW_ attributes.
Various checks added for NEW/OLD reconciliation.
(bgp_packet_attribute) Support 2/4 for AS_PATH and
AGGREGATOR, detect when NEW_ attrs need to be sent.
* bgp_debug.{c,h}: Add 'debug bgp as4'.
* bgp_dump.c: MRTv2 support, unconditionally enabled, which
supports AS4. Based on patches from Erik (RIPE?).
* bgp_ecommunity.c: (ecommunity_ecom2str) ECOMMUNITY_ENCODE_AS4
support.
* bgp_open.c: (peek_for_as4_capability) New, peek for AS4
capability prior to full capability parsing, so we know which
ASN to use for struct peer lookup.
(bgp_open_capability) Always send AS4 capability.
* bgp_packet.c: (bgp_open_send) AS4 handling for AS field
(bgp_open_receive) Peek for AS4 capability first, and figure
out which AS to believe.
* bgp_vty.c: (bgp_show_peer) Print AS4 cap
* tests/aspath_test.c: Support asn32 changes, call aspath_parse
with 16 bit.
* vtysh/extract.pl: AS4 compatibility for router bgp ASNUMBER
* vtysh/extract.pl.in: AS4 compatibility for router bgp ASNUMBER
* vtysh/vtysh.c: AS4 compatibility for router bgp ASNUMBER
2007-10-15 00:32:21 +02:00
|
|
|
else if (as > BGP_AS_MAX)
|
2017-05-15 21:31:01 +02:00
|
|
|
ecomm_type = ECOMMUNITY_ENCODE_AS4;
|
2002-12-13 21:15:29 +01:00
|
|
|
else
|
2017-05-15 21:31:01 +02:00
|
|
|
ecomm_type = ECOMMUNITY_ENCODE_AS;
|
|
|
|
if (ecommunity_encode(ecomm_type, 0, 1, as, ip, val, eval))
|
|
|
|
goto error;
|
2002-12-13 21:15:29 +01:00
|
|
|
*token = ecommunity_token_val;
|
|
|
|
return p;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
error:
|
|
|
|
*token = ecommunity_token_unknown;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
static struct ecommunity *ecommunity_str2com_internal(const char *str, int type,
|
|
|
|
int keyword_included,
|
|
|
|
bool is_ipv6_extcomm)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct ecommunity *ecom = NULL;
|
2015-05-20 03:12:17 +02:00
|
|
|
enum ecommunity_token token = ecommunity_token_unknown;
|
2019-10-17 16:08:16 +02:00
|
|
|
struct ecommunity_val_ipv6 eval;
|
2002-12-13 21:15:29 +01:00
|
|
|
int keyword = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
if (is_ipv6_extcomm)
|
|
|
|
token = ecommunity_token_rt6;
|
|
|
|
while ((str = ecommunity_gettoken(str, (void *)&eval, &token))) {
|
2002-12-13 21:15:29 +01:00
|
|
|
switch (token) {
|
|
|
|
case ecommunity_token_rt:
|
2023-01-27 14:10:08 +01:00
|
|
|
case ecommunity_token_rt6:
|
2002-12-13 21:15:29 +01:00
|
|
|
case ecommunity_token_soo:
|
|
|
|
if (!keyword_included || keyword) {
|
|
|
|
if (ecom)
|
bgpd: Try fix extcommunity resource allocation probs, particularly with 'set extcom..'
* Extended communities has some kind of resource allocation problem which
causes a double-free if the 'set extcommunity ...' command is used.
Try fix by properly interning extcommunities.
Also, more generally, make unintern functions take a double pointer
so they can NULL out callers references - a usefully defensive programming
pattern for functions which make refs invalid.
Sadly, this patch doesn't fix the problem entirely - crashes still
occur on session clear.
* bgp_ecommunity.h: (ecommunity_{free,unintern}) take double pointer
args.
* bgp_community.h: (community_unintern) ditto
* bgp_attr.h: (bgp_attr_intern) ditto
* bgp_aspath.h: (bgp_aspath.h) ditto
* (general) update all callers of above
* bgp_routemap.c: (route_set_ecommunity_{rt,soo}) intern the new extcom added
to the attr, and unintern any old one.
(route_set_ecommunity_{rt,soo}_compile) intern the extcom to be used
for the route-map set.
(route_set_ecommunity_*_free) unintern to match, instead of free
(route_set_ecommunity_soo) Do as _rt does and don't just leak
any pre-existing community, add to it (is additive right though?)
2010-11-23 22:28:03 +01:00
|
|
|
ecommunity_free(&ecom);
|
2002-12-13 21:15:29 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
keyword = 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
if (token == ecommunity_token_rt ||
|
|
|
|
token == ecommunity_token_rt6) {
|
2002-12-13 21:15:29 +01:00
|
|
|
type = ECOMMUNITY_ROUTE_TARGET;
|
|
|
|
}
|
|
|
|
if (token == ecommunity_token_soo) {
|
|
|
|
type = ECOMMUNITY_SITE_ORIGIN;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case ecommunity_token_val:
|
|
|
|
if (keyword_included) {
|
|
|
|
if (!keyword) {
|
2019-10-17 16:11:57 +02:00
|
|
|
ecommunity_free(&ecom);
|
2002-12-13 21:15:29 +01:00
|
|
|
return NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
keyword = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
if (ecom == NULL)
|
|
|
|
ecom = ecommunity_new();
|
|
|
|
eval.val[1] = type;
|
2020-07-02 08:14:41 +02:00
|
|
|
ecommunity_add_val_internal(ecom, (void *)&eval,
|
|
|
|
false, false,
|
2019-10-17 16:08:16 +02:00
|
|
|
ecom->unit_size);
|
|
|
|
break;
|
|
|
|
case ecommunity_token_val6:
|
|
|
|
if (keyword_included) {
|
|
|
|
if (!keyword) {
|
2019-10-17 16:11:57 +02:00
|
|
|
ecommunity_free(&ecom);
|
2019-10-17 16:08:16 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
keyword = 0;
|
|
|
|
}
|
|
|
|
if (ecom == NULL)
|
|
|
|
ecom = ecommunity_new();
|
|
|
|
ecom->unit_size = IPV6_ECOMMUNITY_SIZE;
|
|
|
|
eval.val[1] = type;
|
|
|
|
ecommunity_add_val_internal(ecom, (void *)&eval, false, false,
|
|
|
|
ecom->unit_size);
|
2017-07-17 14:03:14 +02:00
|
|
|
break;
|
2002-12-13 21:15:29 +01:00
|
|
|
case ecommunity_token_unknown:
|
|
|
|
if (ecom)
|
bgpd: Try fix extcommunity resource allocation probs, particularly with 'set extcom..'
* Extended communities has some kind of resource allocation problem which
causes a double-free if the 'set extcommunity ...' command is used.
Try fix by properly interning extcommunities.
Also, more generally, make unintern functions take a double pointer
so they can NULL out callers references - a usefully defensive programming
pattern for functions which make refs invalid.
Sadly, this patch doesn't fix the problem entirely - crashes still
occur on session clear.
* bgp_ecommunity.h: (ecommunity_{free,unintern}) take double pointer
args.
* bgp_community.h: (community_unintern) ditto
* bgp_attr.h: (bgp_attr_intern) ditto
* bgp_aspath.h: (bgp_aspath.h) ditto
* (general) update all callers of above
* bgp_routemap.c: (route_set_ecommunity_{rt,soo}) intern the new extcom added
to the attr, and unintern any old one.
(route_set_ecommunity_{rt,soo}_compile) intern the extcom to be used
for the route-map set.
(route_set_ecommunity_*_free) unintern to match, instead of free
(route_set_ecommunity_soo) Do as _rt does and don't just leak
any pre-existing community, add to it (is additive right though?)
2010-11-23 22:28:03 +01:00
|
|
|
ecommunity_free(&ecom);
|
2002-12-13 21:15:29 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ecom;
|
|
|
|
}
|
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
/* Convert string to extended community attribute.
|
2020-07-02 08:14:41 +02:00
|
|
|
*
|
|
|
|
* When type is already known, please specify both str and type. str
|
|
|
|
* should not include keyword such as "rt" and "soo". Type is
|
|
|
|
* ECOMMUNITY_ROUTE_TARGET or ECOMMUNITY_SITE_ORIGIN.
|
|
|
|
* keyword_included should be zero.
|
|
|
|
*
|
|
|
|
* For example route-map's "set extcommunity" command case:
|
|
|
|
*
|
|
|
|
* "rt 100:1 100:2 100:3" -> str = "100:1 100:2 100:3"
|
|
|
|
* type = ECOMMUNITY_ROUTE_TARGET
|
|
|
|
* keyword_included = 0
|
|
|
|
*
|
|
|
|
* "soo 100:1" -> str = "100:1"
|
|
|
|
* type = ECOMMUNITY_SITE_ORIGIN
|
|
|
|
* keyword_included = 0
|
|
|
|
*
|
|
|
|
* When string includes keyword for each extended community value.
|
|
|
|
* Please specify keyword_included as non-zero value.
|
|
|
|
*
|
|
|
|
* For example standard extcommunity-list case:
|
|
|
|
*
|
|
|
|
* "rt 100:1 rt 100:2 soo 100:1" -> str = "rt 100:1 rt 100:2 soo 100:1"
|
|
|
|
* type = 0
|
|
|
|
* keyword_include = 1
|
|
|
|
*/
|
2019-10-17 16:08:16 +02:00
|
|
|
struct ecommunity *ecommunity_str2com(const char *str, int type,
|
|
|
|
int keyword_included)
|
|
|
|
{
|
|
|
|
return ecommunity_str2com_internal(str, type,
|
|
|
|
keyword_included, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ecommunity *ecommunity_str2com_ipv6(const char *str, int type,
|
|
|
|
int keyword_included)
|
|
|
|
{
|
|
|
|
return ecommunity_str2com_internal(str, type,
|
|
|
|
keyword_included, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int ecommunity_rt_soo_str_internal(char *buf, size_t bufsz,
|
|
|
|
const uint8_t *pnt, int type,
|
|
|
|
int sub_type, int format,
|
|
|
|
unsigned short ecom_size)
|
2017-05-15 21:31:01 +02:00
|
|
|
{
|
|
|
|
int len = 0;
|
|
|
|
const char *prefix;
|
2019-10-17 16:08:16 +02:00
|
|
|
char buf_local[INET6_ADDRSTRLEN];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-15 21:31:01 +02:00
|
|
|
/* For parse Extended Community attribute tupple. */
|
2017-09-13 17:18:51 +02:00
|
|
|
struct ecommunity_as eas;
|
|
|
|
struct ecommunity_ip eip;
|
2019-10-17 16:08:16 +02:00
|
|
|
struct ecommunity_ip6 eip6;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-15 21:31:01 +02:00
|
|
|
/* Determine prefix for string, if any. */
|
|
|
|
switch (format) {
|
|
|
|
case ECOMMUNITY_FORMAT_COMMUNITY_LIST:
|
|
|
|
prefix = (sub_type == ECOMMUNITY_ROUTE_TARGET ? "rt " : "soo ");
|
|
|
|
break;
|
|
|
|
case ECOMMUNITY_FORMAT_DISPLAY:
|
|
|
|
prefix = (sub_type == ECOMMUNITY_ROUTE_TARGET ? "RT:" : "SoO:");
|
|
|
|
break;
|
|
|
|
case ECOMMUNITY_FORMAT_ROUTE_MAP:
|
|
|
|
prefix = "";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
prefix = "";
|
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-15 21:31:01 +02:00
|
|
|
/* Put string into buffer. */
|
|
|
|
if (type == ECOMMUNITY_ENCODE_AS4) {
|
2017-09-07 15:58:18 +02:00
|
|
|
pnt = ptr_get_be32(pnt, &eas.as);
|
2017-05-15 21:31:01 +02:00
|
|
|
eas.val = (*pnt++ << 8);
|
|
|
|
eas.val |= (*pnt++);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-11-22 01:01:55 +01:00
|
|
|
len = snprintf(buf, bufsz, "%s%u:%u", prefix, eas.as, eas.val);
|
2017-05-15 21:31:01 +02:00
|
|
|
} else if (type == ECOMMUNITY_ENCODE_AS) {
|
2019-10-17 16:08:16 +02:00
|
|
|
if (ecom_size == ECOMMUNITY_SIZE) {
|
|
|
|
eas.as = (*pnt++ << 8);
|
|
|
|
eas.as |= (*pnt++);
|
|
|
|
pnt = ptr_get_be32(pnt, &eas.val);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-07-02 08:14:41 +02:00
|
|
|
len = snprintf(buf, bufsz, "%s%u:%u", prefix, eas.as,
|
|
|
|
eas.val);
|
2019-10-17 16:08:16 +02:00
|
|
|
} else {
|
|
|
|
/* this is an IPv6 ext community
|
2020-04-20 18:02:46 +02:00
|
|
|
* first 16 bytes stands for IPv6 addres
|
2019-10-17 16:08:16 +02:00
|
|
|
*/
|
|
|
|
memcpy(&eip6.ip, pnt, 16);
|
|
|
|
pnt += 16;
|
|
|
|
eip6.val = (*pnt++ << 8);
|
|
|
|
eip6.val |= (*pnt++);
|
|
|
|
|
2020-07-02 08:14:41 +02:00
|
|
|
inet_ntop(AF_INET6, &eip6.ip, buf_local,
|
|
|
|
sizeof(buf_local));
|
2019-10-17 16:08:16 +02:00
|
|
|
len = snprintf(buf, bufsz, "%s%s:%u", prefix,
|
|
|
|
buf_local, eip6.val);
|
|
|
|
}
|
2017-05-15 21:31:01 +02:00
|
|
|
} else if (type == ECOMMUNITY_ENCODE_IP) {
|
|
|
|
memcpy(&eip.ip, pnt, 4);
|
|
|
|
pnt += 4;
|
|
|
|
eip.val = (*pnt++ << 8);
|
|
|
|
eip.val |= (*pnt++);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-10-15 21:33:09 +02:00
|
|
|
len = snprintfrr(buf, bufsz, "%s%pI4:%u", prefix, &eip.ip,
|
|
|
|
eip.val);
|
2017-05-15 21:31:01 +02:00
|
|
|
}
|
2019-11-22 01:01:55 +01:00
|
|
|
|
|
|
|
/* consume value */
|
|
|
|
(void)pnt;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-15 21:31:01 +02:00
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2019-10-17 16:08:16 +02:00
|
|
|
static int ecommunity_rt_soo_str(char *buf, size_t bufsz, const uint8_t *pnt,
|
|
|
|
int type, int sub_type, int format)
|
|
|
|
{
|
|
|
|
return ecommunity_rt_soo_str_internal(buf, bufsz, pnt, type,
|
|
|
|
sub_type, format,
|
|
|
|
ECOMMUNITY_SIZE);
|
|
|
|
}
|
|
|
|
|
2021-08-24 09:58:20 +02:00
|
|
|
/* Helper function to convert IEEE-754 Floating Point to uint32 */
|
|
|
|
static uint32_t ieee_float_uint32_to_uint32(uint32_t u)
|
|
|
|
{
|
|
|
|
union {
|
|
|
|
float r;
|
|
|
|
uint32_t d;
|
|
|
|
} f = {.d = u};
|
|
|
|
|
|
|
|
return (uint32_t)f.r;
|
|
|
|
}
|
|
|
|
|
2021-08-29 20:54:13 +02:00
|
|
|
static int ecommunity_lb_str(char *buf, size_t bufsz, const uint8_t *pnt,
|
|
|
|
bool disable_ieee_floating)
|
2020-03-24 20:00:24 +01:00
|
|
|
{
|
|
|
|
int len = 0;
|
|
|
|
as_t as;
|
2021-08-24 09:58:20 +02:00
|
|
|
uint32_t bw_tmp, bw;
|
2020-03-24 20:00:24 +01:00
|
|
|
char bps_buf[20] = {0};
|
|
|
|
|
|
|
|
#define ONE_GBPS_BYTES (1000 * 1000 * 1000 / 8)
|
|
|
|
#define ONE_MBPS_BYTES (1000 * 1000 / 8)
|
|
|
|
#define ONE_KBPS_BYTES (1000 / 8)
|
|
|
|
|
|
|
|
as = (*pnt++ << 8);
|
|
|
|
as |= (*pnt++);
|
2021-08-24 09:58:20 +02:00
|
|
|
(void)ptr_get_be32(pnt, &bw_tmp);
|
|
|
|
|
2021-08-29 20:54:13 +02:00
|
|
|
bw = disable_ieee_floating ? bw_tmp
|
|
|
|
: ieee_float_uint32_to_uint32(bw_tmp);
|
2021-08-24 09:58:20 +02:00
|
|
|
|
2020-03-24 20:00:24 +01:00
|
|
|
if (bw >= ONE_GBPS_BYTES)
|
2020-04-20 20:12:38 +02:00
|
|
|
snprintf(bps_buf, sizeof(bps_buf), "%.3f Gbps",
|
|
|
|
(float)(bw / ONE_GBPS_BYTES));
|
2020-03-24 20:00:24 +01:00
|
|
|
else if (bw >= ONE_MBPS_BYTES)
|
2020-04-20 20:12:38 +02:00
|
|
|
snprintf(bps_buf, sizeof(bps_buf), "%.3f Mbps",
|
|
|
|
(float)(bw / ONE_MBPS_BYTES));
|
2020-03-24 20:00:24 +01:00
|
|
|
else if (bw >= ONE_KBPS_BYTES)
|
2020-04-20 20:12:38 +02:00
|
|
|
snprintf(bps_buf, sizeof(bps_buf), "%.3f Kbps",
|
|
|
|
(float)(bw / ONE_KBPS_BYTES));
|
2020-03-24 20:00:24 +01:00
|
|
|
else
|
2020-04-20 20:12:38 +02:00
|
|
|
snprintf(bps_buf, sizeof(bps_buf), "%u bps", bw * 8);
|
2020-03-24 20:00:24 +01:00
|
|
|
|
|
|
|
len = snprintf(buf, bufsz, "LB:%u:%u (%s)", as, bw, bps_buf);
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Convert extended community attribute to string.
|
|
|
|
|
|
|
|
Due to historical reason of industry standard implementation, there
|
|
|
|
are three types of format.
|
|
|
|
|
|
|
|
route-map set extcommunity format
|
2020-03-27 12:35:23 +01:00
|
|
|
"rt 100:1 100:2soo 100:3"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
extcommunity-list
|
2020-03-27 12:35:23 +01:00
|
|
|
"rt 100:1 rt 100:2 soo 100:3show [ip] bgp" and extcommunity-list regular expression matching
|
2002-12-13 21:15:29 +01:00
|
|
|
"RT:100:1 RT:100:2 SoO:100:3"
|
|
|
|
|
|
|
|
For each formath please use below definition for format:
|
|
|
|
|
|
|
|
ECOMMUNITY_FORMAT_ROUTE_MAP
|
|
|
|
ECOMMUNITY_FORMAT_COMMUNITY_LIST
|
|
|
|
ECOMMUNITY_FORMAT_DISPLAY
|
2016-08-09 10:47:03 +02:00
|
|
|
|
|
|
|
Filter is added to display only ECOMMUNITY_ROUTE_TARGET in some cases.
|
|
|
|
0 value displays all
|
2002-12-13 21:15:29 +01:00
|
|
|
*/
|
2016-08-09 10:47:03 +02:00
|
|
|
char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2021-01-17 22:08:03 +01:00
|
|
|
uint32_t i;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t *pnt;
|
2018-05-17 09:30:28 +02:00
|
|
|
uint8_t type = 0;
|
|
|
|
uint8_t sub_type = 0;
|
2002-12-13 21:15:29 +01:00
|
|
|
int str_size;
|
2004-06-04 19:58:18 +02:00
|
|
|
char *str_buf;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-11-18 18:50:48 +01:00
|
|
|
if (!ecom || ecom->size == 0)
|
2019-11-22 01:01:55 +01:00
|
|
|
return XCALLOC(MTYPE_ECOMMUNITY_STR, 1);
|
|
|
|
|
|
|
|
/* ecom strlen + space + null term */
|
|
|
|
str_size = (ecom->size * (ECOMMUNITY_STRLEN + 1)) + 1;
|
|
|
|
str_buf = XCALLOC(MTYPE_ECOMMUNITY_STR, str_size);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-11-22 01:01:55 +01:00
|
|
|
char encbuf[128];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
for (i = 0; i < ecom->size; i++) {
|
|
|
|
int unk_ecom = 0;
|
2019-11-22 01:01:55 +01:00
|
|
|
memset(encbuf, 0x00, sizeof(encbuf));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-20 12:20:02 +02:00
|
|
|
/* Space between each value. */
|
2019-11-22 01:01:55 +01:00
|
|
|
if (i > 0)
|
|
|
|
strlcat(str_buf, " ", str_size);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-11-22 01:01:55 +01:00
|
|
|
/* Retrieve value field */
|
2019-11-29 11:57:29 +01:00
|
|
|
pnt = ecom->val + (i * ecom->unit_size);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-11-22 01:01:55 +01:00
|
|
|
/* High-order octet is the type */
|
2017-05-15 21:31:01 +02:00
|
|
|
type = *pnt++;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
if (type == ECOMMUNITY_ENCODE_AS || type == ECOMMUNITY_ENCODE_IP
|
2017-05-15 21:31:01 +02:00
|
|
|
|| type == ECOMMUNITY_ENCODE_AS4) {
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Low-order octet of type. */
|
|
|
|
sub_type = *pnt++;
|
|
|
|
if (sub_type != ECOMMUNITY_ROUTE_TARGET
|
2018-11-27 16:32:45 +01:00
|
|
|
&& sub_type != ECOMMUNITY_SITE_ORIGIN) {
|
|
|
|
if (sub_type ==
|
|
|
|
ECOMMUNITY_FLOWSPEC_REDIRECT_IPV4 &&
|
|
|
|
type == ECOMMUNITY_ENCODE_IP) {
|
|
|
|
struct in_addr *ipv4 =
|
|
|
|
(struct in_addr *)pnt;
|
2022-11-29 09:23:20 +01:00
|
|
|
snprintfrr(encbuf, sizeof(encbuf),
|
|
|
|
"NH:%pI4:%d", ipv4, pnt[5]);
|
2020-03-24 20:00:24 +01:00
|
|
|
} else if (sub_type ==
|
|
|
|
ECOMMUNITY_LINK_BANDWIDTH &&
|
|
|
|
type == ECOMMUNITY_ENCODE_AS) {
|
2021-08-29 20:54:13 +02:00
|
|
|
ecommunity_lb_str(
|
|
|
|
encbuf, sizeof(encbuf), pnt,
|
|
|
|
ecom->disable_ieee_floating);
|
2018-11-27 16:32:45 +01:00
|
|
|
} else
|
|
|
|
unk_ecom = 1;
|
2019-11-22 01:01:55 +01:00
|
|
|
} else {
|
|
|
|
ecommunity_rt_soo_str(encbuf, sizeof(encbuf),
|
|
|
|
pnt, type, sub_type,
|
|
|
|
format);
|
|
|
|
}
|
2011-09-26 11:17:05 +02:00
|
|
|
} else if (type == ECOMMUNITY_ENCODE_OPAQUE) {
|
|
|
|
if (filter == ECOMMUNITY_ROUTE_TARGET)
|
2017-05-15 21:31:01 +02:00
|
|
|
continue;
|
2011-09-26 11:17:05 +02:00
|
|
|
if (*pnt == ECOMMUNITY_OPAQUE_SUBTYPE_ENCAP) {
|
2016-01-12 19:42:00 +01:00
|
|
|
uint16_t tunneltype;
|
|
|
|
memcpy(&tunneltype, pnt + 5, 2);
|
2011-09-26 11:17:05 +02:00
|
|
|
tunneltype = ntohs(tunneltype);
|
2019-11-22 01:01:55 +01:00
|
|
|
|
|
|
|
snprintf(encbuf, sizeof(encbuf), "ET:%d",
|
|
|
|
tunneltype);
|
2017-11-13 12:19:52 +01:00
|
|
|
} else if (*pnt == ECOMMUNITY_EVPN_SUBTYPE_DEF_GW) {
|
2019-11-22 01:01:55 +01:00
|
|
|
strlcpy(encbuf, "Default Gateway",
|
|
|
|
sizeof(encbuf));
|
|
|
|
} else {
|
2011-09-26 11:17:05 +02:00
|
|
|
unk_ecom = 1;
|
2019-11-22 01:01:55 +01:00
|
|
|
}
|
2011-09-26 11:17:05 +02:00
|
|
|
} else if (type == ECOMMUNITY_ENCODE_EVPN) {
|
2017-05-15 21:31:01 +02:00
|
|
|
if (filter == ECOMMUNITY_ROUTE_TARGET)
|
|
|
|
continue;
|
2017-10-09 13:55:57 +02:00
|
|
|
if (*pnt == ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC) {
|
|
|
|
struct ethaddr rmac;
|
2017-07-17 14:03:14 +02:00
|
|
|
pnt++;
|
2017-10-09 13:55:57 +02:00
|
|
|
memcpy(&rmac, pnt, ETH_ALEN);
|
2019-11-22 01:01:55 +01:00
|
|
|
|
|
|
|
snprintf(encbuf, sizeof(encbuf),
|
|
|
|
"Rmac:%02x:%02x:%02x:%02x:%02x:%02x",
|
|
|
|
(uint8_t)rmac.octet[0],
|
|
|
|
(uint8_t)rmac.octet[1],
|
|
|
|
(uint8_t)rmac.octet[2],
|
|
|
|
(uint8_t)rmac.octet[3],
|
|
|
|
(uint8_t)rmac.octet[4],
|
|
|
|
(uint8_t)rmac.octet[5]);
|
2017-05-15 23:50:21 +02:00
|
|
|
} else if (*pnt
|
|
|
|
== ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY) {
|
2018-03-27 21:13:34 +02:00
|
|
|
uint32_t seqnum;
|
|
|
|
uint8_t flags = *++pnt;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-15 23:50:21 +02:00
|
|
|
memcpy(&seqnum, pnt + 2, 4);
|
|
|
|
seqnum = ntohl(seqnum);
|
2019-11-22 01:01:55 +01:00
|
|
|
|
|
|
|
snprintf(encbuf, sizeof(encbuf), "MM:%u",
|
|
|
|
seqnum);
|
|
|
|
|
|
|
|
if (CHECK_FLAG(
|
|
|
|
flags,
|
|
|
|
ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY))
|
|
|
|
strlcat(encbuf, ", sticky MAC",
|
|
|
|
sizeof(encbuf));
|
2018-08-09 06:45:37 +02:00
|
|
|
} else if (*pnt == ECOMMUNITY_EVPN_SUBTYPE_ND) {
|
|
|
|
uint8_t flags = *++pnt;
|
|
|
|
|
2019-11-22 01:01:55 +01:00
|
|
|
if (CHECK_FLAG(
|
|
|
|
flags,
|
|
|
|
ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG))
|
|
|
|
strlcpy(encbuf, "ND:Router Flag",
|
|
|
|
sizeof(encbuf));
|
2020-03-28 17:35:08 +01:00
|
|
|
if (CHECK_FLAG(
|
|
|
|
flags,
|
|
|
|
ECOMMUNITY_EVPN_SUBTYPE_PROXY_FLAG))
|
|
|
|
strlcpy(encbuf, "ND:Proxy",
|
|
|
|
sizeof(encbuf));
|
2020-03-27 21:56:08 +01:00
|
|
|
} else if (*pnt
|
|
|
|
== ECOMMUNITY_EVPN_SUBTYPE_ES_IMPORT_RT) {
|
|
|
|
struct ethaddr mac;
|
|
|
|
|
|
|
|
pnt++;
|
|
|
|
memcpy(&mac, pnt, ETH_ALEN);
|
|
|
|
snprintf(encbuf,
|
|
|
|
sizeof(encbuf),
|
|
|
|
"ES-Import-Rt:%02x:%02x:%02x:%02x:%02x:%02x",
|
|
|
|
(uint8_t)mac.octet[0],
|
|
|
|
(uint8_t)mac.octet[1],
|
|
|
|
(uint8_t)mac.octet[2],
|
|
|
|
(uint8_t)mac.octet[3],
|
|
|
|
(uint8_t)mac.octet[4],
|
|
|
|
(uint8_t)mac.octet[5]);
|
|
|
|
} else if (*pnt
|
|
|
|
== ECOMMUNITY_EVPN_SUBTYPE_ESI_LABEL) {
|
|
|
|
uint8_t flags = *++pnt;
|
|
|
|
|
|
|
|
snprintf(encbuf,
|
|
|
|
sizeof(encbuf), "ESI-label-Rt:%s",
|
|
|
|
(flags &
|
|
|
|
ECOMMUNITY_EVPN_SUBTYPE_ESI_SA_FLAG) ?
|
|
|
|
"SA":"AA");
|
2020-05-09 01:35:09 +02:00
|
|
|
} else if (*pnt
|
|
|
|
== ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION) {
|
|
|
|
uint8_t alg;
|
|
|
|
uint16_t pref;
|
|
|
|
uint16_t bmap;
|
|
|
|
|
|
|
|
alg = *(pnt + 1);
|
|
|
|
memcpy(&bmap, pnt + 2, 2);
|
|
|
|
bmap = ntohs(bmap);
|
|
|
|
memcpy(&pref, pnt + 5, 2);
|
|
|
|
pref = ntohs(pref);
|
|
|
|
|
|
|
|
if (bmap)
|
|
|
|
snprintf(
|
|
|
|
encbuf, sizeof(encbuf),
|
|
|
|
"DF: (alg: %u, bmap: 0x%x pref: %u)",
|
|
|
|
alg, bmap, pref);
|
|
|
|
else
|
|
|
|
snprintf(encbuf, sizeof(encbuf),
|
|
|
|
"DF: (alg: %u, pref: %u)", alg,
|
|
|
|
pref);
|
2017-07-17 14:03:14 +02:00
|
|
|
} else
|
2017-05-15 21:31:01 +02:00
|
|
|
unk_ecom = 1;
|
2018-04-06 13:16:01 +02:00
|
|
|
} else if (type == ECOMMUNITY_ENCODE_REDIRECT_IP_NH) {
|
|
|
|
sub_type = *pnt++;
|
|
|
|
if (sub_type == ECOMMUNITY_REDIRECT_IP_NH) {
|
2019-11-22 01:01:55 +01:00
|
|
|
snprintf(encbuf, sizeof(encbuf),
|
|
|
|
"FS:redirect IP 0x%x", *(pnt + 5));
|
2018-04-06 13:16:01 +02:00
|
|
|
} else
|
|
|
|
unk_ecom = 1;
|
2018-05-17 09:30:28 +02:00
|
|
|
} else if (type == ECOMMUNITY_ENCODE_TRANS_EXP ||
|
|
|
|
type == ECOMMUNITY_EXTENDED_COMMUNITY_PART_2 ||
|
|
|
|
type == ECOMMUNITY_EXTENDED_COMMUNITY_PART_3) {
|
2018-01-15 19:17:02 +01:00
|
|
|
sub_type = *pnt++;
|
2019-10-17 16:08:16 +02:00
|
|
|
|
|
|
|
if (sub_type == ECOMMUNITY_ROUTE_TARGET) {
|
2019-10-17 16:11:57 +02:00
|
|
|
char buf[ECOMMUNITY_STRLEN];
|
2019-10-17 16:08:16 +02:00
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
ecommunity_rt_soo_str_internal(buf, sizeof(buf),
|
|
|
|
(const uint8_t *)pnt,
|
|
|
|
type &
|
|
|
|
~ECOMMUNITY_ENCODE_TRANS_EXP,
|
|
|
|
ECOMMUNITY_ROUTE_TARGET,
|
|
|
|
format,
|
|
|
|
ecom->unit_size);
|
|
|
|
snprintf(encbuf, sizeof(encbuf), "%s", buf);
|
2020-07-02 08:14:41 +02:00
|
|
|
} else if (sub_type ==
|
|
|
|
ECOMMUNITY_FLOWSPEC_REDIRECT_IPV6) {
|
2019-10-17 16:08:16 +02:00
|
|
|
char buf[64];
|
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
ecommunity_rt_soo_str_internal(buf, sizeof(buf),
|
|
|
|
(const uint8_t *)pnt,
|
|
|
|
type &
|
|
|
|
~ECOMMUNITY_ENCODE_TRANS_EXP,
|
|
|
|
ECOMMUNITY_ROUTE_TARGET,
|
|
|
|
ECOMMUNITY_FORMAT_DISPLAY,
|
|
|
|
ecom->unit_size);
|
2020-07-02 08:14:41 +02:00
|
|
|
snprintf(encbuf, sizeof(encbuf),
|
|
|
|
"FS:redirect VRF %s", buf);
|
2019-10-17 16:08:16 +02:00
|
|
|
} else if (sub_type == ECOMMUNITY_REDIRECT_VRF) {
|
|
|
|
char buf[16];
|
|
|
|
|
|
|
|
memset(buf, 0, sizeof(buf));
|
2020-07-02 08:14:41 +02:00
|
|
|
ecommunity_rt_soo_str(buf, sizeof(buf),
|
|
|
|
(const uint8_t *)pnt,
|
|
|
|
type &
|
|
|
|
~ECOMMUNITY_ENCODE_TRANS_EXP,
|
|
|
|
ECOMMUNITY_ROUTE_TARGET,
|
|
|
|
ECOMMUNITY_FORMAT_DISPLAY);
|
|
|
|
snprintf(encbuf, sizeof(encbuf),
|
|
|
|
"FS:redirect VRF %s", buf);
|
2019-11-22 01:01:55 +01:00
|
|
|
snprintf(encbuf, sizeof(encbuf),
|
|
|
|
"FS:redirect VRF %s", buf);
|
2018-05-17 09:30:28 +02:00
|
|
|
} else if (type != ECOMMUNITY_ENCODE_TRANS_EXP)
|
|
|
|
unk_ecom = 1;
|
|
|
|
else if (sub_type == ECOMMUNITY_TRAFFIC_ACTION) {
|
2018-01-15 19:17:02 +01:00
|
|
|
char action[64];
|
|
|
|
|
|
|
|
if (*(pnt+3) ==
|
|
|
|
1 << FLOWSPEC_TRAFFIC_ACTION_TERMINAL)
|
2019-11-22 01:01:55 +01:00
|
|
|
strlcpy(action, "terminate (apply)",
|
|
|
|
sizeof(action));
|
2018-01-15 19:17:02 +01:00
|
|
|
else
|
2019-11-22 01:01:55 +01:00
|
|
|
strlcpy(action, "eval stops",
|
|
|
|
sizeof(action));
|
|
|
|
|
2018-01-15 19:17:02 +01:00
|
|
|
if (*(pnt+3) ==
|
|
|
|
1 << FLOWSPEC_TRAFFIC_ACTION_SAMPLE)
|
2019-11-22 01:01:55 +01:00
|
|
|
strlcat(action, ", sample",
|
|
|
|
sizeof(action));
|
|
|
|
|
|
|
|
|
|
|
|
snprintf(encbuf, sizeof(encbuf), "FS:action %s",
|
|
|
|
action);
|
2018-01-15 19:17:02 +01:00
|
|
|
} else if (sub_type == ECOMMUNITY_TRAFFIC_RATE) {
|
|
|
|
union traffic_rate data;
|
|
|
|
|
|
|
|
data.rate_byte[3] = *(pnt+2);
|
|
|
|
data.rate_byte[2] = *(pnt+3);
|
|
|
|
data.rate_byte[1] = *(pnt+4);
|
|
|
|
data.rate_byte[0] = *(pnt+5);
|
2019-11-22 01:01:55 +01:00
|
|
|
snprintf(encbuf, sizeof(encbuf), "FS:rate %f",
|
|
|
|
data.rate_float);
|
2018-01-15 19:17:02 +01:00
|
|
|
} else if (sub_type == ECOMMUNITY_TRAFFIC_MARKING) {
|
2019-11-22 01:01:55 +01:00
|
|
|
snprintf(encbuf, sizeof(encbuf),
|
|
|
|
"FS:marking %u", *(pnt + 5));
|
2018-01-15 19:17:02 +01:00
|
|
|
} else
|
|
|
|
unk_ecom = 1;
|
2020-03-24 20:00:24 +01:00
|
|
|
} else if (type == ECOMMUNITY_ENCODE_AS_NON_TRANS) {
|
|
|
|
sub_type = *pnt++;
|
|
|
|
if (sub_type == ECOMMUNITY_LINK_BANDWIDTH)
|
2021-08-29 20:54:13 +02:00
|
|
|
ecommunity_lb_str(encbuf, sizeof(encbuf), pnt,
|
|
|
|
ecom->disable_ieee_floating);
|
2020-03-24 20:00:24 +01:00
|
|
|
else
|
|
|
|
unk_ecom = 1;
|
bgpd: Add Origin Validation State extended community
```
spine1-debian-11# sh ip bgp 100.100.100.101/32
BGP routing table entry for 100.100.100.101/32, version 21
Paths: (1 available, best #1, table default)
Not advertised to any peer
Local
fe80::ca5d:fd0d:cd8:1bb7 from eth3 (172.17.0.3)
(fe80::ca5d:fd0d:cd8:1bb7) (used)
Origin incomplete, metric 0, localpref 100, valid, internal, best (First path received)
Extended Community: OVS:invalid
Last update: Wed Aug 31 19:31:46 2022
spine1-debian-11# sh ip bgp 100.100.100.100/32
BGP routing table entry for 100.100.100.100/32, version 17
Paths: (1 available, best #1, table default)
Not advertised to any peer
Local
fe80::ca5d:fd0d:cd8:1bb7 from eth3 (172.17.0.3)
(fe80::ca5d:fd0d:cd8:1bb7) (used)
Origin incomplete, metric 0, localpref 100, valid, internal, best (First path received)
Extended Community: OVS:not-found
Last update: Wed Aug 31 19:31:46 2022
spine1-debian-11#
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-08-30 20:25:50 +02:00
|
|
|
} else if (type == ECOMMUNITY_ENCODE_OPAQUE_NON_TRANS) {
|
|
|
|
sub_type = *pnt++;
|
|
|
|
if (sub_type == ECOMMUNITY_ORIGIN_VALIDATION_STATE)
|
|
|
|
ecommunity_origin_validation_state_str(
|
|
|
|
encbuf, sizeof(encbuf), pnt);
|
|
|
|
else
|
|
|
|
unk_ecom = 1;
|
2018-05-17 09:30:28 +02:00
|
|
|
} else {
|
|
|
|
sub_type = *pnt++;
|
2017-05-15 21:31:01 +02:00
|
|
|
unk_ecom = 1;
|
2018-05-17 09:30:28 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-05-15 21:31:01 +02:00
|
|
|
if (unk_ecom)
|
2019-11-22 01:01:55 +01:00
|
|
|
snprintf(encbuf, sizeof(encbuf), "UNK:%d, %d", type,
|
|
|
|
sub_type);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-11-22 01:01:55 +01:00
|
|
|
int r = strlcat(str_buf, encbuf, str_size);
|
|
|
|
assert(r < str_size);
|
2011-09-26 11:17:05 +02:00
|
|
|
}
|
|
|
|
|
2016-01-12 19:42:00 +01:00
|
|
|
return str_buf;
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2004-05-20 12:20:02 +02:00
|
|
|
|
2022-08-19 11:50:29 +02:00
|
|
|
bool ecommunity_include(struct ecommunity *e1, struct ecommunity *e2)
|
|
|
|
{
|
|
|
|
uint32_t i, j;
|
|
|
|
|
|
|
|
if (!e1 || !e2)
|
|
|
|
return false;
|
|
|
|
for (i = 0; i < e1->size; ++i) {
|
|
|
|
for (j = 0; j < e2->size; ++j) {
|
|
|
|
if (!memcmp(e1->val + (i * e1->unit_size),
|
|
|
|
e2->val + (j * e2->unit_size),
|
|
|
|
e1->unit_size))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-03-20 10:57:54 +01:00
|
|
|
bool ecommunity_match(const struct ecommunity *ecom1,
|
|
|
|
const struct ecommunity *ecom2)
|
2004-05-20 12:20:02 +02:00
|
|
|
{
|
2021-01-17 22:08:03 +01:00
|
|
|
uint32_t i = 0;
|
|
|
|
uint32_t j = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-20 12:20:02 +02:00
|
|
|
if (ecom1 == NULL && ecom2 == NULL)
|
2020-03-20 10:57:54 +01:00
|
|
|
return true;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-20 12:20:02 +02:00
|
|
|
if (ecom1 == NULL || ecom2 == NULL)
|
2020-03-20 10:57:54 +01:00
|
|
|
return false;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-20 12:20:02 +02:00
|
|
|
if (ecom1->size < ecom2->size)
|
2020-03-20 10:57:54 +01:00
|
|
|
return false;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-20 12:20:02 +02:00
|
|
|
/* Every community on com2 needs to be on com1 for this to match */
|
|
|
|
while (i < ecom1->size && j < ecom2->size) {
|
2019-10-17 16:08:16 +02:00
|
|
|
if (memcmp(ecom1->val + i * ecom1->unit_size,
|
|
|
|
ecom2->val + j * ecom2->unit_size,
|
|
|
|
ecom2->unit_size)
|
2012-06-27 22:18:08 +02:00
|
|
|
== 0)
|
2004-05-20 12:20:02 +02:00
|
|
|
j++;
|
|
|
|
i++;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2004-05-20 12:20:02 +02:00
|
|
|
if (j == ecom2->size)
|
2020-03-20 10:57:54 +01:00
|
|
|
return true;
|
2004-05-20 12:20:02 +02:00
|
|
|
else
|
2020-03-20 10:57:54 +01:00
|
|
|
return false;
|
2004-05-20 12:20:02 +02:00
|
|
|
}
|
2016-10-06 15:46:45 +02:00
|
|
|
|
|
|
|
/* return first occurence of type */
|
|
|
|
extern struct ecommunity_val *ecommunity_lookup(const struct ecommunity *ecom,
|
|
|
|
uint8_t type, uint8_t subtype)
|
|
|
|
{
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t *p;
|
2021-01-17 22:08:03 +01:00
|
|
|
uint32_t c;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2016-10-06 15:46:45 +02:00
|
|
|
/* If the value already exists in the structure return 0. */
|
|
|
|
c = 0;
|
2019-10-17 16:08:16 +02:00
|
|
|
for (p = ecom->val; c < ecom->size; p += ecom->unit_size, c++) {
|
2016-10-06 15:46:45 +02:00
|
|
|
if (p == NULL) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (p[0] == type && p[1] == subtype)
|
|
|
|
return (struct ecommunity_val *)p;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* remove ext. community matching type and subtype
|
|
|
|
* return 1 on success ( removed ), 0 otherwise (not present)
|
|
|
|
*/
|
2020-03-24 21:50:20 +01:00
|
|
|
bool ecommunity_strip(struct ecommunity *ecom, uint8_t type,
|
|
|
|
uint8_t subtype)
|
2016-10-06 15:46:45 +02:00
|
|
|
{
|
2020-03-18 04:27:23 +01:00
|
|
|
uint8_t *p, *q, *new;
|
2021-01-17 22:08:03 +01:00
|
|
|
uint32_t c, found = 0;
|
2016-10-06 15:46:45 +02:00
|
|
|
/* When this is fist value, just add it. */
|
2020-03-20 10:57:54 +01:00
|
|
|
if (ecom == NULL || ecom->val == NULL)
|
|
|
|
return false;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-03-18 04:27:23 +01:00
|
|
|
/* Check if any existing ext community matches. */
|
|
|
|
/* Certain extended communities like the Route Target can be present
|
|
|
|
* multiple times, handle that.
|
|
|
|
*/
|
2016-10-06 15:46:45 +02:00
|
|
|
c = 0;
|
2019-10-17 16:08:16 +02:00
|
|
|
for (p = ecom->val; c < ecom->size; p += ecom->unit_size, c++) {
|
2020-03-18 04:27:23 +01:00
|
|
|
if (p[0] == type && p[1] == subtype)
|
|
|
|
found++;
|
2016-10-06 15:46:45 +02:00
|
|
|
}
|
2020-03-18 04:27:23 +01:00
|
|
|
/* If no matching ext community exists, return. */
|
2016-10-06 15:46:45 +02:00
|
|
|
if (found == 0)
|
2020-03-20 10:57:54 +01:00
|
|
|
return false;
|
2020-03-18 04:27:23 +01:00
|
|
|
|
|
|
|
/* Handle the case where everything needs to be stripped. */
|
|
|
|
if (found == ecom->size) {
|
|
|
|
XFREE(MTYPE_ECOMMUNITY_VAL, ecom->val);
|
|
|
|
ecom->size = 0;
|
2020-03-20 10:57:54 +01:00
|
|
|
return true;
|
2020-03-18 04:27:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Strip matching ext community(ies). */
|
|
|
|
new = XMALLOC(MTYPE_ECOMMUNITY_VAL,
|
2019-10-17 16:08:16 +02:00
|
|
|
(ecom->size - found) * ecom->unit_size);
|
2020-03-18 04:27:23 +01:00
|
|
|
q = new;
|
2019-10-17 16:08:16 +02:00
|
|
|
for (c = 0, p = ecom->val; c < ecom->size; c++, p += ecom->unit_size) {
|
2020-03-18 04:27:23 +01:00
|
|
|
if (!(p[0] == type && p[1] == subtype)) {
|
2019-10-17 16:08:16 +02:00
|
|
|
memcpy(q, p, ecom->unit_size);
|
|
|
|
q += ecom->unit_size;
|
2020-03-18 04:27:23 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
XFREE(MTYPE_ECOMMUNITY_VAL, ecom->val);
|
|
|
|
ecom->val = new;
|
|
|
|
ecom->size -= found;
|
2020-03-20 10:57:54 +01:00
|
|
|
return true;
|
2016-10-06 15:46:45 +02:00
|
|
|
}
|
2018-03-27 02:24:47 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Remove specified extended community value from extended community.
|
|
|
|
* Returns 1 if value was present (and hence, removed), 0 otherwise.
|
|
|
|
*/
|
2020-03-20 10:57:54 +01:00
|
|
|
bool ecommunity_del_val(struct ecommunity *ecom, struct ecommunity_val *eval)
|
2018-03-27 02:24:47 +02:00
|
|
|
{
|
2018-04-11 15:34:40 +02:00
|
|
|
uint8_t *p;
|
2021-01-17 22:08:03 +01:00
|
|
|
uint32_t c, found = 0;
|
2018-03-27 02:24:47 +02:00
|
|
|
|
|
|
|
/* Make sure specified value exists. */
|
|
|
|
if (ecom == NULL || ecom->val == NULL)
|
2020-03-20 10:57:54 +01:00
|
|
|
return false;
|
2018-03-27 02:24:47 +02:00
|
|
|
c = 0;
|
2019-10-17 16:08:16 +02:00
|
|
|
for (p = ecom->val; c < ecom->size; p += ecom->unit_size, c++) {
|
|
|
|
if (!memcmp(p, eval->val, ecom->unit_size)) {
|
2018-03-27 02:24:47 +02:00
|
|
|
found = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (found == 0)
|
2020-03-20 10:57:54 +01:00
|
|
|
return false;
|
2018-03-27 02:24:47 +02:00
|
|
|
|
|
|
|
/* Delete the selected value */
|
|
|
|
ecom->size--;
|
2021-04-01 07:39:57 +02:00
|
|
|
if (ecom->size) {
|
|
|
|
p = XMALLOC(MTYPE_ECOMMUNITY_VAL, ecom->size * ecom->unit_size);
|
|
|
|
if (c != 0)
|
|
|
|
memcpy(p, ecom->val, c * ecom->unit_size);
|
|
|
|
if ((ecom->size - c) != 0)
|
|
|
|
memcpy(p + (c)*ecom->unit_size,
|
|
|
|
ecom->val + (c + 1) * ecom->unit_size,
|
|
|
|
(ecom->size - c) * ecom->unit_size);
|
|
|
|
XFREE(MTYPE_ECOMMUNITY_VAL, ecom->val);
|
|
|
|
ecom->val = p;
|
|
|
|
} else
|
2022-09-21 10:45:41 +02:00
|
|
|
XFREE(MTYPE_ECOMMUNITY_VAL, ecom->val);
|
2021-04-01 07:39:57 +02:00
|
|
|
|
2020-03-20 10:57:54 +01:00
|
|
|
return true;
|
2018-03-27 02:24:47 +02:00
|
|
|
}
|
2018-03-08 19:13:44 +01:00
|
|
|
|
|
|
|
int ecommunity_fill_pbr_action(struct ecommunity_val *ecom_eval,
|
2019-10-16 10:05:36 +02:00
|
|
|
struct bgp_pbr_entry_action *api,
|
|
|
|
afi_t afi)
|
2018-03-08 19:13:44 +01:00
|
|
|
{
|
|
|
|
if (ecom_eval->val[1] == ECOMMUNITY_TRAFFIC_RATE) {
|
|
|
|
api->action = ACTION_TRAFFICRATE;
|
|
|
|
api->u.r.rate_info[3] = ecom_eval->val[4];
|
|
|
|
api->u.r.rate_info[2] = ecom_eval->val[5];
|
|
|
|
api->u.r.rate_info[1] = ecom_eval->val[6];
|
|
|
|
api->u.r.rate_info[0] = ecom_eval->val[7];
|
|
|
|
} else if (ecom_eval->val[1] == ECOMMUNITY_TRAFFIC_ACTION) {
|
|
|
|
api->action = ACTION_TRAFFIC_ACTION;
|
|
|
|
/* else distribute code is set by default */
|
|
|
|
if (ecom_eval->val[5] & (1 << FLOWSPEC_TRAFFIC_ACTION_TERMINAL))
|
|
|
|
api->u.za.filter |= TRAFFIC_ACTION_TERMINATE;
|
|
|
|
else
|
|
|
|
api->u.za.filter |= TRAFFIC_ACTION_DISTRIBUTE;
|
|
|
|
if (ecom_eval->val[5] == 1 << FLOWSPEC_TRAFFIC_ACTION_SAMPLE)
|
|
|
|
api->u.za.filter |= TRAFFIC_ACTION_SAMPLE;
|
|
|
|
|
|
|
|
} else if (ecom_eval->val[1] == ECOMMUNITY_TRAFFIC_MARKING) {
|
|
|
|
api->action = ACTION_MARKING;
|
|
|
|
api->u.marking_dscp = ecom_eval->val[7];
|
|
|
|
} else if (ecom_eval->val[1] == ECOMMUNITY_REDIRECT_VRF) {
|
|
|
|
/* must use external function */
|
|
|
|
return 0;
|
2019-10-16 10:05:36 +02:00
|
|
|
} else if (ecom_eval->val[1] == ECOMMUNITY_REDIRECT_IP_NH &&
|
|
|
|
afi == AFI_IP) {
|
2018-03-08 19:13:44 +01:00
|
|
|
/* see draft-ietf-idr-flowspec-redirect-ip-02
|
|
|
|
* Q1: how come a ext. community can host ipv6 address
|
|
|
|
* Q2 : from cisco documentation:
|
|
|
|
* Announces the reachability of one or more flowspec NLRI.
|
|
|
|
* When a BGP speaker receives an UPDATE message with the
|
|
|
|
* redirect-to-IP extended community, it is expected to
|
|
|
|
* create a traffic filtering rule for every flow-spec
|
|
|
|
* NLRI in the message that has this path as its best
|
|
|
|
* path. The filter entry matches the IP packets
|
|
|
|
* described in the NLRI field and redirects them or
|
|
|
|
* copies them towards the IPv4 or IPv6 address specified
|
|
|
|
* in the 'Network Address of Next- Hop'
|
|
|
|
* field of the associated MP_REACH_NLRI.
|
|
|
|
*/
|
|
|
|
struct ecommunity_ip *ip_ecom = (struct ecommunity_ip *)
|
|
|
|
ecom_eval + 2;
|
|
|
|
|
|
|
|
api->u.zr.redirect_ip_v4 = ip_ecom->ip;
|
|
|
|
} else
|
|
|
|
return -1;
|
|
|
|
return 0;
|
|
|
|
}
|
2019-02-06 15:31:37 +01:00
|
|
|
|
|
|
|
static struct ecommunity *bgp_aggr_ecommunity_lookup(
|
|
|
|
struct bgp_aggregate *aggregate,
|
|
|
|
struct ecommunity *ecommunity)
|
|
|
|
{
|
|
|
|
return hash_lookup(aggregate->ecommunity_hash, ecommunity);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *bgp_aggr_ecommunty_hash_alloc(void *p)
|
|
|
|
{
|
|
|
|
struct ecommunity *ref = (struct ecommunity *)p;
|
|
|
|
struct ecommunity *ecommunity = NULL;
|
|
|
|
|
|
|
|
ecommunity = ecommunity_dup(ref);
|
|
|
|
return ecommunity;
|
|
|
|
}
|
|
|
|
|
2020-02-27 02:03:34 +01:00
|
|
|
static void bgp_aggr_ecommunity_prepare(struct hash_bucket *hb, void *arg)
|
2019-02-06 15:31:37 +01:00
|
|
|
{
|
|
|
|
struct ecommunity *hb_ecommunity = hb->data;
|
|
|
|
struct ecommunity **aggr_ecommunity = arg;
|
|
|
|
|
2019-08-19 09:50:15 +02:00
|
|
|
if (*aggr_ecommunity)
|
|
|
|
*aggr_ecommunity = ecommunity_merge(*aggr_ecommunity,
|
|
|
|
hb_ecommunity);
|
|
|
|
else
|
2019-02-06 15:31:37 +01:00
|
|
|
*aggr_ecommunity = ecommunity_dup(hb_ecommunity);
|
|
|
|
}
|
|
|
|
|
|
|
|
void bgp_aggr_ecommunity_remove(void *arg)
|
|
|
|
{
|
|
|
|
struct ecommunity *ecommunity = arg;
|
|
|
|
|
|
|
|
ecommunity_free(&ecommunity);
|
|
|
|
}
|
|
|
|
|
|
|
|
void bgp_compute_aggregate_ecommunity(struct bgp_aggregate *aggregate,
|
|
|
|
struct ecommunity *ecommunity)
|
2019-08-19 09:50:15 +02:00
|
|
|
{
|
|
|
|
bgp_compute_aggregate_ecommunity_hash(aggregate, ecommunity);
|
|
|
|
bgp_compute_aggregate_ecommunity_val(aggregate);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void bgp_compute_aggregate_ecommunity_hash(struct bgp_aggregate *aggregate,
|
|
|
|
struct ecommunity *ecommunity)
|
2019-02-06 15:31:37 +01:00
|
|
|
{
|
|
|
|
struct ecommunity *aggr_ecommunity = NULL;
|
|
|
|
|
|
|
|
if ((aggregate == NULL) || (ecommunity == NULL))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Create hash if not already created.
|
|
|
|
*/
|
|
|
|
if (aggregate->ecommunity_hash == NULL)
|
|
|
|
aggregate->ecommunity_hash = hash_create(
|
|
|
|
ecommunity_hash_make, ecommunity_cmp,
|
|
|
|
"BGP Aggregator ecommunity hash");
|
|
|
|
|
|
|
|
aggr_ecommunity = bgp_aggr_ecommunity_lookup(aggregate, ecommunity);
|
|
|
|
if (aggr_ecommunity == NULL) {
|
|
|
|
/* Insert ecommunity into hash.
|
|
|
|
*/
|
|
|
|
aggr_ecommunity = hash_get(aggregate->ecommunity_hash,
|
|
|
|
ecommunity,
|
|
|
|
bgp_aggr_ecommunty_hash_alloc);
|
2019-08-19 09:50:15 +02:00
|
|
|
}
|
2019-02-06 15:31:37 +01:00
|
|
|
|
2019-08-19 09:50:15 +02:00
|
|
|
/* Increment reference counter.
|
|
|
|
*/
|
|
|
|
aggr_ecommunity->refcnt++;
|
|
|
|
}
|
2019-02-06 15:31:37 +01:00
|
|
|
|
2019-08-19 09:50:15 +02:00
|
|
|
void bgp_compute_aggregate_ecommunity_val(struct bgp_aggregate *aggregate)
|
|
|
|
{
|
|
|
|
struct ecommunity *ecommerge = NULL;
|
|
|
|
|
|
|
|
if (aggregate == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Re-compute aggregate's ecommunity.
|
|
|
|
*/
|
|
|
|
if (aggregate->ecommunity)
|
|
|
|
ecommunity_free(&aggregate->ecommunity);
|
|
|
|
if (aggregate->ecommunity_hash
|
|
|
|
&& aggregate->ecommunity_hash->count) {
|
2019-02-06 15:31:37 +01:00
|
|
|
hash_iterate(aggregate->ecommunity_hash,
|
|
|
|
bgp_aggr_ecommunity_prepare,
|
|
|
|
&aggregate->ecommunity);
|
2019-08-19 09:50:15 +02:00
|
|
|
ecommerge = aggregate->ecommunity;
|
|
|
|
aggregate->ecommunity = ecommunity_uniq_sort(ecommerge);
|
|
|
|
if (ecommerge)
|
|
|
|
ecommunity_free(&ecommerge);
|
2019-02-06 15:31:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void bgp_remove_ecommunity_from_aggregate(struct bgp_aggregate *aggregate,
|
|
|
|
struct ecommunity *ecommunity)
|
|
|
|
{
|
|
|
|
struct ecommunity *aggr_ecommunity = NULL;
|
|
|
|
struct ecommunity *ret_ecomm = NULL;
|
|
|
|
|
2019-08-19 09:50:15 +02:00
|
|
|
if ((!aggregate)
|
|
|
|
|| (!aggregate->ecommunity_hash)
|
|
|
|
|| (!ecommunity))
|
2019-02-06 15:31:37 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* Look-up the ecommunity in the hash.
|
|
|
|
*/
|
|
|
|
aggr_ecommunity = bgp_aggr_ecommunity_lookup(aggregate, ecommunity);
|
|
|
|
if (aggr_ecommunity) {
|
|
|
|
aggr_ecommunity->refcnt--;
|
|
|
|
|
|
|
|
if (aggr_ecommunity->refcnt == 0) {
|
|
|
|
ret_ecomm = hash_release(aggregate->ecommunity_hash,
|
|
|
|
aggr_ecommunity);
|
|
|
|
ecommunity_free(&ret_ecomm);
|
2019-08-19 09:50:15 +02:00
|
|
|
bgp_compute_aggregate_ecommunity_val(aggregate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void bgp_remove_ecomm_from_aggregate_hash(struct bgp_aggregate *aggregate,
|
|
|
|
struct ecommunity *ecommunity)
|
|
|
|
{
|
|
|
|
|
|
|
|
struct ecommunity *aggr_ecommunity = NULL;
|
|
|
|
struct ecommunity *ret_ecomm = NULL;
|
2019-02-06 15:31:37 +01:00
|
|
|
|
2019-08-19 09:50:15 +02:00
|
|
|
if ((!aggregate)
|
|
|
|
|| (!aggregate->ecommunity_hash)
|
|
|
|
|| (!ecommunity))
|
|
|
|
return;
|
2019-02-06 15:31:37 +01:00
|
|
|
|
2019-08-19 09:50:15 +02:00
|
|
|
/* Look-up the ecommunity in the hash.
|
|
|
|
*/
|
|
|
|
aggr_ecommunity = bgp_aggr_ecommunity_lookup(aggregate, ecommunity);
|
|
|
|
if (aggr_ecommunity) {
|
|
|
|
aggr_ecommunity->refcnt--;
|
|
|
|
|
|
|
|
if (aggr_ecommunity->refcnt == 0) {
|
|
|
|
ret_ecomm = hash_release(aggregate->ecommunity_hash,
|
|
|
|
aggr_ecommunity);
|
|
|
|
ecommunity_free(&ret_ecomm);
|
2019-02-06 15:31:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-03-24 20:17:19 +01:00
|
|
|
|
bgpd: Add Origin Validation State extended community
```
spine1-debian-11# sh ip bgp 100.100.100.101/32
BGP routing table entry for 100.100.100.101/32, version 21
Paths: (1 available, best #1, table default)
Not advertised to any peer
Local
fe80::ca5d:fd0d:cd8:1bb7 from eth3 (172.17.0.3)
(fe80::ca5d:fd0d:cd8:1bb7) (used)
Origin incomplete, metric 0, localpref 100, valid, internal, best (First path received)
Extended Community: OVS:invalid
Last update: Wed Aug 31 19:31:46 2022
spine1-debian-11# sh ip bgp 100.100.100.100/32
BGP routing table entry for 100.100.100.100/32, version 17
Paths: (1 available, best #1, table default)
Not advertised to any peer
Local
fe80::ca5d:fd0d:cd8:1bb7 from eth3 (172.17.0.3)
(fe80::ca5d:fd0d:cd8:1bb7) (used)
Origin incomplete, metric 0, localpref 100, valid, internal, best (First path received)
Extended Community: OVS:not-found
Last update: Wed Aug 31 19:31:46 2022
spine1-debian-11#
```
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-08-30 20:25:50 +02:00
|
|
|
struct ecommunity *
|
|
|
|
ecommunity_add_origin_validation_state(enum rpki_states rpki_state,
|
|
|
|
struct ecommunity *old)
|
|
|
|
{
|
|
|
|
struct ecommunity *new = NULL;
|
|
|
|
struct ecommunity ovs_ecomm = {0};
|
|
|
|
struct ecommunity_val ovs_eval;
|
|
|
|
|
|
|
|
encode_origin_validation_state(rpki_state, &ovs_eval);
|
|
|
|
|
|
|
|
if (old) {
|
|
|
|
new = ecommunity_dup(old);
|
|
|
|
ecommunity_add_val(new, &ovs_eval, true, true);
|
|
|
|
if (!old->refcnt)
|
|
|
|
ecommunity_free(&old);
|
|
|
|
} else {
|
|
|
|
ovs_ecomm.size = 1;
|
|
|
|
ovs_ecomm.unit_size = ECOMMUNITY_SIZE;
|
|
|
|
ovs_ecomm.val = (uint8_t *)&ovs_eval.val;
|
|
|
|
new = ecommunity_dup(&ovs_ecomm);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|
|
|
|
|
2020-03-24 20:17:19 +01:00
|
|
|
/*
|
|
|
|
* return the BGP link bandwidth extended community, if present;
|
|
|
|
* the actual bandwidth is returned via param
|
|
|
|
*/
|
|
|
|
const uint8_t *ecommunity_linkbw_present(struct ecommunity *ecom, uint32_t *bw)
|
|
|
|
{
|
|
|
|
const uint8_t *eval;
|
2021-01-17 22:08:03 +01:00
|
|
|
uint32_t i;
|
2020-03-24 20:17:19 +01:00
|
|
|
|
|
|
|
if (bw)
|
|
|
|
*bw = 0;
|
|
|
|
|
|
|
|
if (!ecom || !ecom->size)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for (i = 0; i < ecom->size; i++) {
|
|
|
|
const uint8_t *pnt;
|
|
|
|
uint8_t type, sub_type;
|
|
|
|
uint32_t bwval;
|
|
|
|
|
|
|
|
eval = pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
|
|
|
|
type = *pnt++;
|
|
|
|
sub_type = *pnt++;
|
|
|
|
|
|
|
|
if ((type == ECOMMUNITY_ENCODE_AS ||
|
|
|
|
type == ECOMMUNITY_ENCODE_AS_NON_TRANS) &&
|
|
|
|
sub_type == ECOMMUNITY_LINK_BANDWIDTH) {
|
|
|
|
pnt += 2; /* bandwidth is encoded as AS:val */
|
|
|
|
pnt = ptr_get_be32(pnt, &bwval);
|
|
|
|
(void)pnt; /* consume value */
|
|
|
|
if (bw)
|
2021-08-29 20:54:13 +02:00
|
|
|
*bw = ecom->disable_ieee_floating
|
|
|
|
? bwval
|
|
|
|
: ieee_float_uint32_to_uint32(
|
|
|
|
bwval);
|
2020-03-24 20:17:19 +01:00
|
|
|
return eval;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2020-03-24 22:25:56 +01:00
|
|
|
|
|
|
|
|
2021-08-29 20:54:13 +02:00
|
|
|
struct ecommunity *ecommunity_replace_linkbw(as_t as, struct ecommunity *ecom,
|
|
|
|
uint64_t cum_bw,
|
|
|
|
bool disable_ieee_floating)
|
2020-03-24 22:25:56 +01:00
|
|
|
{
|
|
|
|
struct ecommunity *new;
|
|
|
|
struct ecommunity_val lb_eval;
|
|
|
|
const uint8_t *eval;
|
|
|
|
uint8_t type;
|
|
|
|
uint32_t cur_bw;
|
|
|
|
|
|
|
|
/* Nothing to replace if link-bandwidth doesn't exist or
|
|
|
|
* is non-transitive - just return existing extcommunity.
|
|
|
|
*/
|
|
|
|
new = ecom;
|
|
|
|
if (!ecom || !ecom->size)
|
|
|
|
return new;
|
|
|
|
|
|
|
|
eval = ecommunity_linkbw_present(ecom, &cur_bw);
|
|
|
|
if (!eval)
|
|
|
|
return new;
|
|
|
|
|
|
|
|
type = *eval;
|
|
|
|
if (type & ECOMMUNITY_FLAG_NON_TRANSITIVE)
|
|
|
|
return new;
|
|
|
|
|
|
|
|
/* Transitive link-bandwidth exists, replace with the passed
|
|
|
|
* (cumulative) bandwidth value. We need to create a new
|
|
|
|
* extcommunity for this - refer to AS-Path replace function
|
|
|
|
* for reference.
|
|
|
|
*/
|
|
|
|
if (cum_bw > 0xFFFFFFFF)
|
|
|
|
cum_bw = 0xFFFFFFFF;
|
2021-08-29 20:54:13 +02:00
|
|
|
encode_lb_extcomm(as > BGP_AS_MAX ? BGP_AS_TRANS : as, cum_bw, false,
|
|
|
|
&lb_eval, disable_ieee_floating);
|
2020-03-24 22:25:56 +01:00
|
|
|
new = ecommunity_dup(ecom);
|
|
|
|
ecommunity_add_val(new, &lb_eval, true, true);
|
|
|
|
|
|
|
|
return new;
|
|
|
|
}
|