summaryrefslogtreecommitdiff
path: root/net/openbgpd/files/patch-bgpd_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openbgpd/files/patch-bgpd_util.c')
-rw-r--r--net/openbgpd/files/patch-bgpd_util.c147
1 files changed, 141 insertions, 6 deletions
diff --git a/net/openbgpd/files/patch-bgpd_util.c b/net/openbgpd/files/patch-bgpd_util.c
index 213c90a2276e..54e74ec9805f 100644
--- a/net/openbgpd/files/patch-bgpd_util.c
+++ b/net/openbgpd/files/patch-bgpd_util.c
@@ -2,10 +2,10 @@ Index: bgpd/util.c
===================================================================
RCS file: /home/cvs/private/hrs/openbgpd/bgpd/util.c,v
retrieving revision 1.1.1.6
-retrieving revision 1.6
-diff -u -p -r1.1.1.6 -r1.6
+retrieving revision 1.7
+diff -u -p -r1.1.1.6 -r1.7
--- bgpd/util.c 14 Feb 2010 20:19:57 -0000 1.1.1.6
-+++ bgpd/util.c 2 Jul 2011 16:06:38 -0000 1.6
++++ bgpd/util.c 13 Oct 2012 18:36:00 -0000 1.7
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.6 2009/06/12 16:42:53 claudio Exp $ */
+/* $OpenBSD: util.c,v 1.11 2010/03/29 09:04:43 claudio Exp $ */
@@ -43,14 +43,14 @@ diff -u -p -r1.1.1.6 -r1.6
+ if (inet_ntop(aid2af(addr->aid), &addr->ba, buf,
+ sizeof(buf)) == NULL)
+ return ("?");
-+ return (buf);
+ return (buf);
+ case AID_VPN_IPv4:
+ if (inet_ntop(AF_INET, &addr->vpn4.addr, tbuf,
+ sizeof(tbuf)) == NULL)
+ return ("?");
+ snprintf(buf, sizeof(buf), "%s %s", log_rd(addr->vpn4.rd),
+ tbuf);
- return (buf);
++ return (buf);
+ }
+ return ("???");
}
@@ -187,7 +187,142 @@ diff -u -p -r1.1.1.6 -r1.6
}
/* ensure that we have a valid C-string especially for empty as path */
if (size > 0)
-@@ -276,3 +376,115 @@ inet6applymask(struct in6_addr *dest, co
+@@ -235,6 +335,67 @@ aspath_strlen(void *data, u_int16_t len)
+ return (total_size);
+ }
+
++/* we need to be able to search more than one as */
++int
++aspath_match(void *data, u_int16_t len, enum as_spec type, u_int32_t as)
++{
++ u_int8_t *seg;
++ int final;
++ u_int16_t seg_size;
++ u_int8_t i, seg_type, seg_len;
++
++ if (type == AS_EMPTY) {
++ if (len == 0)
++ return (1);
++ else
++ return (0);
++ }
++
++ final = 0;
++ seg = data;
++ for (; 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;
++
++ final = (len == seg_size);
++
++ /* just check the first (leftmost) AS */
++ if (type == AS_PEER) {
++ if (as == aspath_extract(seg, 0))
++ return (1);
++ else
++ return (0);
++ }
++ /* just check the final (rightmost) AS */
++ if (type == AS_SOURCE) {
++ /* not yet in the final segment */
++ if (!final)
++ continue;
++
++ if (as == aspath_extract(seg, seg_len - 1))
++ return (1);
++ else
++ return (0);
++ }
++
++ /* AS_TRANSIT or AS_ALL */
++ for (i = 0; i < seg_len; i++) {
++ if (as == aspath_extract(seg, i)) {
++ /*
++ * the source (rightmost) AS is excluded from
++ * AS_TRANSIT matches.
++ */
++ if (final && i == seg_len - 1 &&
++ type == AS_TRANSIT)
++ return (0);
++ return (1);
++ }
++ }
++ }
++ return (0);
++}
++
+ /*
+ * Extract the asnum out of the as segment at the specified position.
+ * Direct access is not possible because of non-aligned reads.
+@@ -251,6 +412,66 @@ aspath_extract(const void *seg, int pos)
+ return (ntohl(as));
+ }
+
++int
++prefix_compare(const struct bgpd_addr *a, const struct bgpd_addr *b,
++ int prefixlen)
++{
++ in_addr_t mask, aa, ba;
++ int i;
++ u_int8_t m;
++
++ if (a->aid != b->aid)
++ return (a->aid - b->aid);
++
++ switch (a->aid) {
++ case AID_INET:
++ if (prefixlen > 32)
++ fatalx("prefix_cmp: bad IPv4 prefixlen");
++ mask = htonl(prefixlen2mask(prefixlen));
++ aa = ntohl(a->v4.s_addr & mask);
++ ba = ntohl(b->v4.s_addr & mask);
++ if (aa != ba)
++ return (aa - ba);
++ return (0);
++ case AID_INET6:
++ if (prefixlen > 128)
++ fatalx("prefix_cmp: bad IPv6 prefixlen");
++ for (i = 0; i < prefixlen / 8; i++)
++ if (a->v6.s6_addr[i] != b->v6.s6_addr[i])
++ return (a->v6.s6_addr[i] - b->v6.s6_addr[i]);
++ i = prefixlen % 8;
++ if (i) {
++ m = 0xff00 >> i;
++ if ((a->v6.s6_addr[prefixlen / 8] & m) !=
++ (b->v6.s6_addr[prefixlen / 8] & m))
++ return ((a->v6.s6_addr[prefixlen / 8] & m) -
++ (b->v6.s6_addr[prefixlen / 8] & m));
++ }
++ return (0);
++ case AID_VPN_IPv4:
++ if (prefixlen > 32)
++ fatalx("prefix_cmp: bad IPv4 VPN prefixlen");
++ if (betoh64(a->vpn4.rd) > betoh64(b->vpn4.rd))
++ return (1);
++ if (betoh64(a->vpn4.rd) < betoh64(b->vpn4.rd))
++ return (-1);
++ mask = htonl(prefixlen2mask(prefixlen));
++ aa = ntohl(a->vpn4.addr.s_addr & mask);
++ ba = ntohl(b->vpn4.addr.s_addr & mask);
++ if (aa != ba)
++ return (aa - ba);
++ if (a->vpn4.labellen > b->vpn4.labellen)
++ return (1);
++ if (a->vpn4.labellen < b->vpn4.labellen)
++ return (-1);
++ return (memcmp(a->vpn4.labelstack, b->vpn4.labelstack,
++ a->vpn4.labellen));
++ default:
++ fatalx("prefix_cmp: unknown af");
++ }
++ return (-1);
++}
++
+ in_addr_t
+ prefixlen2mask(u_int8_t prefixlen)
+ {
+@@ -276,3 +497,115 @@ inet6applymask(struct in6_addr *dest, co
for (i = 0; i < 16; i++)
dest->s6_addr[i] = src->s6_addr[i] & mask.s6_addr[i];
}