diff --git a/filter/filter.c b/filter/filter.c index 7893d9ae..6f85c064 100644 --- a/filter/filter.c +++ b/filter/filter.c @@ -247,7 +247,7 @@ val_print(struct f_val v) case T_SET: tree_print( v.val.t ); PRINTF( "\n" ); break; case T_ENUM: PRINTF( "(enum %x)%d", v.type, v.val.i ); break; case T_PATH: as_path_format(v.val.ad, buf2, 1020); PRINTF( "(path %s)", buf2 ); break; - case T_CLIST: int_set_format(v.val.ad, buf2, 1020); PRINTF( "(clist %s)", buf2 ); break; + case T_CLIST: int_set_format(v.val.ad, 1, buf2, 1020); PRINTF( "(clist %s)", buf2 ); break; case T_PATH_MASK: pm_format(v.val.path_mask, buf2, 1020); PRINTF( "(pathmask %s)", buf2 ); break; default: PRINTF( "[unknown type %x]", v.type ); #undef PRINTF diff --git a/nest/a-set.c b/nest/a-set.c index 69c090b7..505c0e51 100644 --- a/nest/a-set.c +++ b/nest/a-set.c @@ -14,7 +14,7 @@ #include "lib/string.h" void -int_set_format(struct adata *set, byte *buf, unsigned int size) +int_set_format(struct adata *set, int way, byte *buf, unsigned int size) { u32 *z = (u32 *) set->data; int l = set->length / 4; @@ -30,7 +30,14 @@ int_set_format(struct adata *set, byte *buf, unsigned int size) strcpy(buf, "..."); return; } - buf += bsprintf(buf, "(%d,%d)", *z >> 16, *z & 0xffff); + + if (way) + buf += bsprintf(buf, "(%d,%d)", *z >> 16, *z & 0xffff); + else + buf += bsprintf(buf, "%d.%d.%d.%d", + (*z >> 24) & 0xff, (*z >> 16) & 0xff, + (*z >> 8) & 0xff, *z & 0xff); + z++; sp = 0; } diff --git a/nest/attrs.h b/nest/attrs.h index fee2c2c8..6f0bc1f5 100644 --- a/nest/attrs.h +++ b/nest/attrs.h @@ -43,7 +43,7 @@ int as_path_match(struct adata *path, struct f_path_mask *mask); /* a-set.c */ -void int_set_format(struct adata *set, byte *buf, unsigned int size); +void int_set_format(struct adata *set, int way, byte *buf, unsigned int size); struct adata *int_set_add(struct linpool *pool, struct adata *list, u32 val); int int_set_contains(struct adata *list, u32 val); struct adata *int_set_del(struct linpool *pool, struct adata *list, u32 val); diff --git a/nest/proto-hooks.c b/nest/proto-hooks.c index 4035fdd7..82df5cb7 100644 --- a/nest/proto-hooks.c +++ b/nest/proto-hooks.c @@ -146,7 +146,7 @@ void get_route_info(rte *e, byte *buf, ea_list *attrs) * or doing the whole conversion (used in case the value requires extra * care; return %GA_FULL). */ -int get_attr(eattr *a, byte *buf) +int get_attr(eattr *a, byte *buf, int buflen) { DUMMY; } /** diff --git a/nest/protocol.h b/nest/protocol.h index 64ea4661..d681ae68 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -48,7 +48,7 @@ struct protocol { int (*shutdown)(struct proto *); /* Stop the instance */ void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */ void (*get_route_info)(struct rte *, byte *buf, struct ea_list *attrs); /* Get route information (for `show route' command) */ - int (*get_attr)(struct eattr *, byte *buf); /* ASCIIfy dynamic attribute (returns GA_*) */ + int (*get_attr)(struct eattr *, byte *buf, int buflen); /* ASCIIfy dynamic attribute (returns GA_*) */ }; void protos_build(void); diff --git a/nest/rt-attr.c b/nest/rt-attr.c index cbece881..e79cba1f 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -386,7 +386,7 @@ ea_format(eattr *e, byte *buf) { buf += bsprintf(buf, "%s.", p->name); if (p->get_attr) - status = p->get_attr(e, buf); + status = p->get_attr(e, buf, end - buf); buf += strlen(buf); } else if (EA_PROTO(e->id)) @@ -429,7 +429,7 @@ ea_format(eattr *e, byte *buf) as_path_format(ad, buf, end - buf); break; case EAF_TYPE_INT_SET: - int_set_format(ad, buf, end - buf); + int_set_format(ad, 1, buf, end - buf); break; case EAF_TYPE_UNDEF: default: diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c index 811d52eb..c13f9056 100644 --- a/proto/bgp/attrs.c +++ b/proto/bgp/attrs.c @@ -35,7 +35,7 @@ struct attr_desc { int type; int allow_in_ebgp; int (*validate)(struct bgp_proto *p, byte *attr, int len); - void (*format)(eattr *ea, byte *buf); + void (*format)(eattr *ea, byte *buf, int buflen); }; static int @@ -47,7 +47,7 @@ bgp_check_origin(struct bgp_proto *p UNUSED, byte *a UNUSED, int len) } static void -bgp_format_origin(eattr *a, byte *buf) +bgp_format_origin(eattr *a, byte *buf, int buflen) { static char *bgp_origin_names[] = { "IGP", "EGP", "Incomplete" }; @@ -104,7 +104,7 @@ bgp_check_next_hop(struct bgp_proto *p UNUSED, byte *a, int len) } static int -bgp_check_aggregator(struct bgp_proto *p, UNUSED byte *a, int len) +bgp_check_aggregator(struct bgp_proto *p, byte *a UNUSED, int len) { int exp_len = p->as4_session ? 8 : 6; @@ -112,11 +112,17 @@ bgp_check_aggregator(struct bgp_proto *p, UNUSED byte *a, int len) } static int -bgp_check_cluster_list(struct bgp_proto *p UNUSED, UNUSED byte *a, int len) +bgp_check_cluster_list(struct bgp_proto *p UNUSED, byte *a UNUSED, int len) { return ((len % 4) == 0) ? 0 : 5; } +static void +bgp_format_cluster_list(eattr *a, byte *buf, int buflen UNUSED) +{ + int_set_format(a->u.ptr, 0, buf, buflen); +} + static int bgp_check_reach_nlri(struct bgp_proto *p UNUSED, byte *a UNUSED, int len UNUSED) { @@ -156,10 +162,10 @@ static struct attr_desc bgp_attr_table[] = { bgp_check_aggregator, NULL }, { "community", -1, BAF_OPTIONAL | BAF_TRANSITIVE, EAF_TYPE_INT_SET, 1, /* BA_COMMUNITY */ NULL, NULL }, - { "originator_id", 4, BAF_OPTIONAL, EAF_TYPE_INT, 0, /* BA_ORIGINATOR_ID */ + { "originator_id", 4, BAF_OPTIONAL, EAF_TYPE_ROUTER_ID, 0, /* BA_ORIGINATOR_ID */ NULL, NULL }, { "cluster_list", -1, BAF_OPTIONAL, EAF_TYPE_INT_SET, 0, /* BA_CLUSTER_LIST */ - bgp_check_cluster_list, NULL }, + bgp_check_cluster_list, bgp_format_cluster_list }, { NULL, }, /* BA_DPA */ { NULL, }, /* BA_ADVERTISER */ { NULL, }, /* BA_RCID_PATH */ @@ -1306,7 +1312,7 @@ err: } int -bgp_get_attr(eattr *a, byte *buf) +bgp_get_attr(eattr *a, byte *buf, int buflen) { unsigned int i = EA_ID(a->id); struct attr_desc *d; @@ -1319,7 +1325,7 @@ bgp_get_attr(eattr *a, byte *buf) { *buf++ = ':'; *buf++ = ' '; - d->format(a, buf); + d->format(a, buf, buflen); return GA_FULL; } return GA_NAME; diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h index ea64584d..aaa2c4ac 100644 --- a/proto/bgp/bgp.h +++ b/proto/bgp/bgp.h @@ -132,7 +132,7 @@ void bgp_close_conn(struct bgp_conn *c); void bgp_attach_attr(struct ea_list **to, struct linpool *pool, unsigned attr, uintptr_t val); byte *bgp_attach_attr_wa(struct ea_list **to, struct linpool *pool, unsigned attr, unsigned len); struct rta *bgp_decode_attrs(struct bgp_conn *conn, byte *a, unsigned int len, struct linpool *pool, int mandatory); -int bgp_get_attr(struct eattr *e, byte *buf); +int bgp_get_attr(struct eattr *e, byte *buf, int buflen); int bgp_rte_better(struct rte *, struct rte *); void bgp_rt_notify(struct proto *, struct network *, struct rte *, struct rte *, struct ea_list *); int bgp_import_control(struct proto *, struct rte **, struct ea_list **, struct linpool *); diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c index cd510bc8..1eae3762 100644 --- a/proto/ospf/ospf.c +++ b/proto/ospf/ospf.c @@ -529,7 +529,7 @@ ospf_get_route_info(rte * rte, byte * buf, ea_list * attrs UNUSED) } static int -ospf_get_attr(eattr * a, byte * buf) +ospf_get_attr(eattr * a, byte * buf, int buflen UNUSED) { switch (a->id) { diff --git a/proto/rip/rip.c b/proto/rip/rip.c index 6c7bd369..b5a4cc36 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -972,7 +972,7 @@ rip_init_config(struct rip_proto_config *c) } static int -rip_get_attr(eattr *a, byte *buf) +rip_get_attr(eattr *a, byte *buf, int buflen UNUSED) { switch (a->id) { case EA_RIP_METRIC: buf += bsprintf( buf, "metric: %d", a->u.data ); return GA_FULL;