Changed initialization of protocol list -- now we call proto_build() instead
of calling the protocols manually. Implemented printing of dynamic attributes in `show route all'. Each protocol can now register its own attribute class (protocol->attr_class, set to EAP_xxx) and also a callback for naming and formatting of attributes. The callback can return one of the following results: GA_UNKNOWN Attribute not recognized. GA_NAME Attribute name recognized and put to the buffer, generic code should format the value. GA_FULL Both attribute name and value put to the buffer. Please update protocols generating dynamic attributes to provide the attr_class and formatting hook.
This commit is contained in:
parent
f880924990
commit
3991d84e8f
8 changed files with 99 additions and 18 deletions
2
TODO
2
TODO
|
@ -24,6 +24,8 @@ Documentation
|
||||||
Globals
|
Globals
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
- right usage of DBG vs. debug
|
- right usage of DBG vs. debug
|
||||||
|
- kill preconfigs?
|
||||||
|
- check dump functions
|
||||||
- cleanup debugging calls
|
- cleanup debugging calls
|
||||||
- logging and tracing; use appropriate log levels
|
- logging and tracing; use appropriate log levels
|
||||||
- check incoming packets and log errors!!
|
- check incoming packets and log errors!!
|
||||||
|
|
|
@ -35,6 +35,7 @@ Reply codes of BIRD command-line interface
|
||||||
1009 Static route list
|
1009 Static route list
|
||||||
1010 Symbol list
|
1010 Symbol list
|
||||||
1011 Uptime
|
1011 Uptime
|
||||||
|
1012 Route extended attribute list
|
||||||
|
|
||||||
8000 Reply too long
|
8000 Reply too long
|
||||||
8001 Route not found
|
8001 Route not found
|
||||||
|
|
25
nest/proto.c
25
nest/proto.c
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
static pool *proto_pool;
|
static pool *proto_pool;
|
||||||
|
|
||||||
list protocol_list;
|
static list protocol_list;
|
||||||
static list proto_list;
|
static list proto_list;
|
||||||
|
|
||||||
#define WALK_PROTO_LIST(p) do { \
|
#define WALK_PROTO_LIST(p) do { \
|
||||||
|
@ -343,6 +343,17 @@ protos_dump_all(void)
|
||||||
debug(" flushing %s\n", p->name);
|
debug(" flushing %s\n", p->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
proto_build(struct protocol *p)
|
||||||
|
{
|
||||||
|
add_tail(&protocol_list, &p->n);
|
||||||
|
if (p->attr_class)
|
||||||
|
{
|
||||||
|
ASSERT(!attr_class_to_protocol[p->attr_class]);
|
||||||
|
attr_class_to_protocol[p->attr_class] = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
protos_build(void)
|
protos_build(void)
|
||||||
{
|
{
|
||||||
|
@ -352,21 +363,21 @@ protos_build(void)
|
||||||
init_list(&inactive_proto_list);
|
init_list(&inactive_proto_list);
|
||||||
init_list(&initial_proto_list);
|
init_list(&initial_proto_list);
|
||||||
init_list(&flush_proto_list);
|
init_list(&flush_proto_list);
|
||||||
add_tail(&protocol_list, &proto_device.n);
|
proto_build(&proto_device);
|
||||||
#ifdef CONFIG_RIP
|
#ifdef CONFIG_RIP
|
||||||
add_tail(&protocol_list, &proto_rip.n);
|
proto_build(&proto_rip);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_STATIC
|
#ifdef CONFIG_STATIC
|
||||||
add_tail(&protocol_list, &proto_static.n);
|
proto_build(&proto_static);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_OSPF
|
#ifdef CONFIG_OSPF
|
||||||
add_tail(&protocol_list, &proto_ospf.n);
|
proto_build(&proto_ospf);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_PIPE
|
#ifdef CONFIG_PIPE
|
||||||
add_tail(&protocol_list, &proto_pipe.n);
|
proto_build(&proto_pipe);
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_BGP
|
#ifdef CONFIG_BGP
|
||||||
add_tail(&protocol_list, &proto_bgp.n);
|
proto_build(&proto_bgp);
|
||||||
#endif
|
#endif
|
||||||
proto_pool = rp_new(&root_pool, "Protocols");
|
proto_pool = rp_new(&root_pool, "Protocols");
|
||||||
proto_flush_event = ev_new(proto_pool);
|
proto_flush_event = ev_new(proto_pool);
|
||||||
|
|
|
@ -24,6 +24,7 @@ struct config;
|
||||||
struct proto;
|
struct proto;
|
||||||
struct event;
|
struct event;
|
||||||
struct ea_list;
|
struct ea_list;
|
||||||
|
struct eattr;
|
||||||
struct symbol;
|
struct symbol;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -35,6 +36,7 @@ struct protocol {
|
||||||
char *name;
|
char *name;
|
||||||
char *template; /* Template for automatic generation of names */
|
char *template; /* Template for automatic generation of names */
|
||||||
int name_counter; /* Counter for automatic name generation */
|
int name_counter; /* Counter for automatic name generation */
|
||||||
|
int attr_class; /* Attribute class known to this protocol */
|
||||||
|
|
||||||
void (*preconfig)(struct protocol *, struct config *); /* Just before configuring */
|
void (*preconfig)(struct protocol *, struct config *); /* Just before configuring */
|
||||||
void (*postconfig)(struct proto_config *); /* After configuring each instance */
|
void (*postconfig)(struct proto_config *); /* After configuring each instance */
|
||||||
|
@ -46,16 +48,19 @@ struct protocol {
|
||||||
int (*shutdown)(struct proto *); /* Stop the instance */
|
int (*shutdown)(struct proto *); /* Stop the instance */
|
||||||
void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
|
void (*get_status)(struct proto *, byte *buf); /* Get instance status (for `show protocols' command) */
|
||||||
void (*get_route_info)(struct rte *, byte *buf); /* Get route information (for `show route' command) */
|
void (*get_route_info)(struct rte *, byte *buf); /* Get route information (for `show route' command) */
|
||||||
void (*show_route_data)(struct rte *); /* Print verbose route information (`show route' again) */
|
int (*get_attr)(struct eattr *, byte *buf); /* ASCIIfy dynamic attribute (returns GA_*) */
|
||||||
};
|
};
|
||||||
|
|
||||||
void protos_build(void);
|
void protos_build(void);
|
||||||
|
void proto_build(struct protocol *);
|
||||||
void protos_preconfig(struct config *);
|
void protos_preconfig(struct config *);
|
||||||
void protos_postconfig(struct config *);
|
void protos_postconfig(struct config *);
|
||||||
void protos_commit(struct config *new, struct config *old, int force_restart);
|
void protos_commit(struct config *new, struct config *old, int force_restart);
|
||||||
void protos_dump_all(void);
|
void protos_dump_all(void);
|
||||||
|
|
||||||
extern list protocol_list;
|
#define GA_UNKNOWN 0 /* Attribute not recognized */
|
||||||
|
#define GA_NAME 1 /* Result = name */
|
||||||
|
#define GA_FULL 2 /* Result = both name and value */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Known protocols
|
* Known protocols
|
||||||
|
@ -146,7 +151,6 @@ struct proto {
|
||||||
/* Hic sunt protocol-specific data */
|
/* Hic sunt protocol-specific data */
|
||||||
};
|
};
|
||||||
|
|
||||||
void proto_build(struct proto_config *);
|
|
||||||
void *proto_new(struct proto_config *, unsigned size);
|
void *proto_new(struct proto_config *, unsigned size);
|
||||||
void *proto_config_new(struct protocol *, unsigned size);
|
void *proto_config_new(struct protocol *, unsigned size);
|
||||||
|
|
||||||
|
|
|
@ -283,6 +283,7 @@ typedef struct eattr {
|
||||||
#define EAP_GENERIC 0 /* Generic attributes */
|
#define EAP_GENERIC 0 /* Generic attributes */
|
||||||
#define EAP_BGP 1 /* BGP attributes */
|
#define EAP_BGP 1 /* BGP attributes */
|
||||||
#define EAP_RIP 2 /* RIP */
|
#define EAP_RIP 2 /* RIP */
|
||||||
|
#define EAP_MAX 3
|
||||||
|
|
||||||
#define EA_CODE(proto,id) (((proto) << 8) | (id))
|
#define EA_CODE(proto,id) (((proto) << 8) | (id))
|
||||||
#define EA_PROTO(ea) ((ea) >> 8)
|
#define EA_PROTO(ea) ((ea) >> 8)
|
||||||
|
@ -336,6 +337,8 @@ void rta_dump_all(void);
|
||||||
static inline eattr * rta_find(rta *a, unsigned ea) { return ea_find(a->eattrs, ea); }
|
static inline eattr * rta_find(rta *a, unsigned ea) { return ea_find(a->eattrs, ea); }
|
||||||
void rta_show(struct cli *, rta *);
|
void rta_show(struct cli *, rta *);
|
||||||
|
|
||||||
|
extern struct protocol *attr_class_to_protocol[EAP_MAX];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default protocol preferences
|
* Default protocol preferences
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
static slab *rta_slab;
|
static slab *rta_slab;
|
||||||
static pool *rta_pool;
|
static pool *rta_pool;
|
||||||
|
|
||||||
|
struct protocol *attr_class_to_protocol[EAP_MAX];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extended Attributes
|
* Extended Attributes
|
||||||
*/
|
*/
|
||||||
|
@ -233,6 +235,60 @@ ea_list_copy(ea_list *o)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ea_format(eattr *e, byte *buf)
|
||||||
|
{
|
||||||
|
struct protocol *p;
|
||||||
|
int status = GA_UNKNOWN;
|
||||||
|
unsigned int i, l;
|
||||||
|
struct adata *ad = (e->type & EAF_EMBEDDED) ? NULL : e->u.ptr;
|
||||||
|
|
||||||
|
if (p = attr_class_to_protocol[EA_PROTO(e->id)])
|
||||||
|
{
|
||||||
|
buf += bsprintf(buf, "%s.", p->name);
|
||||||
|
if (p->get_attr)
|
||||||
|
status = p->get_attr(e, buf);
|
||||||
|
buf += strlen(buf);
|
||||||
|
}
|
||||||
|
else if (EA_PROTO(e->id))
|
||||||
|
buf += bsprintf(buf, "%02x.", EA_PROTO(e->id));
|
||||||
|
if (status < GA_NAME)
|
||||||
|
buf += bsprintf(buf, "%02x", EA_ID(e->id));
|
||||||
|
if (status < GA_FULL)
|
||||||
|
{
|
||||||
|
*buf++ = ':';
|
||||||
|
*buf++ = ' ';
|
||||||
|
switch (e->type & EAF_TYPE_MASK)
|
||||||
|
{
|
||||||
|
case EAF_TYPE_INT:
|
||||||
|
bsprintf(buf, "%d", e->u.data);
|
||||||
|
break;
|
||||||
|
case EAF_TYPE_OPAQUE:
|
||||||
|
l = (ad->length < 16) ? ad->length : 16;
|
||||||
|
for(i=0; i<l; i++)
|
||||||
|
{
|
||||||
|
buf += bsprintf(buf, "%02x", ad->data[i]);
|
||||||
|
if (i < l)
|
||||||
|
*buf++ = ' ';
|
||||||
|
}
|
||||||
|
if (l < ad->length)
|
||||||
|
strcpy(buf, "...");
|
||||||
|
break;
|
||||||
|
case EAF_TYPE_IP_ADDRESS:
|
||||||
|
bsprintf(buf, "%I", *(ip_addr *) ad->data);
|
||||||
|
break;
|
||||||
|
case EAF_TYPE_ROUTER_ID:
|
||||||
|
bsprintf(buf, "%08x", e->u.data); /* FIXME: Better printing of router ID's */
|
||||||
|
break;
|
||||||
|
case EAF_TYPE_AS_PATH: /* FIXME */
|
||||||
|
case EAF_TYPE_INT_SET: /* FIXME */
|
||||||
|
case EAF_TYPE_UNDEF:
|
||||||
|
default:
|
||||||
|
bsprintf(buf, "<type %02x>", e->type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ea_dump(ea_list *e)
|
ea_dump(ea_list *e)
|
||||||
{
|
{
|
||||||
|
@ -484,9 +540,17 @@ rta_show(struct cli *c, rta *a)
|
||||||
"RIP", "RIP-ext", "OSPF", "OSPF-ext", "OSPF-IA", "OSPF-boundary",
|
"RIP", "RIP-ext", "OSPF", "OSPF-ext", "OSPF-IA", "OSPF-boundary",
|
||||||
"BGP" };
|
"BGP" };
|
||||||
static char *cast_names[] = { "unicast", "broadcast", "multicast", "anycast" };
|
static char *cast_names[] = { "unicast", "broadcast", "multicast", "anycast" };
|
||||||
|
ea_list *eal;
|
||||||
|
int i;
|
||||||
|
byte buf[256];
|
||||||
|
|
||||||
cli_printf(c, -1008, "\tType: %s %s %s", src_names[a->source], cast_names[a->cast], ip_scope_text(a->scope));
|
cli_printf(c, -1008, "\tType: %s %s %s", src_names[a->source], cast_names[a->cast], ip_scope_text(a->scope));
|
||||||
/* FIXME: Here we probably should print the dynamic attributes... */
|
for(eal=a->eattrs; eal; eal=eal->next)
|
||||||
|
for(i=0; i<eal->count; i++)
|
||||||
|
{
|
||||||
|
ea_format(&eal->attrs[i], buf);
|
||||||
|
cli_printf(c, -1012, "\t%s", buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -675,11 +675,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d)
|
||||||
bsprintf(info, " (%d)", e->pref);
|
bsprintf(info, " (%d)", e->pref);
|
||||||
cli_printf(c, -1007, "%-18s %s [%s %s%s]%s", ia, via, a->proto->name, tm, from, info);
|
cli_printf(c, -1007, "%-18s %s [%s %s%s]%s", ia, via, a->proto->name, tm, from, info);
|
||||||
if (d->verbose)
|
if (d->verbose)
|
||||||
{
|
|
||||||
rta_show(c, a);
|
rta_show(c, a);
|
||||||
if (a->proto->proto->show_route_data)
|
|
||||||
a->proto->proto->show_route_data(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -400,8 +400,8 @@ main(int argc, char **argv)
|
||||||
if_init();
|
if_init();
|
||||||
|
|
||||||
protos_build();
|
protos_build();
|
||||||
add_tail(&protocol_list, &proto_unix_kernel.n);
|
proto_build(&proto_unix_kernel);
|
||||||
add_tail(&protocol_list, &proto_unix_iface.n);
|
proto_build(&proto_unix_iface);
|
||||||
|
|
||||||
read_config();
|
read_config();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue