summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--proto/bgp/attrs.c77
-rw-r--r--proto/bgp/bgp.c3
-rw-r--r--proto/bgp/bgp.h2
3 files changed, 66 insertions, 16 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index 29d6acb8..64281930 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -19,14 +19,24 @@
#include "bgp.h"
-static int bgp_check_origin(byte *a, int len)
+static int
+bgp_check_origin(byte *a, int len)
{
if (len > 2)
return 6;
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)
{
@@ -41,7 +51,8 @@ static int bgp_check_path(byte *a, int len)
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;
@@ -53,26 +64,36 @@ static int bgp_check_next_hop(byte *a, int len)
}
struct attr_desc {
+ char *name; /* FIXME: Use the same names as in filters */
int expected_length;
int expected_flags;
int type;
int (*validate)(byte *attr, int len);
+ void (*format)(struct eattr *ea, byte *buf);
};
static struct attr_desc bgp_attr_table[] = {
- { -1, 0, 0, NULL }, /* Undefined */
- { 1, BAF_TRANSITIVE, EAF_TYPE_INT, bgp_check_origin }, /* BA_ORIGIN */
- { -1, BAF_TRANSITIVE, EAF_TYPE_AS_PATH, bgp_check_path }, /* BA_AS_PATH */
- { 4, BAF_TRANSITIVE, EAF_TYPE_IP_ADDRESS, bgp_check_next_hop }, /* BA_NEXT_HOP */
- { 4, BAF_OPTIONAL, EAF_TYPE_INT, NULL }, /* BA_MULTI_EXIT_DISC */
- { 4, BAF_OPTIONAL, EAF_TYPE_INT, NULL }, /* BA_LOCAL_PREF */
- { 0, BAF_OPTIONAL, EAF_TYPE_OPAQUE, NULL }, /* BA_ATOMIC_AGGR */
- { 6, BAF_OPTIONAL, EAF_TYPE_OPAQUE, NULL }, /* BA_AGGREGATOR */
+ { NULL, -1, 0, 0, /* Undefined */
+ NULL, NULL },
+ { "origin", 1, BAF_TRANSITIVE, EAF_TYPE_INT, /* BA_ORIGIN */
+ bgp_check_origin, bgp_format_origin },
+ { "as_path", -1, BAF_TRANSITIVE, EAF_TYPE_AS_PATH, /* BA_AS_PATH */
+ bgp_check_path, NULL },
+ { "next_hop", 4, BAF_TRANSITIVE, EAF_TYPE_IP_ADDRESS, /* BA_NEXT_HOP */
+ 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
/* FIXME: Handle community lists */
- { 0, 0 }, /* BA_COMMUNITY */
- { 0, 0 }, /* BA_ORIGINATOR_ID */
- { 0, 0 }, /* BA_CLUSTER_LIST */
+ { 0, 0 }, /* BA_COMMUNITY */
+ { 0, 0 }, /* BA_ORIGINATOR_ID */
+ { 0, 0 }, /* BA_CLUSTER_LIST */
#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_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;
case EAF_TYPE_IP_ADDRESS:
*(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! */
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;
+}
diff --git a/proto/bgp/bgp.c b/proto/bgp/bgp.c
index 9bef2e58..f325aa30 100644
--- a/proto/bgp/bgp.c
+++ b/proto/bgp/bgp.c
@@ -406,14 +406,15 @@ bgp_get_status(struct proto *P, byte *buf)
struct protocol proto_bgp = {
name: "BGP",
template: "bgp%d",
+ attr_class: EAP_BGP,
init: bgp_init,
start: bgp_start,
shutdown: bgp_shutdown,
get_status: bgp_get_status,
+ get_attr: bgp_get_attr,
#if 0
dump: bgp_dump,
get_route_info: bgp_get_route_info,
- show_route_data: bgp_show_route_data
/* FIXME: Reconfiguration */
#endif
};
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index eadf2b04..8aaac88c 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -10,6 +10,7 @@
#define _BIRD_BGP_H_
struct linpool;
+struct eattr;
struct bgp_config {
struct proto_config c;
@@ -67,6 +68,7 @@ void bgp_close_conn(struct bgp_conn *c);
/* attrs.c */
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 */