Formatting of dynamic attributes (except for paths and communities which
will be added soon).
This commit is contained in:
parent
dad177d7e0
commit
10be74da20
3 changed files with 66 additions and 16 deletions
|
@ -19,14 +19,24 @@
|
||||||
|
|
||||||
#include "bgp.h"
|
#include "bgp.h"
|
||||||
|
|
||||||
static int bgp_check_origin(byte *a, int len)
|
static int
|
||||||
|
bgp_check_origin(byte *a, int len)
|
||||||
{
|
{
|
||||||
if (len > 2)
|
if (len > 2)
|
||||||
return 6;
|
return 6;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bgp_check_path(byte *a, int len)
|
static void
|
||||||
|
bgp_format_origin(struct eattr *a, byte *buf)
|
||||||
|
{
|
||||||
|
static char *bgp_origin_names[] = { "IGP", "EGP", "Incomplete" };
|
||||||
|
|
||||||
|
bsprintf(buf, bgp_origin_names[a->u.data]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
bgp_check_path(byte *a, int len)
|
||||||
{
|
{
|
||||||
while (len)
|
while (len)
|
||||||
{
|
{
|
||||||
|
@ -41,7 +51,8 @@ static int bgp_check_path(byte *a, int len)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bgp_check_next_hop(byte *a, int len)
|
static int
|
||||||
|
bgp_check_next_hop(byte *a, int len)
|
||||||
{
|
{
|
||||||
ip_addr addr;
|
ip_addr addr;
|
||||||
|
|
||||||
|
@ -53,26 +64,36 @@ static int bgp_check_next_hop(byte *a, int len)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct attr_desc {
|
struct attr_desc {
|
||||||
|
char *name; /* FIXME: Use the same names as in filters */
|
||||||
int expected_length;
|
int expected_length;
|
||||||
int expected_flags;
|
int expected_flags;
|
||||||
int type;
|
int type;
|
||||||
int (*validate)(byte *attr, int len);
|
int (*validate)(byte *attr, int len);
|
||||||
|
void (*format)(struct eattr *ea, byte *buf);
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct attr_desc bgp_attr_table[] = {
|
static struct attr_desc bgp_attr_table[] = {
|
||||||
{ -1, 0, 0, NULL }, /* Undefined */
|
{ NULL, -1, 0, 0, /* Undefined */
|
||||||
{ 1, BAF_TRANSITIVE, EAF_TYPE_INT, bgp_check_origin }, /* BA_ORIGIN */
|
NULL, NULL },
|
||||||
{ -1, BAF_TRANSITIVE, EAF_TYPE_AS_PATH, bgp_check_path }, /* BA_AS_PATH */
|
{ "origin", 1, BAF_TRANSITIVE, EAF_TYPE_INT, /* BA_ORIGIN */
|
||||||
{ 4, BAF_TRANSITIVE, EAF_TYPE_IP_ADDRESS, bgp_check_next_hop }, /* BA_NEXT_HOP */
|
bgp_check_origin, bgp_format_origin },
|
||||||
{ 4, BAF_OPTIONAL, EAF_TYPE_INT, NULL }, /* BA_MULTI_EXIT_DISC */
|
{ "as_path", -1, BAF_TRANSITIVE, EAF_TYPE_AS_PATH, /* BA_AS_PATH */
|
||||||
{ 4, BAF_OPTIONAL, EAF_TYPE_INT, NULL }, /* BA_LOCAL_PREF */
|
bgp_check_path, NULL },
|
||||||
{ 0, BAF_OPTIONAL, EAF_TYPE_OPAQUE, NULL }, /* BA_ATOMIC_AGGR */
|
{ "next_hop", 4, BAF_TRANSITIVE, EAF_TYPE_IP_ADDRESS, /* BA_NEXT_HOP */
|
||||||
{ 6, BAF_OPTIONAL, EAF_TYPE_OPAQUE, NULL }, /* BA_AGGREGATOR */
|
bgp_check_next_hop, NULL },
|
||||||
|
{ "MED", 4, BAF_OPTIONAL, EAF_TYPE_INT, /* BA_MULTI_EXIT_DISC */
|
||||||
|
NULL, NULL },
|
||||||
|
{ "local_pref", 4, BAF_OPTIONAL, EAF_TYPE_INT, /* BA_LOCAL_PREF */
|
||||||
|
NULL, NULL },
|
||||||
|
{ "atomic_aggr", 0, BAF_OPTIONAL, EAF_TYPE_OPAQUE, /* BA_ATOMIC_AGGR */
|
||||||
|
NULL, NULL },
|
||||||
|
{ "aggregator", 6, BAF_OPTIONAL, EAF_TYPE_OPAQUE, /* BA_AGGREGATOR */
|
||||||
|
NULL, NULL },
|
||||||
#if 0
|
#if 0
|
||||||
/* FIXME: Handle community lists */
|
/* FIXME: Handle community lists */
|
||||||
{ 0, 0 }, /* BA_COMMUNITY */
|
{ 0, 0 }, /* BA_COMMUNITY */
|
||||||
{ 0, 0 }, /* BA_ORIGINATOR_ID */
|
{ 0, 0 }, /* BA_ORIGINATOR_ID */
|
||||||
{ 0, 0 }, /* BA_CLUSTER_LIST */
|
{ 0, 0 }, /* BA_CLUSTER_LIST */
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -175,7 +196,10 @@ bgp_decode_attrs(struct bgp_conn *conn, byte *attr, unsigned int len, struct lin
|
||||||
{
|
{
|
||||||
case EAF_TYPE_ROUTER_ID:
|
case EAF_TYPE_ROUTER_ID:
|
||||||
case EAF_TYPE_INT:
|
case EAF_TYPE_INT:
|
||||||
ea->attrs[0].u.data = get_u32(z);
|
if (l == 1)
|
||||||
|
ea->attrs[0].u.data = *z;
|
||||||
|
else
|
||||||
|
ea->attrs[0].u.data = get_u32(z);
|
||||||
break;
|
break;
|
||||||
case EAF_TYPE_IP_ADDRESS:
|
case EAF_TYPE_IP_ADDRESS:
|
||||||
*(ip_addr *)ad->data = ipa_ntoh(*(ip_addr *)ad->data);
|
*(ip_addr *)ad->data = ipa_ntoh(*(ip_addr *)ad->data);
|
||||||
|
@ -223,3 +247,26 @@ err:
|
||||||
bgp_error(conn, 3, errcode, code, 0); /* FIXME: Return attribute data! */
|
bgp_error(conn, 3, errcode, code, 0); /* FIXME: Return attribute data! */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
bgp_get_attr(eattr *a, byte *buf)
|
||||||
|
{
|
||||||
|
unsigned int i = EA_ID(a->id);
|
||||||
|
struct attr_desc *d;
|
||||||
|
|
||||||
|
if (i && i < sizeof(bgp_attr_table)/sizeof(bgp_attr_table[0]))
|
||||||
|
{
|
||||||
|
d = &bgp_attr_table[i];
|
||||||
|
buf += bsprintf(buf, "%s", d->name);
|
||||||
|
if (d->format)
|
||||||
|
{
|
||||||
|
*buf++ = ':';
|
||||||
|
*buf++ = ' ';
|
||||||
|
d->format(a, buf);
|
||||||
|
return GA_FULL;
|
||||||
|
}
|
||||||
|
return GA_NAME;
|
||||||
|
}
|
||||||
|
bsprintf(buf, "%02x%s", i, (a->flags & BAF_TRANSITIVE) ? "[t]" : "");
|
||||||
|
return GA_NAME;
|
||||||
|
}
|
||||||
|
|
|
@ -406,14 +406,15 @@ bgp_get_status(struct proto *P, byte *buf)
|
||||||
struct protocol proto_bgp = {
|
struct protocol proto_bgp = {
|
||||||
name: "BGP",
|
name: "BGP",
|
||||||
template: "bgp%d",
|
template: "bgp%d",
|
||||||
|
attr_class: EAP_BGP,
|
||||||
init: bgp_init,
|
init: bgp_init,
|
||||||
start: bgp_start,
|
start: bgp_start,
|
||||||
shutdown: bgp_shutdown,
|
shutdown: bgp_shutdown,
|
||||||
get_status: bgp_get_status,
|
get_status: bgp_get_status,
|
||||||
|
get_attr: bgp_get_attr,
|
||||||
#if 0
|
#if 0
|
||||||
dump: bgp_dump,
|
dump: bgp_dump,
|
||||||
get_route_info: bgp_get_route_info,
|
get_route_info: bgp_get_route_info,
|
||||||
show_route_data: bgp_show_route_data
|
|
||||||
/* FIXME: Reconfiguration */
|
/* FIXME: Reconfiguration */
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#define _BIRD_BGP_H_
|
#define _BIRD_BGP_H_
|
||||||
|
|
||||||
struct linpool;
|
struct linpool;
|
||||||
|
struct eattr;
|
||||||
|
|
||||||
struct bgp_config {
|
struct bgp_config {
|
||||||
struct proto_config c;
|
struct proto_config c;
|
||||||
|
@ -67,6 +68,7 @@ void bgp_close_conn(struct bgp_conn *c);
|
||||||
/* attrs.c */
|
/* attrs.c */
|
||||||
|
|
||||||
struct rta *bgp_decode_attrs(struct bgp_conn *conn, byte *a, unsigned int len, struct linpool *pool);
|
struct rta *bgp_decode_attrs(struct bgp_conn *conn, byte *a, unsigned int len, struct linpool *pool);
|
||||||
|
int bgp_get_attr(struct eattr *e, byte *buf);
|
||||||
|
|
||||||
/* packets.c */
|
/* packets.c */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue