mirror of
https://gitlab.nic.cz/labs/bird.git
synced 2024-12-22 09:41:54 +00:00
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
2
TODO
2
TODO
@ -24,6 +24,8 @@ Documentation
|
||||
Globals
|
||||
~~~~~~~
|
||||
- right usage of DBG vs. debug
|
||||
- kill preconfigs?
|
||||
- check dump functions
|
||||
- cleanup debugging calls
|
||||
- logging and tracing; use appropriate log levels
|
||||
- check incoming packets and log errors!!
|
||||
|
@ -35,6 +35,7 @@ Reply codes of BIRD command-line interface
|
||||
1009 Static route list
|
||||
1010 Symbol list
|
||||
1011 Uptime
|
||||
1012 Route extended attribute list
|
||||
|
||||
8000 Reply too long
|
||||
8001 Route not found
|
||||
|
25
nest/proto.c
25
nest/proto.c
@ -22,7 +22,7 @@
|
||||
|
||||
static pool *proto_pool;
|
||||
|
||||
list protocol_list;
|
||||
static list protocol_list;
|
||||
static list proto_list;
|
||||
|
||||
#define WALK_PROTO_LIST(p) do { \
|
||||
@ -343,6 +343,17 @@ protos_dump_all(void)
|
||||
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
|
||||
protos_build(void)
|
||||
{
|
||||
@ -352,21 +363,21 @@ protos_build(void)
|
||||
init_list(&inactive_proto_list);
|
||||
init_list(&initial_proto_list);
|
||||
init_list(&flush_proto_list);
|
||||
add_tail(&protocol_list, &proto_device.n);
|
||||
proto_build(&proto_device);
|
||||
#ifdef CONFIG_RIP
|
||||
add_tail(&protocol_list, &proto_rip.n);
|
||||
proto_build(&proto_rip);
|
||||
#endif
|
||||
#ifdef CONFIG_STATIC
|
||||
add_tail(&protocol_list, &proto_static.n);
|
||||
proto_build(&proto_static);
|
||||
#endif
|
||||
#ifdef CONFIG_OSPF
|
||||
add_tail(&protocol_list, &proto_ospf.n);
|
||||
proto_build(&proto_ospf);
|
||||
#endif
|
||||
#ifdef CONFIG_PIPE
|
||||
add_tail(&protocol_list, &proto_pipe.n);
|
||||
proto_build(&proto_pipe);
|
||||
#endif
|
||||
#ifdef CONFIG_BGP
|
||||
add_tail(&protocol_list, &proto_bgp.n);
|
||||
proto_build(&proto_bgp);
|
||||
#endif
|
||||
proto_pool = rp_new(&root_pool, "Protocols");
|
||||
proto_flush_event = ev_new(proto_pool);
|
||||
|
@ -24,6 +24,7 @@ struct config;
|
||||
struct proto;
|
||||
struct event;
|
||||
struct ea_list;
|
||||
struct eattr;
|
||||
struct symbol;
|
||||
|
||||
/*
|
||||
@ -35,6 +36,7 @@ struct protocol {
|
||||
char *name;
|
||||
char *template; /* Template for automatic generation of names */
|
||||
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 (*postconfig)(struct proto_config *); /* After configuring each instance */
|
||||
@ -46,16 +48,19 @@ 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); /* 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 proto_build(struct protocol *);
|
||||
void protos_preconfig(struct config *);
|
||||
void protos_postconfig(struct config *);
|
||||
void protos_commit(struct config *new, struct config *old, int force_restart);
|
||||
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
|
||||
@ -146,7 +151,6 @@ struct proto {
|
||||
/* Hic sunt protocol-specific data */
|
||||
};
|
||||
|
||||
void proto_build(struct proto_config *);
|
||||
void *proto_new(struct proto_config *, 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_BGP 1 /* BGP attributes */
|
||||
#define EAP_RIP 2 /* RIP */
|
||||
#define EAP_MAX 3
|
||||
|
||||
#define EA_CODE(proto,id) (((proto) << 8) | (id))
|
||||
#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); }
|
||||
void rta_show(struct cli *, rta *);
|
||||
|
||||
extern struct protocol *attr_class_to_protocol[EAP_MAX];
|
||||
|
||||
/*
|
||||
* Default protocol preferences
|
||||
*/
|
||||
|
@ -19,6 +19,8 @@
|
||||
static slab *rta_slab;
|
||||
static pool *rta_pool;
|
||||
|
||||
struct protocol *attr_class_to_protocol[EAP_MAX];
|
||||
|
||||
/*
|
||||
* Extended Attributes
|
||||
*/
|
||||
@ -233,6 +235,60 @@ ea_list_copy(ea_list *o)
|
||||
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
|
||||
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",
|
||||
"BGP" };
|
||||
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));
|
||||
/* 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
|
||||
|
@ -675,11 +675,7 @@ rt_show_rte(struct cli *c, byte *ia, rte *e, struct rt_show_data *d)
|
||||
bsprintf(info, " (%d)", e->pref);
|
||||
cli_printf(c, -1007, "%-18s %s [%s %s%s]%s", ia, via, a->proto->name, tm, from, info);
|
||||
if (d->verbose)
|
||||
{
|
||||
rta_show(c, a);
|
||||
if (a->proto->proto->show_route_data)
|
||||
a->proto->proto->show_route_data(e);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -400,8 +400,8 @@ main(int argc, char **argv)
|
||||
if_init();
|
||||
|
||||
protos_build();
|
||||
add_tail(&protocol_list, &proto_unix_kernel.n);
|
||||
add_tail(&protocol_list, &proto_unix_iface.n);
|
||||
proto_build(&proto_unix_kernel);
|
||||
proto_build(&proto_unix_iface);
|
||||
|
||||
read_config();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user