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
#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;
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;
}
/* 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);
* 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; }
/**
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);
{
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))
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:
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
}
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" };
}
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;
}
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)
{
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 */
}
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;
{
*buf++ = ':';
*buf++ = ' ';
- d->format(a, buf);
+ d->format(a, buf, buflen);
return GA_FULL;
}
return GA_NAME;
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 *);
}
static int
-ospf_get_attr(eattr * a, byte * buf)
+ospf_get_attr(eattr * a, byte * buf, int buflen UNUSED)
{
switch (a->id)
{
}
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;