summaryrefslogtreecommitdiff
path: root/net/openbgpd/files/patch-bgpd_rde_attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openbgpd/files/patch-bgpd_rde_attr.c')
-rw-r--r--net/openbgpd/files/patch-bgpd_rde_attr.c145
1 files changed, 125 insertions, 20 deletions
diff --git a/net/openbgpd/files/patch-bgpd_rde_attr.c b/net/openbgpd/files/patch-bgpd_rde_attr.c
index f62d59f083f0..eccdc1e36c27 100644
--- a/net/openbgpd/files/patch-bgpd_rde_attr.c
+++ b/net/openbgpd/files/patch-bgpd_rde_attr.c
@@ -2,17 +2,17 @@ Index: bgpd/rde_attr.c
===================================================================
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde_attr.c,v
retrieving revision 1.1.1.6
-retrieving revision 1.5
-diff -u -p -r1.1.1.6 -r1.5
+retrieving revision 1.6
+diff -u -p -r1.1.1.6 -r1.6
--- bgpd/rde_attr.c 14 Feb 2010 20:19:57 -0000 1.1.1.6
-+++ bgpd/rde_attr.c 10 Apr 2010 12:16:23 -0000 1.5
++++ bgpd/rde_attr.c 2 Jul 2011 16:06:38 -0000 1.6
@@ -1,4 +1,4 @@
-/* $OpenBSD: rde_attr.c,v 1.79 2009/03/19 06:52:59 claudio Exp $ */
+/* $OpenBSD: rde_attr.c,v 1.83 2010/03/29 09:24:07 claudio Exp $ */
/*
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
-@@ -17,7 +17,11 @@
+@@ -17,14 +17,22 @@
*/
#include <sys/types.h>
@@ -24,7 +24,8 @@ diff -u -p -r1.1.1.6 -r1.5
#include <sys/queue.h>
#include <netinet/in.h>
-@@ -25,6 +29,9 @@
+
++#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@@ -34,39 +35,143 @@ diff -u -p -r1.1.1.6 -r1.5
#include "bgpd.h"
#include "rde.h"
-@@ -971,15 +978,26 @@ aspath_match(struct aspath *a, enum as_s
+@@ -63,7 +71,7 @@ attr_write(void *p, u_int16_t p_len, u_i
+ }
+
+ int
+-attr_writebuf(struct buf *buf, u_int8_t flags, u_int8_t type, void *data,
++attr_writebuf(struct ibuf *buf, u_int8_t flags, u_int8_t type, void *data,
+ u_int16_t data_len)
+ {
+ u_char hdr[4];
+@@ -80,9 +88,9 @@ attr_writebuf(struct buf *buf, u_int8_t
+ hdr[0] = flags;
+ hdr[1] = type;
+
+- if (buf_add(buf, hdr, flags & ATTR_EXTLEN ? 4 : 3) == -1)
++ if (ibuf_add(buf, hdr, flags & ATTR_EXTLEN ? 4 : 3) == -1)
+ return (-1);
+- if (buf_add(buf, data, data_len) == -1)
++ if (ibuf_add(buf, data, data_len) == -1)
+ return (-1);
return (0);
}
+@@ -146,8 +154,11 @@ attr_optadd(struct rde_aspath *asp, u_in
+ for (l = 0; l < asp->others_len; l++) {
+ if (asp->others[l] == NULL)
+ break;
+- if (type == asp->others[l]->type)
++ if (type == asp->others[l]->type) {
++ if (a->refcnt == 0)
++ attr_put(a);
+ return (-1);
++ }
+ }
+
+ /* add attribute to the table but first bump refcnt */
+@@ -405,6 +416,7 @@ aspath_verify(void *data, u_int16_t len,
+ u_int8_t *seg = data;
+ u_int16_t seg_size, as_size = 2;
+ u_int8_t seg_len, seg_type;
++ int err = 0;
+ if (len & 1)
+ /* odd length aspath are invalid */
+@@ -419,7 +431,15 @@ aspath_verify(void *data, u_int16_t len,
+ seg_type = seg[0];
+ seg_len = seg[1];
+
+- if (seg_type != AS_SET && seg_type != AS_SEQUENCE)
++ /*
++ * BGP confederations should not show up but consider them
++ * as a soft error which invalidates the path but keeps the
++ * bgp session running.
++ */
++ if (seg_type == AS_CONFED_SEQUENCE || seg_type == AS_CONFED_SET)
++ err = AS_ERR_SOFT;
++ if (seg_type != AS_SET && seg_type != AS_SEQUENCE &&
++ seg_type != AS_CONFED_SEQUENCE && seg_type != AS_CONFED_SET)
+ return (AS_ERR_TYPE);
+
+ seg_size = 2 + as_size * seg_len;
+@@ -431,7 +451,7 @@ aspath_verify(void *data, u_int16_t len,
+ /* empty aspath segments are not allowed */
+ return (AS_ERR_BAD);
+ }
+- return (0); /* aspath is valid but probably not loop free */
++ return (err); /* aspath is valid but probably not loop free */
+ }
+
+ void
+@@ -972,14 +992,62 @@ aspath_match(struct aspath *a, enum as_s
+ }
+
+ int
+-community_match(void *data, u_int16_t len, int as, int type)
++aspath_lenmatch(struct aspath *a, enum aslen_spec type, u_int aslen)
+ {
+- u_int8_t *p = data;
+- u_int16_t eas, etype;
++ u_int8_t *seg;
++ u_int32_t as, lastas = 0;
++ u_int count = 0;
++ u_int16_t len, seg_size;
++ u_int8_t i, seg_type, seg_len;
++
++ if (type == ASLEN_MAX) {
++ if (aslen < aspath_count(a->data, a->len))
++ return (1);
++ else
++ return (0);
++ }
+
+- len >>= 2; /* divide by four */
++ /* type == ASLEN_SEQ */
++ seg = a->data;
++ for (len = a->len; len > 0; len -= seg_size, seg += seg_size) {
++ seg_type = seg[0];
++ seg_len = seg[1];
++ seg_size = 2 + sizeof(u_int32_t) * seg_len;
+
+- for (; len > 0; len--) {
++ for (i = 0; i < seg_len; i++) {
++ /* what should we do with AS_SET? */
++ as = aspath_extract(seg, i);
++ if (as == lastas) {
++ if (aslen < ++count)
++ return (1);
++ } else
++ count = 1;
++ lastas = as;
++ }
++ }
++ return (0);
++}
++
+/*
+ * Functions handling communities and extended communities.
+ */
+
+int community_ext_matchone(struct filter_extcommunity *, u_int16_t, u_int64_t);
+
- int
--community_match(void *data, u_int16_t len, int as, int type)
++int
+community_match(struct rde_aspath *asp, int as, int type)
- {
-- u_int8_t *p = data;
-- u_int16_t eas, etype;
++{
+ struct attr *a;
+ u_int8_t *p;
+ u_int16_t eas, etype, len;
-
-- len >>= 2; /* divide by four */
++
+ a = attr_optget(asp, ATTR_COMMUNITIES);
+ if (a == NULL)
+ /* no communities, no match */
+ return (0);
-
-- for (; len > 0; len--) {
++
+ p = a->data;
+ for (len = a->len / 4; len > 0; len--) {
eas = *p++;
eas <<= 8;
eas |= *p++;
-@@ -1000,7 +1018,6 @@ community_set(struct rde_aspath *asp, in
+@@ -1000,7 +1068,6 @@ community_set(struct rde_aspath *asp, in
u_int8_t *p = NULL;
unsigned int i, ncommunities = 0;
u_int8_t f = ATTR_OPTIONAL|ATTR_TRANSITIVE;
@@ -74,7 +179,7 @@ diff -u -p -r1.1.1.6 -r1.5
attr = attr_optget(asp, ATTR_COMMUNITIES);
if (attr != NULL) {
-@@ -1017,7 +1034,7 @@ community_set(struct rde_aspath *asp, in
+@@ -1017,7 +1084,7 @@ community_set(struct rde_aspath *asp, in
p += 4;
}
@@ -83,7 +188,7 @@ diff -u -p -r1.1.1.6 -r1.5
/* overflow */
return (0);
-@@ -1032,11 +1049,10 @@ community_set(struct rde_aspath *asp, in
+@@ -1032,11 +1099,10 @@ community_set(struct rde_aspath *asp, in
if (attr != NULL) {
memcpy(p + 4, attr->data, attr->len);
f = attr->flags;
@@ -96,7 +201,7 @@ diff -u -p -r1.1.1.6 -r1.5
free(p);
return (1);
-@@ -1049,7 +1065,7 @@ community_delete(struct rde_aspath *asp,
+@@ -1049,7 +1115,7 @@ community_delete(struct rde_aspath *asp,
u_int8_t *p, *n;
u_int16_t l, len = 0;
u_int16_t eas, etype;
@@ -105,7 +210,7 @@ diff -u -p -r1.1.1.6 -r1.5
attr = attr_optget(asp, ATTR_COMMUNITIES);
if (attr == NULL)
-@@ -1100,10 +1116,250 @@ community_delete(struct rde_aspath *asp,
+@@ -1100,10 +1166,250 @@ community_delete(struct rde_aspath *asp,
}
f = attr->flags;