mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 22:57:45 +00:00
bgpd: aspath list format binds on as-notation format
Each BGP prefix may have an as-path list attached. A forged string is stored in the BGP attribute and shows the as-path list output. Before this commit, the as-path list output was expressed as a list of AS values in plain format. Now, if a given BGP instance uses a specific asnotation, then the output is changed: new output: router bgp 1.1 asnotation dot ! address-family ipv4 unicast network 10.200.0.0/24 route-map rmap network 10.201.0.0/24 route-map rmap redistribute connected route-map rmap exit-address-family exit ! route-map rmap permit 1 set as-path prepend 1.1 5433.55 264564564 exit ubuntu2004# do show bgp ipv4 BGP table version is 2, local router ID is 10.0.2.15, vrf id 0 Default local pref 100, local AS 1.1 Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, i internal, r RIB-failure, S Stale, R Removed Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self Origin codes: i - IGP, e - EGP, ? - incomplete RPKI validation codes: V valid, I invalid, N Not found Network Next Hop Metric LocPrf Weight Path *> 4.4.4.4/32 0.0.0.0 0 32768 1.1 5433.55 4036.61268 ? *> 10.0.2.0/24 0.0.0.0 0 32768 1.1 5433.55 4036.61268 ? 10.200.0.0/24 0.0.0.0 0 32768 1.1 5433.55 4036.61268 i 10.201.0.0/24 0.0.0.0 0 32768 1.1 5433.55 4036.61268 i The changes include: - the aspath structure has a new field: asnotation type The ashash list will differentiate 2 aspaths using a different asnotation. - 3 new printf extensions display the as number in the wished format: pASP, pASD, pASE for plain, dot, or dot+ format (extended). Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
parent
e55b088399
commit
17571c4ae7
@ -302,9 +302,13 @@ static struct assegment *assegment_normalise(struct assegment *head)
|
||||
return head;
|
||||
}
|
||||
|
||||
static struct aspath *aspath_new(void)
|
||||
static struct aspath *aspath_new(enum asnotation_mode asnotation)
|
||||
{
|
||||
return XCALLOC(MTYPE_AS_PATH, sizeof(struct aspath));
|
||||
struct aspath *as;
|
||||
|
||||
as = XCALLOC(MTYPE_AS_PATH, sizeof(struct aspath));
|
||||
as->asnotation = asnotation;
|
||||
return as;
|
||||
}
|
||||
|
||||
/* Free AS path structure. */
|
||||
@ -552,8 +556,10 @@ static void aspath_make_str_count(struct aspath *as, bool make_json)
|
||||
*
|
||||
* This was changed to 10 after the well-known BGP assertion, which
|
||||
* had hit some parts of the Internet in May of 2009.
|
||||
* plain format : '4294967295 ' : 10 + 1
|
||||
* astod format : '65535.65535 ': 11 + 1
|
||||
*/
|
||||
#define ASN_STR_LEN (10 + 1)
|
||||
#define ASN_STR_LEN (11 + 1)
|
||||
str_size = MAX(assegment_count_asns(seg, 0) * ASN_STR_LEN + 2 + 1,
|
||||
ASPATH_STR_DEFAULT_LEN);
|
||||
str_buf = XMALLOC(MTYPE_AS_STR, str_size);
|
||||
@ -584,7 +590,7 @@ static void aspath_make_str_count(struct aspath *as, bool make_json)
|
||||
|
||||
/* We might need to increase str_buf, particularly if path has
|
||||
* differing segments types, our initial guesstimate above will
|
||||
* have been wrong. Need 10 chars for ASN, a separator each and
|
||||
* have been wrong. Need 11 chars for ASN, a separator each and
|
||||
* potentially two segment delimiters, plus a space between each
|
||||
* segment and trailing zero.
|
||||
*
|
||||
@ -610,12 +616,11 @@ static void aspath_make_str_count(struct aspath *as, bool make_json)
|
||||
/* write out the ASNs, with their separators, bar the last one*/
|
||||
for (i = 0; i < seg->length; i++) {
|
||||
if (make_json)
|
||||
json_object_array_add(
|
||||
jseg_list,
|
||||
json_object_new_int64(seg->as[i]));
|
||||
|
||||
len += snprintf(str_buf + len, str_size - len, "%u",
|
||||
seg->as[i]);
|
||||
asn_asn2json_array(jseg_list, seg->as[i],
|
||||
as->asnotation);
|
||||
len += snprintfrr(str_buf + len, str_size - len,
|
||||
ASN_FORMAT(as->asnotation),
|
||||
&seg->as[i]);
|
||||
|
||||
if (i < (seg->length - 1))
|
||||
len += snprintf(str_buf + len, str_size - len,
|
||||
@ -706,6 +711,7 @@ struct aspath *aspath_dup(struct aspath *aspath)
|
||||
|
||||
new->str = XMALLOC(MTYPE_AS_STR, buflen);
|
||||
new->str_len = aspath->str_len;
|
||||
new->asnotation = aspath->asnotation;
|
||||
|
||||
/* copy the string data */
|
||||
if (aspath->str_len > 0)
|
||||
@ -733,6 +739,7 @@ static void *aspath_hash_alloc(void *arg)
|
||||
new->str = aspath->str;
|
||||
new->str_len = aspath->str_len;
|
||||
new->json = aspath->json;
|
||||
new->asnotation = aspath->asnotation;
|
||||
|
||||
return new;
|
||||
}
|
||||
@ -840,7 +847,8 @@ static int assegments_parse(struct stream *s, size_t length,
|
||||
|
||||
On error NULL is returned.
|
||||
*/
|
||||
struct aspath *aspath_parse(struct stream *s, size_t length, int use32bit)
|
||||
struct aspath *aspath_parse(struct stream *s, size_t length, int use32bit,
|
||||
enum asnotation_mode asnotation)
|
||||
{
|
||||
struct aspath as;
|
||||
struct aspath *find;
|
||||
@ -855,6 +863,7 @@ struct aspath *aspath_parse(struct stream *s, size_t length, int use32bit)
|
||||
return NULL;
|
||||
|
||||
memset(&as, 0, sizeof(as));
|
||||
as.asnotation = asnotation;
|
||||
if (assegments_parse(s, length, &as.segments, use32bit) < 0)
|
||||
return NULL;
|
||||
|
||||
@ -1072,7 +1081,7 @@ struct aspath *aspath_aggregate(struct aspath *as1, struct aspath *as2)
|
||||
seg = assegment_append_asns(seg, seg1->as, match);
|
||||
|
||||
if (!aspath) {
|
||||
aspath = aspath_new();
|
||||
aspath = aspath_new(as1->asnotation);
|
||||
aspath->segments = seg;
|
||||
} else
|
||||
prevseg->next = seg;
|
||||
@ -1092,7 +1101,7 @@ struct aspath *aspath_aggregate(struct aspath *as1, struct aspath *as2)
|
||||
}
|
||||
|
||||
if (!aspath)
|
||||
aspath = aspath_new();
|
||||
aspath = aspath_new(as1->asnotation);
|
||||
|
||||
/* Make as-set using rest of all information. */
|
||||
from = match;
|
||||
@ -1536,7 +1545,7 @@ struct aspath *aspath_filter_exclude(struct aspath *source,
|
||||
struct assegment *srcseg, *exclseg, *lastseg;
|
||||
struct aspath *newpath;
|
||||
|
||||
newpath = aspath_new();
|
||||
newpath = aspath_new(source->asnotation);
|
||||
lastseg = NULL;
|
||||
|
||||
for (srcseg = source->segments; srcseg; srcseg = srcseg->next) {
|
||||
@ -1766,7 +1775,7 @@ struct aspath *aspath_reconcile_as4(struct aspath *aspath,
|
||||
newseg = assegment_append_asns(newseg, seg->as, cpasns);
|
||||
|
||||
if (!newpath) {
|
||||
newpath = aspath_new();
|
||||
newpath = aspath_new(aspath->asnotation);
|
||||
newpath->segments = newseg;
|
||||
} else
|
||||
prevseg->next = newseg;
|
||||
@ -1895,16 +1904,16 @@ static void aspath_segment_add(struct aspath *as, int type)
|
||||
as->segments = new;
|
||||
}
|
||||
|
||||
struct aspath *aspath_empty(void)
|
||||
struct aspath *aspath_empty(enum asnotation_mode asnotation)
|
||||
{
|
||||
return aspath_parse(NULL, 0, 1); /* 32Bit ;-) */
|
||||
return aspath_parse(NULL, 0, 1, asnotation); /* 32Bit ;-) */
|
||||
}
|
||||
|
||||
struct aspath *aspath_empty_get(void)
|
||||
{
|
||||
struct aspath *aspath;
|
||||
|
||||
aspath = aspath_new();
|
||||
aspath = aspath_new(bgp_get_asnotation(NULL));
|
||||
aspath_make_str_count(aspath, false);
|
||||
return aspath;
|
||||
}
|
||||
@ -1988,7 +1997,8 @@ static const char *aspath_gettoken(const char *buf, enum as_token *token,
|
||||
return p;
|
||||
}
|
||||
|
||||
struct aspath *aspath_str2aspath(const char *str)
|
||||
struct aspath *aspath_str2aspath(const char *str,
|
||||
enum asnotation_mode asnotation)
|
||||
{
|
||||
enum as_token token = as_token_unknown;
|
||||
unsigned short as_type;
|
||||
@ -1996,7 +2006,7 @@ struct aspath *aspath_str2aspath(const char *str)
|
||||
struct aspath *aspath;
|
||||
int needtype;
|
||||
|
||||
aspath = aspath_new();
|
||||
aspath = aspath_new(asnotation);
|
||||
|
||||
/* We start default type as AS_SEQUENCE. */
|
||||
as_type = AS_SEQUENCE;
|
||||
@ -2070,6 +2080,10 @@ bool aspath_cmp(const void *arg1, const void *arg2)
|
||||
const struct assegment *seg1 = ((const struct aspath *)arg1)->segments;
|
||||
const struct assegment *seg2 = ((const struct aspath *)arg2)->segments;
|
||||
|
||||
if (((const struct aspath *)arg1)->asnotation !=
|
||||
((const struct aspath *)arg2)->asnotation)
|
||||
return false;
|
||||
|
||||
while (seg1 || seg2) {
|
||||
int i;
|
||||
if ((!seg1 && seg2) || (seg1 && !seg2))
|
||||
|
@ -72,6 +72,9 @@ struct aspath {
|
||||
and AS path regular expression match. */
|
||||
char *str;
|
||||
unsigned short str_len;
|
||||
|
||||
/* AS notation used by string expression of AS path */
|
||||
enum asnotation_mode asnotation;
|
||||
};
|
||||
|
||||
#define ASPATH_STR_DEFAULT_LEN 32
|
||||
@ -80,7 +83,9 @@ struct aspath {
|
||||
extern void aspath_init(void);
|
||||
extern void aspath_finish(void);
|
||||
extern struct aspath *aspath_parse(struct stream *s, size_t length,
|
||||
int use32bit);
|
||||
int use32bit,
|
||||
enum asnotation_mode asnotation);
|
||||
|
||||
extern struct aspath *aspath_dup(struct aspath *aspath);
|
||||
extern struct aspath *aspath_aggregate(struct aspath *as1, struct aspath *as2);
|
||||
extern struct aspath *aspath_prepend(struct aspath *as1, struct aspath *as2);
|
||||
@ -96,9 +101,10 @@ extern bool aspath_cmp_left(const struct aspath *aspath1,
|
||||
extern bool aspath_cmp_left_confed(const struct aspath *as1,
|
||||
const struct aspath *as2);
|
||||
extern struct aspath *aspath_delete_confed_seq(struct aspath *aspath);
|
||||
extern struct aspath *aspath_empty(void);
|
||||
extern struct aspath *aspath_empty(enum asnotation_mode asnotation);
|
||||
extern struct aspath *aspath_empty_get(void);
|
||||
extern struct aspath *aspath_str2aspath(const char *str);
|
||||
extern struct aspath *aspath_str2aspath(const char *str,
|
||||
enum asnotation_mode asnotation);
|
||||
extern void aspath_str_update(struct aspath *as, bool make_json);
|
||||
extern void aspath_free(struct aspath *aspath);
|
||||
extern struct aspath *aspath_intern(struct aspath *aspath);
|
||||
|
@ -1069,7 +1069,7 @@ struct attr *bgp_attr_default_set(struct attr *attr, struct bgp *bgp,
|
||||
|
||||
attr->origin = origin;
|
||||
attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_ORIGIN);
|
||||
attr->aspath = aspath_empty();
|
||||
attr->aspath = aspath_empty(bgp->asnotation);
|
||||
attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
|
||||
attr->weight = BGP_ATTR_DEFAULT_WEIGHT;
|
||||
attr->tag = 0;
|
||||
@ -1107,7 +1107,7 @@ struct attr *bgp_attr_aggregate_intern(
|
||||
if (aspath)
|
||||
attr.aspath = aspath_intern(aspath);
|
||||
else
|
||||
attr.aspath = aspath_empty();
|
||||
attr.aspath = aspath_empty(bgp->asnotation);
|
||||
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_AS_PATH);
|
||||
|
||||
/* Next hop attribute. */
|
||||
@ -1605,15 +1605,19 @@ static int bgp_attr_aspath(struct bgp_attr_parser_args *args)
|
||||
struct attr *const attr = args->attr;
|
||||
struct peer *const peer = args->peer;
|
||||
const bgp_size_t length = args->length;
|
||||
enum asnotation_mode asnotation;
|
||||
|
||||
asnotation = bgp_get_asnotation(
|
||||
args->peer && args->peer->bgp ? args->peer->bgp : NULL);
|
||||
/*
|
||||
* peer with AS4 => will get 4Byte ASnums
|
||||
* otherwise, will get 16 Bit
|
||||
*/
|
||||
attr->aspath = aspath_parse(
|
||||
peer->curr, length,
|
||||
CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV)
|
||||
&& CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV));
|
||||
attr->aspath =
|
||||
aspath_parse(peer->curr, length,
|
||||
CHECK_FLAG(peer->cap, PEER_CAP_AS4_RCV) &&
|
||||
CHECK_FLAG(peer->cap, PEER_CAP_AS4_ADV),
|
||||
asnotation);
|
||||
|
||||
/* In case of IBGP, length will be zero. */
|
||||
if (!attr->aspath) {
|
||||
@ -1705,8 +1709,11 @@ static int bgp_attr_as4_path(struct bgp_attr_parser_args *args,
|
||||
struct peer *const peer = args->peer;
|
||||
struct attr *const attr = args->attr;
|
||||
const bgp_size_t length = args->length;
|
||||
enum asnotation_mode asnotation;
|
||||
|
||||
*as4_path = aspath_parse(peer->curr, length, 1);
|
||||
asnotation = bgp_get_asnotation(peer->bgp);
|
||||
|
||||
*as4_path = aspath_parse(peer->curr, length, 1, asnotation);
|
||||
|
||||
/* In case of IBGP, length will be zero. */
|
||||
if (!*as4_path) {
|
||||
|
@ -101,7 +101,8 @@ static void attr_parse(struct stream *s, uint16_t len)
|
||||
case BGP_ATTR_AS_PATH: {
|
||||
struct aspath *aspath;
|
||||
|
||||
aspath = aspath_parse(s, length, 1);
|
||||
aspath = aspath_parse(s, length, 1,
|
||||
bgp_get_asnotation(NULL));
|
||||
printf("ASPATH: %s\n", aspath->str);
|
||||
aspath_free(aspath);
|
||||
} break;
|
||||
|
@ -7246,7 +7246,7 @@ static bool aggr_suppress_map_test(struct bgp *bgp,
|
||||
return false;
|
||||
|
||||
/* Call route map matching and return result. */
|
||||
attr.aspath = aspath_empty();
|
||||
attr.aspath = aspath_empty(bgp->asnotation);
|
||||
rmap_path.peer = bgp->peer_self;
|
||||
rmap_path.attr = &attr;
|
||||
|
||||
@ -7340,9 +7340,12 @@ static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
|
||||
struct lcommunity *lcomm)
|
||||
{
|
||||
static struct aspath *ae = NULL;
|
||||
enum asnotation_mode asnotation;
|
||||
|
||||
asnotation = bgp_get_asnotation(NULL);
|
||||
|
||||
if (!ae)
|
||||
ae = aspath_empty();
|
||||
ae = aspath_empty(asnotation);
|
||||
|
||||
if (!pi)
|
||||
return false;
|
||||
|
@ -228,7 +228,7 @@ static void *route_aspath_compile(const char *arg)
|
||||
{
|
||||
struct aspath *aspath;
|
||||
|
||||
aspath = aspath_str2aspath(arg);
|
||||
aspath = aspath_str2aspath(arg, bgp_get_asnotation(NULL));
|
||||
if (!aspath)
|
||||
return NULL;
|
||||
return aspath;
|
||||
|
@ -163,7 +163,8 @@ void lua_decode_attr(lua_State *L, int idx, struct attr *attr)
|
||||
attr->nh_ifindex = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, idx, "aspath");
|
||||
attr->aspath = aspath_str2aspath(lua_tostring(L, -1));
|
||||
attr->aspath = aspath_str2aspath(lua_tostring(L, -1),
|
||||
bgp_get_asnotation(NULL));
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, idx, "localpref");
|
||||
attr->local_pref = lua_tointeger(L, -1);
|
||||
|
@ -2060,6 +2060,13 @@ const char *bgp_get_name_by_role(uint8_t role)
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
enum asnotation_mode bgp_get_asnotation(struct bgp *bgp)
|
||||
{
|
||||
if (!bgp)
|
||||
return ASNOTATION_PLAIN;
|
||||
return bgp->asnotation;
|
||||
}
|
||||
|
||||
static void peer_group2peer_config_copy_af(struct peer_group *group,
|
||||
struct peer *peer, afi_t afi,
|
||||
safi_t safi)
|
||||
|
@ -2350,6 +2350,7 @@ extern void peer_tx_shutdown_message_unset(struct peer *);
|
||||
|
||||
extern void bgp_route_map_update_timer(struct thread *thread);
|
||||
extern const char *bgp_get_name_by_role(uint8_t role);
|
||||
extern enum asnotation_mode bgp_get_asnotation(struct bgp *bgp);
|
||||
|
||||
extern void bgp_route_map_terminate(void);
|
||||
|
||||
|
64
lib/asn.c
64
lib/asn.c
@ -118,6 +118,15 @@ static bool asn_str2asn_internal(const char *asstring, as_t *asn,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void asn_asn2asdot(as_t asn, char *asstring, size_t len)
|
||||
{
|
||||
uint16_t low, high;
|
||||
|
||||
high = (asn >> 16) & 0xffff;
|
||||
low = asn & 0xffff;
|
||||
snprintf(asstring, len, "%hu.%hu", high, low);
|
||||
}
|
||||
|
||||
bool asn_str2asn(const char *asstring, as_t *asn)
|
||||
{
|
||||
return asn_str2asn_internal(asstring, asn, NULL, NULL, NULL);
|
||||
@ -173,3 +182,58 @@ const char *asn_mode2str(enum asnotation_mode asnotation)
|
||||
return lookup_msg(asnotation_mode_msg, asnotation,
|
||||
"Unrecognized AS notation mode");
|
||||
}
|
||||
|
||||
void asn_asn2json_array(json_object *jseg_list, as_t asn,
|
||||
enum asnotation_mode asnotation)
|
||||
{
|
||||
static char as_str[ASN_STRING_MAX_SIZE];
|
||||
|
||||
if ((asnotation == ASNOTATION_PLAIN) ||
|
||||
((asnotation == ASNOTATION_DOT) && asn < UINT16_MAX))
|
||||
json_object_array_add(jseg_list,
|
||||
json_object_new_int64(asn));
|
||||
else {
|
||||
asn_asn2asdot(asn, as_str, sizeof(as_str));
|
||||
json_array_string_add(jseg_list, as_str);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t printfrr_asnotation(struct fbuf *buf, struct printfrr_eargs *ea,
|
||||
const void *ptr,
|
||||
enum asnotation_mode asnotation)
|
||||
{
|
||||
/* for alignemnt up to 33 chars - %33pASD for instance - */
|
||||
char as_str[ASN_STRING_MAX_SIZE*3];
|
||||
const as_t *asn;
|
||||
|
||||
if (!ptr)
|
||||
return bputs(buf, "(null)");
|
||||
asn = ptr;
|
||||
if ((asnotation == ASNOTATION_PLAIN) ||
|
||||
((asnotation == ASNOTATION_DOT) && *asn < UINT16_MAX))
|
||||
snprintf(as_str, sizeof(as_str), "%u", *asn);
|
||||
else
|
||||
asn_asn2asdot(*asn, as_str, sizeof(as_str));
|
||||
return bputs(buf, as_str);
|
||||
}
|
||||
|
||||
printfrr_ext_autoreg_p("ASP", printfrr_asplain);
|
||||
static ssize_t printfrr_asplain(struct fbuf *buf, struct printfrr_eargs *ea,
|
||||
const void *ptr)
|
||||
{
|
||||
return printfrr_asnotation(buf, ea, ptr, ASNOTATION_PLAIN);
|
||||
}
|
||||
|
||||
printfrr_ext_autoreg_p("ASD", printfrr_asdot);
|
||||
static ssize_t printfrr_asdot(struct fbuf *buf, struct printfrr_eargs *ea,
|
||||
const void *ptr)
|
||||
{
|
||||
return printfrr_asnotation(buf, ea, ptr, ASNOTATION_DOT);
|
||||
}
|
||||
|
||||
printfrr_ext_autoreg_p("ASE", printfrr_asdotplus);
|
||||
static ssize_t printfrr_asdotplus(struct fbuf *buf, struct printfrr_eargs *ea,
|
||||
const void *ptr)
|
||||
{
|
||||
return printfrr_asnotation(buf, ea, ptr, ASNOTATION_DOTPLUS);
|
||||
}
|
||||
|
15
lib/asn.h
15
lib/asn.h
@ -24,6 +24,7 @@
|
||||
|
||||
#include "zebra.h"
|
||||
#include "command_match.h"
|
||||
#include "json.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -48,6 +49,20 @@ extern enum match_type asn_str2asn_match(const char *str);
|
||||
extern bool asn_str2asn_notation(const char *asstring, as_t *asn,
|
||||
enum asnotation_mode *asnotation);
|
||||
extern const char *asn_mode2str(enum asnotation_mode asnotation);
|
||||
void asn_asn2json_array(json_object *jseg_list, as_t asn,
|
||||
enum asnotation_mode asnotation);
|
||||
/* display AS in appropriate format */
|
||||
#ifdef _FRR_ATTRIBUTE_PRINTFRR
|
||||
#pragma FRR printfrr_ext "%pASP" (as_t *)
|
||||
#pragma FRR printfrr_ext "%pASD" (as_t *)
|
||||
#pragma FRR printfrr_ext "%pASE" (as_t *)
|
||||
#endif
|
||||
|
||||
#define ASN_FORMAT(mode) \
|
||||
((mode == ASNOTATION_DOT) ? "%pASD" : \
|
||||
((mode == ASNOTATION_DOTPLUS) ? "%pASE" : \
|
||||
"%pASP"))
|
||||
|
||||
/* for test */
|
||||
extern void asn_relax_as_zero(bool relax);
|
||||
|
||||
|
@ -880,7 +880,7 @@ static struct aspath *make_aspath(const uint8_t *data, size_t len, int use32bit)
|
||||
s = stream_new(len);
|
||||
stream_put(s, data, len);
|
||||
}
|
||||
as = aspath_parse(s, len, use32bit);
|
||||
as = aspath_parse(s, len, use32bit, ASNOTATION_PLAIN);
|
||||
|
||||
if (s)
|
||||
stream_free(s);
|
||||
@ -925,7 +925,7 @@ static int validate(struct aspath *as, const struct test_spec *sp)
|
||||
as4 = make_aspath(STREAM_DATA(s), bytes4, 1);
|
||||
|
||||
asn_relax_as_zero(true);
|
||||
asstr = aspath_str2aspath(sp->shouldbe);
|
||||
asstr = aspath_str2aspath(sp->shouldbe, ASNOTATION_PLAIN);
|
||||
asn_relax_as_zero(false);
|
||||
|
||||
asconfeddel = aspath_delete_confed_seq(aspath_dup(asinout));
|
||||
@ -1103,7 +1103,7 @@ static void empty_prepend_test(struct test_segment *t)
|
||||
printf("empty prepend %s: %s\n", t->name, t->desc);
|
||||
|
||||
asp1 = make_aspath(t->asdata, t->len, 0);
|
||||
asp2 = aspath_empty();
|
||||
asp2 = aspath_empty(ASNOTATION_PLAIN);
|
||||
|
||||
ascratch = aspath_dup(asp2);
|
||||
aspath_unintern(&asp2);
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "lib/memory.h"
|
||||
#include "lib/prefix.h"
|
||||
#include "lib/nexthop.h"
|
||||
#include "lib/asn.h"
|
||||
|
||||
static int errors;
|
||||
|
||||
@ -158,6 +159,7 @@ int main(int argc, char **argv)
|
||||
struct in_addr ip;
|
||||
char *p;
|
||||
char buf[256];
|
||||
as_t asn;
|
||||
|
||||
printcmp("%d %u %d %u", 123, 123, -456, -456);
|
||||
printcmp("%lld %llu %lld %llu", 123LL, 123LL, -456LL, -456LL);
|
||||
@ -405,6 +407,13 @@ int main(int argc, char **argv)
|
||||
printchk("-00:09", "%pTSIm", &ts);
|
||||
printchk("--:--", "%pTVImx", &tv);
|
||||
printchk("--:--", "%pTTImx", &tt);
|
||||
/* ASN checks */
|
||||
asn = 65536;
|
||||
printchk("1.0", "%pASD", &asn);
|
||||
asn = 65400;
|
||||
printchk("65400", "%pASP", &asn);
|
||||
printchk("0.65400", "%pASE", &asn);
|
||||
printchk("65400", "%pASD", &asn);
|
||||
|
||||
return !!errors;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user