summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2004-08-05 18:44:20 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2004-08-05 18:44:20 +0000
commit475388ebf609553cd9c9c2e5c86f22388f366dcd (patch)
tree8127764db95d65e5da4dcd61ac2f6643a839bc85 /usr.sbin
parenta9afe3a1c53305a7d4f2e003ce8fc277c893e008 (diff)
Cleanup aspath specific functions and api. Mainly switch to a refcnt based
allocation. This helps to save a bit of RAM. looks good henning@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bgpd/rde.c8
-rw-r--r--usr.sbin/bgpd/rde.h37
-rw-r--r--usr.sbin/bgpd/rde_attr.c344
-rw-r--r--usr.sbin/bgpd/rde_decide.c10
-rw-r--r--usr.sbin/bgpd/rde_filter.c16
-rw-r--r--usr.sbin/bgpd/rde_prefix.c4
-rw-r--r--usr.sbin/bgpd/rde_rib.c5
-rw-r--r--usr.sbin/bgpd/rde_update.c20
8 files changed, 247 insertions, 197 deletions
diff --git a/usr.sbin/bgpd/rde.c b/usr.sbin/bgpd/rde.c
index 6278cc4301b..97e2d2bdc30 100644
--- a/usr.sbin/bgpd/rde.c
+++ b/usr.sbin/bgpd/rde.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.c,v 1.134 2004/08/05 16:26:56 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.135 2004/08/05 18:44:19 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@@ -172,6 +172,7 @@ rde_main(struct bgpd_config *config, struct network_head *net_l,
pt_init();
path_init(pathhashsize);
+ aspath_init(pathhashsize);
nexthop_init(nexthophashsize);
peer_init(peerhashsize);
rules_l = rules;
@@ -644,9 +645,6 @@ rde_update_dispatch(struct imsg *imsg)
/* aspath needs to be loop free nota bene this is not a hard error */
if (peer->conf.ebgp && !aspath_loopfree(attrs.aspath, conf->as)) {
- char *s;
- aspath_asprint(&s, attrs.aspath->data, attrs.aspath->hdr.len);
- free(s);
attr_free(&attrs);
return (0);
}
@@ -1481,7 +1479,7 @@ network_add(struct network_config *nc, int flagstatic)
bzero(&attrs, sizeof(attrs));
- attrs.aspath = aspath_create(NULL, 0);
+ attrs.aspath = aspath_get(NULL, 0);
attrs.nexthop.s_addr = INADDR_ANY;
/* med = 0 */
attrs.lpref = DEFAULT_LPREF;
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h
index 5f94d0d6bc6..e7829dba2dc 100644
--- a/usr.sbin/bgpd/rde.h
+++ b/usr.sbin/bgpd/rde.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde.h,v 1.48 2004/08/05 15:58:21 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.49 2004/08/05 18:44:19 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
@@ -67,25 +67,16 @@ struct rde_peer {
#define AS_SET 1
#define AS_SEQUENCE 2
-#define ASPATH_HEADER_SIZE sizeof(struct aspath_hdr)
+#define ASPATH_HEADER_SIZE sizeof(struct aspath)
-struct aspath_hdr {
- u_int16_t len; /* total length of aspath
- in octets */
- u_int16_t as_cnt; /* number of AS's in data */
- u_int16_t prepend;
-};
+LIST_HEAD(aspath_list, aspath);
struct aspath {
- struct aspath_hdr hdr;
- u_char data[1];
- /*
- * data consists of multiple struct aspath_segment with a length of
- * len octets. In zebra data is a pointer to some memory location with
- * the aspath segments. We could do it like this but then we should
- * remove the pointer from rde_aspath and store the aspath header
- * directly there.
- */
+ LIST_ENTRY(aspath) entry;
+ int refcnt; /* reference count */
+ u_int16_t len; /* total length of aspath in octets */
+ u_int16_t ascnt; /* number of AS hops in data */
+ u_char data[0]; /* placeholder for actual data */
};
enum attrtypes {
@@ -264,17 +255,17 @@ int aspath_verify(void *, u_int16_t);
#define AS_ERR_LEN -1
#define AS_ERR_TYPE -2
#define AS_ERR_BAD -3
-struct aspath *aspath_create(void *, u_int16_t);
-void aspath_destroy(struct aspath *);
-int aspath_write(void *, u_int16_t, struct aspath *, u_int16_t,
- int);
+void aspath_init(u_int32_t);
+struct aspath *aspath_get(void *, u_int16_t);
+void aspath_put(struct aspath *);
u_char *aspath_dump(struct aspath *);
u_int16_t aspath_length(struct aspath *);
-u_int16_t aspath_count(struct aspath *);
+u_int16_t aspath_count(const void *, u_int16_t);
u_int16_t aspath_neighbor(struct aspath *);
-u_int32_t aspath_hash(struct aspath *);
int aspath_loopfree(struct aspath *, u_int16_t);
int aspath_compare(struct aspath *, struct aspath *);
+u_int32_t aspath_hash(const void *, u_int16_t);
+struct aspath *aspath_prepend(struct aspath *, u_int16_t, int);
int aspath_snprint(char *, size_t, void *, u_int16_t);
int aspath_asprint(char **, void *, u_int16_t);
size_t aspath_strlen(void *, u_int16_t);
diff --git a/usr.sbin/bgpd/rde_attr.c b/usr.sbin/bgpd/rde_attr.c
index 84d0007b23a..756d4649869 100644
--- a/usr.sbin/bgpd/rde_attr.c
+++ b/usr.sbin/bgpd/rde_attr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_attr.c,v 1.39 2004/07/28 16:02:14 claudio Exp $ */
+/* $OpenBSD: rde_attr.c,v 1.40 2004/08/05 18:44:19 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -112,7 +112,7 @@ attr_parse(u_char *p, u_int16_t len, struct attr_flags *a, int ebgp,
if (aspath_verify(p, attr_len) != 0)
return (-1);
WFLAG(a->wflags, F_ATTR_ASPATH);
- a->aspath = aspath_create(p, attr_len);
+ a->aspath = aspath_get(p, attr_len);
if (enforce_as == ENFORCE_AS_ON &&
remote_as != aspath_neighbor(a->aspath))
return (-1);
@@ -448,7 +448,7 @@ attr_copy(struct attr_flags *t, struct attr_flags *s)
* a own copy.
*/
memcpy(t, s, sizeof(struct attr_flags));
- t->aspath = aspath_create(s->aspath->data, s->aspath->hdr.len);
+ t->aspath = aspath_get(s->aspath->data, s->aspath->len);
TAILQ_INIT(&t->others);
TAILQ_FOREACH(os, &s->others, entry)
attr_optadd(t, os->flags, os->type, os->data, os->len);
@@ -476,7 +476,7 @@ attr_free(struct attr_flags *a)
* free the aspath and all optional path attributes
* but not the attr_flags struct.
*/
- aspath_destroy(a->aspath);
+ aspath_put(a->aspath);
a->aspath = NULL;
attr_optfree(a);
}
@@ -667,25 +667,17 @@ attr_mp_nexthop(const struct attr_flags *attrs)
/* aspath specific functions */
-static u_int16_t aspath_extract(void *, int);
+u_int32_t aspath_hash(const void *, u_int16_t);
+u_int16_t aspath_extract(const void *, int);
+struct aspath *aspath_lookup(const void *, u_int16_t);
-/*
- * Extract the asnum out of the as segment at the specified position.
- * Direct access is not possible because of non-aligned reads.
- * ATTENTION: no bounds check are done.
- */
-static u_int16_t
-aspath_extract(void *seg, int pos)
-{
- u_char *ptr = seg;
- u_int16_t as = 0;
+struct aspath_table {
+ struct aspath_list *hashtbl;
+ u_int32_t hashmask;
+} astable;
- ptr += 2 + 2 * pos;
- as = *ptr++;
- as <<= 8;
- as |= *ptr;
- return (as);
-}
+#define ASPATH_HASH(x) \
+ &astable.hashtbl[(x) & astable.hashmask]
int
aspath_verify(void *data, u_int16_t len)
@@ -719,115 +711,63 @@ aspath_verify(void *data, u_int16_t len)
return (0); /* aspath is valid but probably not loop free */
}
-struct aspath *
-aspath_create(void *data, u_int16_t len)
+void
+aspath_init(u_int32_t hashsize)
{
- struct aspath *aspath;
+ u_int32_t hs, i;
- /* The aspath must already have been checked for correctness. */
- aspath = malloc(ASPATH_HEADER_SIZE + len);
- if (aspath == NULL)
- fatal("aspath_create");
- aspath->hdr.len = len;
- memcpy(aspath->data, data, len);
+ for (hs = 1; hs < hashsize; hs <<= 1)
+ ;
+ astable.hashtbl = calloc(hs, sizeof(struct aspath_list));
+ if (astable.hashtbl == NULL)
+ fatal("path_init");
- aspath->hdr.as_cnt = aspath_count(aspath);
- aspath->hdr.prepend = 0;
+ for (i = 0; i < hs; i++)
+ LIST_INIT(&astable.hashtbl[i]);
- return (aspath);
+ astable.hashmask = hs - 1;
}
-int
-aspath_write(void *p, u_int16_t len, struct aspath *aspath, u_int16_t myAS,
- int ebgp)
+struct aspath *
+aspath_get(void *data, u_int16_t len)
{
- u_char *b = p;
- int tot_len, as_len, prepend, size, wpos = 0;
- u_int16_t tmp;
- u_int8_t type, attr_flag = ATTR_WELL_KNOWN;
-
- prepend = aspath->hdr.prepend + (ebgp ? 1 : 0);
-
- if (prepend > 255)
- /* lunatic prepends need to be blocked in the parser */
- return (-1);
+ struct aspath_list *head;
+ struct aspath *aspath;
- /* first calculate new size */
- if (aspath->hdr.len > 0) {
- if (aspath->hdr.len < 2)
- return (-1);
- type = aspath->data[0];
- size = aspath->data[1];
- } else {
- /* empty as path */
- type = AS_SET;
- size = 0;
+ /* The aspath must already have been checked for correctness. */
+ aspath = aspath_lookup(data, len);
+ if (aspath == NULL) {
+ aspath = malloc(ASPATH_HEADER_SIZE + len);
+ if (aspath == NULL)
+ fatal("aspath_get");
+
+ aspath->refcnt = 0;
+ aspath->len = len;
+ aspath->ascnt = aspath_count(data, len);
+ memcpy(aspath->data, data, len);
+
+ /* link */
+ head = ASPATH_HASH(aspath_hash(aspath->data, aspath->len));
+ LIST_INSERT_HEAD(head, aspath, entry);
}
- if (prepend == 0)
- as_len = aspath->hdr.len;
- else if (type == AS_SET || size + prepend > 255)
- /* need to attach a new AS_SEQUENCE */
- as_len = 2 + prepend * 2 + aspath->hdr.len;
- else
- as_len = prepend * 2 + aspath->hdr.len;
-
- /* check buffer size */
- tot_len = 2 + as_len;
- if (as_len > 255) {
- attr_flag |= ATTR_EXTLEN;
- tot_len += 2;
- } else
- tot_len += 1;
-
- if (tot_len > len)
- return (-1);
-
- /* header */
- b[wpos++] = attr_flag;
- b[wpos++] = ATTR_ASPATH;
- if (as_len > 255) {
- tmp = as_len;
- tmp = htons(tmp);
- memcpy(b, &tmp, 2);
- wpos += 2;
- } else
- b[wpos++] = (u_char)(as_len & 0xff);
+ aspath->refcnt++;
- /* first prepends */
- myAS = htons(myAS);
- if (type == AS_SET) {
- b[wpos++] = AS_SEQUENCE;
- b[wpos++] = prepend;
- for (; prepend > 0; prepend--) {
- memcpy(b + wpos, &myAS, 2);
- wpos += 2;
- }
- memcpy(b + wpos, aspath->data, aspath->hdr.len);
- } else {
- if (size + prepend > 255) {
- b[wpos++] = AS_SEQUENCE;
- b[wpos++] = size + prepend - 255;
- for (; prepend + size > 255; prepend--) {
- memcpy(b + wpos, &myAS, 2);
- wpos += 2;
- }
- }
- b[wpos++] = AS_SEQUENCE;
- b[wpos++] = size + prepend;
- for (; prepend > 0; prepend--) {
- memcpy(b + wpos, &myAS, 2);
- wpos += 2;
- }
- memcpy(b + wpos, aspath->data + 2, aspath->hdr.len - 2);
- }
- return (tot_len);
+ return (aspath);
}
void
-aspath_destroy(struct aspath *aspath)
+aspath_put(struct aspath *aspath)
{
- /* only the aspath needs to be freed */
- if (aspath == NULL) return;
+ if (aspath == NULL)
+ return;
+
+ if (--aspath->refcnt > 0)
+ /* somebody still holds a reference */
+ return;
+
+ /* unlink */
+ LIST_REMOVE(aspath, entry);
+
free(aspath);
}
@@ -840,19 +780,19 @@ aspath_dump(struct aspath *aspath)
u_int16_t
aspath_length(struct aspath *aspath)
{
- return (aspath->hdr.len);
+ return (aspath->len);
}
u_int16_t
-aspath_count(struct aspath *aspath)
+aspath_count(const void *data, u_int16_t len)
{
- u_int8_t *seg;
- u_int16_t cnt, len, seg_size;
+ const u_int8_t *seg;
+ u_int16_t cnt, seg_size;
u_int8_t seg_type, seg_len;
cnt = 0;
- seg = aspath->data;
- for (len = aspath->hdr.len; len > 0; len -= seg_size, seg += seg_size) {
+ seg = data;
+ for (; len > 0; len -= seg_size, seg += seg_size) {
seg_type = seg[0];
seg_len = seg[1];
seg_size = 2 + 2 * seg_len;
@@ -861,6 +801,9 @@ aspath_count(struct aspath *aspath)
cnt += 1;
else
cnt += seg_len;
+
+ if (seg_size > len)
+ fatalx("aspath_count: bula bula");
}
return (cnt);
}
@@ -874,7 +817,7 @@ aspath_neighbor(struct aspath *aspath)
* That should not break anything.
*/
- if (aspath->hdr.len == 0)
+ if (aspath->len == 0)
return (0);
return (aspath_extract(aspath->data, 0));
@@ -888,7 +831,7 @@ aspath_loopfree(struct aspath *aspath, u_int16_t myAS)
u_int8_t i, seg_len, seg_type;
seg = aspath->data;
- for (len = aspath->hdr.len; len > 0; len -= seg_size, seg += seg_size) {
+ for (len = aspath->len; len > 0; len -= seg_size, seg += seg_size) {
seg_type = seg[0];
seg_len = seg[1];
seg_size = 2 + 2 * seg_len;
@@ -897,23 +840,43 @@ aspath_loopfree(struct aspath *aspath, u_int16_t myAS)
if (myAS == aspath_extract(seg, i))
return (0);
}
+
+ if (seg_size > len)
+ fatalx("aspath_loopfree: bula bula");
}
return (1);
}
+int
+aspath_compare(struct aspath *a1, struct aspath *a2)
+{
+ int r;
+
+ if (a1->len > a2->len)
+ return (1);
+ if (a1->len < a2->len)
+ return (-1);
+ r = memcmp(a1->data, a2->data, a1->len);
+ if (r > 0)
+ return (1);
+ if (r < 0)
+ return (-1);
+ return (0);
+}
+
#define AS_HASH_INITIAL 8271
u_int32_t
-aspath_hash(struct aspath *aspath)
+aspath_hash(const void *data, u_int16_t len)
{
- u_int8_t *seg;
+ const u_int8_t *seg;
u_int32_t hash;
- u_int16_t len, seg_size;
+ u_int16_t seg_size;
u_int8_t i, seg_len, seg_type;
hash = AS_HASH_INITIAL;
- seg = aspath->data;
- for (len = aspath->hdr.len; len > 0; len -= seg_size, seg += seg_size) {
+ seg = data;
+ for (; len > 0; len -= seg_size, seg += seg_size) {
seg_type = seg[0];
seg_len = seg[1];
seg_size = 2 + 2 * seg_len;
@@ -922,25 +885,117 @@ aspath_hash(struct aspath *aspath)
hash += (hash << 5);
hash ^= aspath_extract(seg, i);
}
+
+ if (seg_size > len)
+ fatalx("aspath_hash: bula bula");
}
return (hash);
}
-int
-aspath_compare(struct aspath *a1, struct aspath *a2)
+/*
+ * Extract the asnum out of the as segment at the specified position.
+ * Direct access is not possible because of non-aligned reads.
+ * ATTENTION: no bounds check are done.
+ */
+u_int16_t
+aspath_extract(const void *seg, int pos)
{
- int r;
+ const u_char *ptr = seg;
+ u_int16_t as = 0;
- if (a1->hdr.len > a2->hdr.len)
- return (1);
- if (a1->hdr.len < a2->hdr.len)
- return (-1);
- r = memcmp(a1->data, a2->data, a1->hdr.len);
- if (r > 0)
- return (1);
- if (r < 0)
- return (-1);
- return (0);
+ ptr += 2 + 2 * pos;
+ as = *ptr++;
+ as <<= 8;
+ as |= *ptr;
+ return (as);
+}
+
+struct aspath *
+aspath_lookup(const void *data, u_int16_t len)
+{
+ struct aspath_list *head;
+ struct aspath *aspath;
+ u_int32_t hash;
+
+ hash = aspath_hash(data, len);
+ head = ASPATH_HASH(hash);
+
+ LIST_FOREACH(aspath, head, entry) {
+ if (len == aspath->len && memcmp(data, aspath->data, len) == 0)
+ return (aspath);
+ }
+ return (NULL);
+}
+
+
+/*
+ * Returns a new prepended aspath. Old needs to be freed by caller.
+ */
+struct aspath *
+aspath_prepend(struct aspath *asp, u_int16_t as, int quantum)
+{
+ u_char *p;
+ int len, overflow = 0, shift = 0, size, wpos = 0;
+ u_int8_t type;
+
+ /* lunatic prepends are blocked in the parser and limited */
+
+ /* first calculate new size */
+ if (asp->len > 0) {
+ if (asp->len < 2)
+ fatalx("aspath_prepend: bula bula");
+ type = asp->data[0];
+ size = asp->data[1];
+ } else {
+ /* empty as path */
+ type = AS_SET;
+ size = 0;
+ }
+
+ if (quantum == 0) {
+ /* no change needed but increase refcnt as we return a copy */
+ asp->refcnt++;
+ return (asp);
+ } else if (type == AS_SET || size + quantum > 255) {
+ /* need to attach a new AS_SEQUENCE */
+ len = 2 + quantum * 2 + asp->len;
+ overflow = type == AS_SET ? quantum : (size + quantum) & 0xff;
+ } else
+ len = quantum * 2 + asp->len;
+
+ quantum -= overflow;
+
+ p = malloc(len);
+ if (p == NULL)
+ fatal("aspath_prepend");
+
+ /* first prepends */
+ as = htons(as);
+ if (overflow > 0) {
+ p[wpos++] = AS_SEQUENCE;
+ p[wpos++] = overflow;
+
+ for (; overflow > 0; overflow--) {
+ memcpy(p + wpos, &as, 2);
+ wpos += 2;
+ }
+ }
+ if (quantum > 0) {
+ shift = 2;
+ p[wpos++] = AS_SEQUENCE;
+ p[wpos++] = quantum + size;
+
+ for (; quantum > 0; quantum--) {
+ memcpy(p + wpos, &as, 2);
+ wpos += 2;
+ }
+ }
+ memcpy(p + wpos, asp->data + shift, asp->len - shift);
+
+ asp = aspath_get(p, len);
+ free(p);
+
+ return (asp);
}
int
@@ -1073,7 +1128,7 @@ aspath_match(struct aspath *a, enum as_spec type, u_int16_t as)
u_int8_t i, seg_type, seg_len;
if (type == AS_EMPTY) {
- if (a->hdr.len == 0)
+ if (a->len == 0)
return (1);
else
return (0);
@@ -1081,7 +1136,7 @@ aspath_match(struct aspath *a, enum as_spec type, u_int16_t as)
final = 0;
seg = a->data;
- for (len = a->hdr.len; len > 0; len -= seg_size, seg += seg_size) {
+ for (len = a->len; len > 0; len -= seg_size, seg += seg_size) {
seg_type = seg[0];
seg_len = seg[1];
seg_size = 2 + 2 * seg_len;
@@ -1149,6 +1204,7 @@ community_set(struct attr *attr, int as, int type)
attr->len += 4;
if ((p = realloc(attr->data, attr->len)) == NULL)
return (0);
+
attr->data = p;
p = attr->data + attr->len - 4;
}
diff --git a/usr.sbin/bgpd/rde_decide.c b/usr.sbin/bgpd/rde_decide.c
index e42f58c36d4..1d116f75bb3 100644
--- a/usr.sbin/bgpd/rde_decide.c
+++ b/usr.sbin/bgpd/rde_decide.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_decide.c,v 1.36 2004/07/28 17:10:15 claudio Exp $ */
+/* $OpenBSD: rde_decide.c,v 1.37 2004/08/05 18:44:19 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -132,10 +132,10 @@ prefix_cmp(struct prefix *p1, struct prefix *p2)
return (asp1->flags.lpref - asp2->flags.lpref);
/* 3. aspath count, the shorter the better */
- if ((asp2->flags.aspath->hdr.as_cnt -
- asp1->flags.aspath->hdr.as_cnt) != 0)
- return (asp2->flags.aspath->hdr.as_cnt -
- asp1->flags.aspath->hdr.as_cnt);
+ if ((asp2->flags.aspath->ascnt -
+ asp1->flags.aspath->ascnt) != 0)
+ return (asp2->flags.aspath->ascnt -
+ asp1->flags.aspath->ascnt);
/* 4. origin, the lower the better */
if ((asp2->flags.origin - asp1->flags.origin) != 0)
diff --git a/usr.sbin/bgpd/rde_filter.c b/usr.sbin/bgpd/rde_filter.c
index df96d864692..22d880364c5 100644
--- a/usr.sbin/bgpd/rde_filter.c
+++ b/usr.sbin/bgpd/rde_filter.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_filter.c,v 1.14 2004/08/05 15:58:21 claudio Exp $ */
+/* $OpenBSD: rde_filter.c,v 1.15 2004/08/05 18:44:19 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -58,6 +58,9 @@ rde_filter(struct rde_peer *peer, struct attr_flags *attrs,
void
rde_apply_set(struct attr_flags *attrs, struct filter_set *set)
{
+ struct aspath *new;
+ u_int16_t as;
+
if (attrs == NULL)
return;
@@ -72,13 +75,10 @@ rde_apply_set(struct attr_flags *attrs, struct filter_set *set)
if (set->flags & SET_NEXTHOP_BLACKHOLE)
attrs->nexthop_blackhole = 1;
if (set->flags & SET_PREPEND) {
- /*
- * The actual prepending is done afterwards because
- * This could overflow but somebody that uses that many
- * prepends is loony and needs professional help.
- */
- attrs->aspath->hdr.prepend += set->prepend;
- attrs->aspath->hdr.as_cnt += set->prepend;
+ as = rde_local_as();
+ new = aspath_prepend(attrs->aspath, as, set->prepend);
+ aspath_put(attrs->aspath);
+ attrs->aspath = new;
}
if (set->flags & SET_PFTABLE)
strlcpy(attrs->pftable, set->pftable, sizeof(attrs->pftable));
diff --git a/usr.sbin/bgpd/rde_prefix.c b/usr.sbin/bgpd/rde_prefix.c
index 0a9155a0ea3..d4cc5854fe5 100644
--- a/usr.sbin/bgpd/rde_prefix.c
+++ b/usr.sbin/bgpd/rde_prefix.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_prefix.c,v 1.17 2004/08/03 14:46:23 claudio Exp $ */
+/* $OpenBSD: rde_prefix.c,v 1.18 2004/08/05 18:44:19 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -270,7 +270,7 @@ pt_prefix_cmp(const struct pt_entry *a, const struct pt_entry *b)
int i;
if (a->af != b->af)
- fatalx("king bula sez: comapring pears with apples");
+ fatalx("king bula sez: comapring pears with apples");
switch (a->af) {
case AF_INET:
diff --git a/usr.sbin/bgpd/rde_rib.c b/usr.sbin/bgpd/rde_rib.c
index 5e0c5d6390c..482f73d139b 100644
--- a/usr.sbin/bgpd/rde_rib.c
+++ b/usr.sbin/bgpd/rde_rib.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_rib.c,v 1.52 2004/08/05 16:26:56 claudio Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.53 2004/08/05 18:44:19 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -73,7 +73,8 @@ static void path_free(struct rde_aspath *);
struct path_table pathtable;
#define PATH_HASH(x) \
- &pathtable.path_hashtbl[aspath_hash((x)) & pathtable.path_hashmask]
+ &pathtable.path_hashtbl[aspath_hash((x)->data, (x)->len) & \
+ pathtable.path_hashmask]
void
path_init(u_int32_t hashsize)
diff --git a/usr.sbin/bgpd/rde_update.c b/usr.sbin/bgpd/rde_update.c
index d26bd2e30cc..8b442352305 100644
--- a/usr.sbin/bgpd/rde_update.c
+++ b/usr.sbin/bgpd/rde_update.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_update.c,v 1.25 2004/08/05 16:26:56 claudio Exp $ */
+/* $OpenBSD: rde_update.c,v 1.26 2004/08/05 18:44:19 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
@@ -283,7 +283,7 @@ up_generate_updates(struct rde_peer *peer,
* pass only prefix that have a aspath count
* of zero this is equal to the ^$ regex.
*/
- if (old->aspath->flags.aspath->hdr.as_cnt != 0)
+ if (old->aspath->flags.aspath->ascnt != 0)
return;
break;
}
@@ -385,7 +385,7 @@ up_generate_updates(struct rde_peer *peer,
* pass only prefix that have a aspath count
* of zero this is equal to the ^$ regex.
*/
- if (new->aspath->flags.aspath->hdr.as_cnt != 0) {
+ if (new->aspath->flags.aspath->ascnt != 0) {
up_generate_updates(peer, NULL, old);
return;
}
@@ -455,7 +455,8 @@ up_generate_updates(struct rde_peer *peer,
* use aspath_hash as attr_hash, this may be unoptimal
* but currently I don't care.
*/
- a->attr_hash = aspath_hash(attrs.aspath);
+ a->attr_hash = aspath_hash(attrs.aspath->data,
+ attrs.aspath->len);
p->prefix = addr;
p->prefixlen = new->prefix->prefixlen;
@@ -480,7 +481,7 @@ up_generate_default(struct rde_peer *peer, sa_family_t af)
bzero(&addr, sizeof(addr));
bzero(&nexthop, sizeof(nexthop));
- attrs.aspath = aspath_create(NULL, 0);
+ attrs.aspath = aspath_get(NULL, 0);
attrs.nexthop.s_addr = INADDR_ANY;
/* med = 0 */
attrs.lpref = DEFAULT_LPREF;
@@ -521,7 +522,7 @@ up_generate_default(struct rde_peer *peer, sa_family_t af)
* use aspath_hash as attr_hash, this may be unoptimal
* but currently I don't care.
*/
- a->attr_hash = aspath_hash(attrs.aspath);
+ a->attr_hash = aspath_hash(attrs.aspath->data, attrs.aspath->len);
p->prefix = addr;
p->prefixlen = 0; /* default route */
@@ -539,6 +540,7 @@ int
up_generate_attr(struct rde_peer *peer, struct update_attr *upa,
struct attr_flags *a, struct nexthop *nh)
{
+ struct aspath *path;
struct attr *oa;
u_int32_t tmp32;
in_addr_t nexthop, mask;
@@ -552,9 +554,11 @@ up_generate_attr(struct rde_peer *peer, struct update_attr *upa,
wlen += r; len -= r;
/* aspath */
- if ((r = aspath_write(up_attr_buf + wlen, len, a->aspath,
- rde_local_as(), peer->conf.ebgp)) == -1)
+ path = aspath_prepend(a->aspath, rde_local_as(), peer->conf.ebgp);
+ if ((r = attr_write(up_attr_buf + wlen, len, ATTR_WELL_KNOWN,
+ ATTR_ASPATH, path->data, path->len)) == -1)
return (-1);
+ aspath_put(path);
wlen += r; len -= r;
/* nexthop, already network byte order */