diff options
author | Claudio Jeker <claudio@cvs.openbsd.org> | 2004-06-22 20:28:59 +0000 |
---|---|---|
committer | Claudio Jeker <claudio@cvs.openbsd.org> | 2004-06-22 20:28:59 +0000 |
commit | 6fea9855664583f52deafa42b35f7320cad8da93 (patch) | |
tree | 03958bbe9997531e60137428ca3852b1405c29eb /usr.sbin/bgpd/kroute.c | |
parent | 73fe7b61cd58457249a00cb41a0673dc5db8bbaa (diff) |
Make the RDE IPv6 ready missing is the message handling. The internal
prefix tree changed form a hash table to a per AF RB tree.
OK henning@ some ideas are from Brent Graveland.
Diffstat (limited to 'usr.sbin/bgpd/kroute.c')
-rw-r--r-- | usr.sbin/bgpd/kroute.c | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/usr.sbin/bgpd/kroute.c b/usr.sbin/bgpd/kroute.c index d2440c8ee44..07a152c78ac 100644 --- a/usr.sbin/bgpd/kroute.c +++ b/usr.sbin/bgpd/kroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kroute.c,v 1.97 2004/06/22 07:22:31 henning Exp $ */ +/* $OpenBSD: kroute.c,v 1.98 2004/06/22 20:28:58 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org> @@ -98,7 +98,6 @@ void kroute_detach_nexthop(struct knexthop_node *); int protect_lo(void); u_int8_t prefixlen_classful(in_addr_t); u_int8_t mask2prefixlen(in_addr_t); -in_addr_t prefixlen2mask(u_int8_t); void get_rtaddrs(int, struct sockaddr *, struct sockaddr **); void if_change(u_short, int, struct if_data *); void if_announce(void *); @@ -817,6 +816,60 @@ prefixlen2mask(u_int8_t prefixlen) return (0xffffffff << (32 - prefixlen)); } +int +prefix_equal(const struct bgpd_addr *a, const struct bgpd_addr *b, + int prefixlen) +{ + in_addr_t mask; + int i; + u_int8_t m; + + if (a->af != b->af) + return 0; + switch (a->af) { + case AF_INET: + if (prefixlen > 32) + fatalx("prefix_cmp: bad IPv4 prefixlen"); + mask = htonl(prefixlen2mask(prefixlen)); + if ((a->v4.s_addr & mask) == (b->v4.s_addr & mask)) + return (1); + else + return (0); + case AF_INET6: + for (i = 0; i < prefixlen / 8; i++) + if (a->v6.s6_addr[i] != b->v6.s6_addr[i]) + return (0); + i = prefixlen % 8; + if (i) { + m = 0xff00 >> i; + if ((a->v6.s6_addr[prefixlen / 8] & m) != + (b->v6.s6_addr[prefixlen / 8] & m)) + return (0); + } + return (1); + default: + fatalx("prefix_cmp: unknown af"); + } + return (0); +} + +void +inet6applymask(struct in6_addr *dest, const struct in6_addr *src, int prefixlen) +{ + struct in6_addr mask; + int i; + + bzero(&mask, sizeof(mask)); + for (i = 0; i < prefixlen / 8; i++) + mask.s6_addr[i] = 0xff; + i = prefixlen % 8; + if (i) + mask.s6_addr[prefixlen / 8] = 0xff00 >> i; + + for (i = 0; i < 16; i++) + dest->s6_addr[i] = src->s6_addr[i] & mask.s6_addr[i]; +} + #define ROUNDUP(a, size) \ (((a) & ((size) - 1)) ? (1 + ((a) | ((size) - 1))) : (a)) |