aboutsummaryrefslogtreecommitdiff
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.c137
1 files changed, 121 insertions, 16 deletions
diff --git a/net/openbgpd/files/patch-bgpd_rde_attr.c b/net/openbgpd/files/patch-bgpd_rde_attr.c
index 7aa74567837d..f62d59f083f0 100644
--- a/net/openbgpd/files/patch-bgpd_rde_attr.c
+++ b/net/openbgpd/files/patch-bgpd_rde_attr.c
@@ -2,13 +2,13 @@ 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.4
-diff -u -p -r1.1.1.6 -r1.4
+retrieving revision 1.5
+diff -u -p -r1.1.1.6 -r1.5
--- bgpd/rde_attr.c 14 Feb 2010 20:19:57 -0000 1.1.1.6
-+++ bgpd/rde_attr.c 4 Feb 2010 16:22:23 -0000 1.4
++++ bgpd/rde_attr.c 10 Apr 2010 12:16:23 -0000 1.5
@@ -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.81 2009/12/18 15:51:37 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>
@@ -34,7 +34,7 @@ diff -u -p -r1.1.1.6 -r1.4
#include "bgpd.h"
#include "rde.h"
-@@ -971,13 +978,26 @@ aspath_match(struct aspath *a, enum as_s
+@@ -971,15 +978,26 @@ aspath_match(struct aspath *a, enum as_s
return (0);
}
@@ -42,7 +42,7 @@ diff -u -p -r1.1.1.6 -r1.4
+ * Functions handling communities and extended communities.
+ */
+
-+int community_ext_conv(struct filter_extcommunity *, u_int16_t, u_int64_t *);
++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)
@@ -59,13 +59,14 @@ diff -u -p -r1.1.1.6 -r1.4
+ if (a == NULL)
+ /* no communities, no match */
+ return (0);
-+
-+ len = a->len / 4;
-+ p = a->data;
- for (; len > 0; len--) {
+- for (; len > 0; len--) {
++ p = a->data;
++ for (len = a->len / 4; len > 0; len--) {
eas = *p++;
-@@ -1000,7 +1020,6 @@ community_set(struct rde_aspath *asp, in
+ eas <<= 8;
+ eas |= *p++;
+@@ -1000,7 +1018,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;
@@ -73,7 +74,7 @@ diff -u -p -r1.1.1.6 -r1.4
attr = attr_optget(asp, ATTR_COMMUNITIES);
if (attr != NULL) {
-@@ -1017,7 +1036,7 @@ community_set(struct rde_aspath *asp, in
+@@ -1017,7 +1034,7 @@ community_set(struct rde_aspath *asp, in
p += 4;
}
@@ -82,7 +83,7 @@ diff -u -p -r1.1.1.6 -r1.4
/* overflow */
return (0);
-@@ -1032,11 +1051,10 @@ community_set(struct rde_aspath *asp, in
+@@ -1032,11 +1049,10 @@ community_set(struct rde_aspath *asp, in
if (attr != NULL) {
memcpy(p + 4, attr->data, attr->len);
f = attr->flags;
@@ -95,7 +96,7 @@ diff -u -p -r1.1.1.6 -r1.4
free(p);
return (1);
-@@ -1049,7 +1067,7 @@ community_delete(struct rde_aspath *asp,
+@@ -1049,7 +1065,7 @@ community_delete(struct rde_aspath *asp,
u_int8_t *p, *n;
u_int16_t l, len = 0;
u_int16_t eas, etype;
@@ -104,7 +105,7 @@ diff -u -p -r1.1.1.6 -r1.4
attr = attr_optget(asp, ATTR_COMMUNITIES);
if (attr == NULL)
-@@ -1100,10 +1118,146 @@ community_delete(struct rde_aspath *asp,
+@@ -1100,10 +1116,250 @@ community_delete(struct rde_aspath *asp,
}
f = attr->flags;
@@ -117,6 +118,31 @@ diff -u -p -r1.1.1.6 -r1.4
+}
+
+int
++community_ext_match(struct rde_aspath *asp, struct filter_extcommunity *c,
++ u_int16_t neighas)
++{
++ struct attr *attr;
++ u_int8_t *p;
++ u_int64_t ec;
++ u_int16_t len;
++
++ attr = attr_optget(asp, ATTR_EXT_COMMUNITIES);
++ if (attr == NULL)
++ /* no communities, no match */
++ return (0);
++
++ p = attr->data;
++ for (len = attr->len / sizeof(ec); len > 0; len--) {
++ memcpy(&ec, p, sizeof(ec));
++ if (community_ext_matchone(c, neighas, ec))
++ return (1);
++ p += sizeof(ec);
++ }
++
++ return (0);
++}
++
++int
+community_ext_set(struct rde_aspath *asp, struct filter_extcommunity *c,
+ u_int16_t neighas)
+{
@@ -132,7 +158,7 @@ diff -u -p -r1.1.1.6 -r1.4
+ attr = attr_optget(asp, ATTR_EXT_COMMUNITIES);
+ if (attr != NULL) {
+ p = attr->data;
-+ ncommunities = attr->len / 8; /* 64bit per ext-community */
++ ncommunities = attr->len / sizeof(community);
+ }
+
+ /* first check if the community is not already set */
@@ -253,3 +279,82 @@ diff -u -p -r1.1.1.6 -r1.4
+
+ return (0);
+}
++
++int
++community_ext_matchone(struct filter_extcommunity *c, u_int16_t neighas,
++ u_int64_t community)
++{
++ u_int64_t com, mask;
++ u_int32_t ip;
++
++ community = betoh64(community);
++
++ com = (u_int64_t)c->type << 56;
++ mask = 0xffULL << 56;
++ if ((com & mask) != (community & mask))
++ return (0);
++
++ switch (c->type & EXT_COMMUNITY_VALUE) {
++ case EXT_COMMUNITY_TWO_AS:
++ case EXT_COMMUNITY_IPV4:
++ case EXT_COMMUNITY_FOUR_AS:
++ case EXT_COMMUNITY_OPAQUE:
++ com = (u_int64_t)c->subtype << 48;
++ mask = 0xffULL << 48;
++ if ((com & mask) != (community & mask))
++ return (0);
++ break;
++ default:
++ com = c->data.ext_opaq & 0xffffffffffffffULL;
++ mask = 0xffffffffffffffULL;
++ if ((com & mask) == (community & mask))
++ return (1);
++ return (0);
++ }
++
++
++ switch (c->type & EXT_COMMUNITY_VALUE) {
++ case EXT_COMMUNITY_TWO_AS:
++ com = (u_int64_t)c->data.ext_as.as << 32;
++ mask = 0xffffULL << 32;
++ if ((com & mask) != (community & mask))
++ return (0);
++
++ com = c->data.ext_as.val;
++ mask = 0xffffffffULL;
++ if ((com & mask) == (community & mask))
++ return (1);
++ break;
++ case EXT_COMMUNITY_IPV4:
++ ip = ntohl(c->data.ext_ip.addr.s_addr);
++ com = (u_int64_t)ip << 16;
++ mask = 0xffffffff0000ULL;
++ if ((com & mask) != (community & mask))
++ return (0);
++
++ com = c->data.ext_ip.val;
++ mask = 0xffff;
++ if ((com & mask) == (community & mask))
++ return (1);
++ break;
++ case EXT_COMMUNITY_FOUR_AS:
++ com = (u_int64_t)c->data.ext_as4.as4 << 16;
++ mask = 0xffffffffULL << 16;
++ if ((com & mask) != (community & mask))
++ return (0);
++
++ com = c->data.ext_as4.val;
++ mask = 0xffff;
++ if ((com & mask) == (community & mask))
++ return (1);
++ break;
++ case EXT_COMMUNITY_OPAQUE:
++ com = c->data.ext_opaq & EXT_COMMUNITY_OPAQUE_MAX;
++ mask = EXT_COMMUNITY_OPAQUE_MAX;
++ if ((com & mask) == (community & mask))
++ return (1);
++ break;
++ }
++
++ return (0);
++}