summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd/rde_prefix.c
diff options
context:
space:
mode:
authorClaudio Jeker <claudio@cvs.openbsd.org>2009-12-01 14:28:06 +0000
committerClaudio Jeker <claudio@cvs.openbsd.org>2009-12-01 14:28:06 +0000
commitd34d8813c5fa9b8031432c45c008b3a7a0d97441 (patch)
tree55c9c7d433f909d1af59bc9e1671cee07a80c7c3 /usr.sbin/bgpd/rde_prefix.c
parentd2eb742e2cf480aa441fc39d7cec70b5c3e71ca6 (diff)
Use an artificial address family id in struct bgpd_addr and almost everywhere
else. Adds conversion functions to map AFI/SAFI and the Unix AF_ values from and into AID used in bgpd. This is needed to support things like MPLS VPN and other upcomming changes that need to play a lot with AFI/SAFI pairs. Mostly mechanical change, henning@ has no particular issues with this. Must go in so that I can continue working.
Diffstat (limited to 'usr.sbin/bgpd/rde_prefix.c')
-rw-r--r--usr.sbin/bgpd/rde_prefix.c117
1 files changed, 39 insertions, 78 deletions
diff --git a/usr.sbin/bgpd/rde_prefix.c b/usr.sbin/bgpd/rde_prefix.c
index 0c8e211f688..019e8123464 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.29 2009/05/30 18:27:17 claudio Exp $ */
+/* $OpenBSD: rde_prefix.c,v 1.30 2009/12/01 14:28:05 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
@@ -38,15 +38,16 @@
* pt_lookup: lookup a IP in the prefix table. Mainly for "show ip bgp".
* pt_empty: returns true if there is no bgp prefix linked to the pt_entry.
* pt_init: initialize prefix table.
- * pt_alloc?: allocate a AF specific pt_entry. Internal function.
+ * pt_alloc: allocate a AF specific pt_entry. Internal function.
* pt_free: free a pt_entry. Internal function.
*/
/* internal prototypes */
-static struct pt_entry4 *pt_alloc4(void);
-static struct pt_entry6 *pt_alloc6(void);
+static struct pt_entry *pt_alloc(struct pt_entry *);
static void pt_free(struct pt_entry *);
+size_t pt_sizes[AID_MAX] = AID_PTSIZE;
+
RB_HEAD(pt_tree, pt_entry);
RB_PROTOTYPE(pt_tree, pt_entry, pt_e, pt_prefix_cmp);
RB_GENERATE(pt_tree, pt_entry, pt_e, pt_prefix_cmp);
@@ -70,13 +71,12 @@ void
pt_getaddr(struct pt_entry *pte, struct bgpd_addr *addr)
{
bzero(addr, sizeof(struct bgpd_addr));
- switch (pte->af) {
- case AF_INET:
- addr->af = pte->af;
+ addr->aid = pte->aid;
+ switch (addr->aid) {
+ case AID_INET:
addr->v4 = ((struct pt_entry4 *)pte)->prefix4;
break;
- case AF_INET6:
- addr->af = pte->af;
+ case AID_INET6:
memcpy(&addr->v6, &((struct pt_entry6 *)pte)->prefix6,
sizeof(addr->v6));
/* XXX scope_id ??? */
@@ -93,27 +93,29 @@ pt_fill(struct bgpd_addr *prefix, int prefixlen)
static struct pt_entry6 pte6;
in_addr_t addr_hbo;
- switch (prefix->af) {
- case AF_INET:
+ switch (prefix->aid) {
+ case AID_INET:
bzero(&pte4, sizeof(pte4));
+ if (af2aid(AF_INET, 0, &pte4.aid))
+ fatalx("pt_fill: unknown aid");
if (prefixlen > 32)
- fatalx("pt_get: bad IPv4 prefixlen");
- pte4.af = AF_INET;
+ fatalx("pt_fill: bad IPv4 prefixlen");
addr_hbo = ntohl(prefix->v4.s_addr);
pte4.prefix4.s_addr = htonl(addr_hbo &
prefixlen2mask(prefixlen));
pte4.prefixlen = prefixlen;
return ((struct pt_entry *)&pte4);
- case AF_INET6:
+ case AID_INET6:
bzero(&pte6, sizeof(pte6));
+ if (af2aid(AF_INET6, 0, &pte6.aid))
+ fatalx("pt_fill: unknown aid");
if (prefixlen > 128)
fatalx("pt_get: bad IPv6 prefixlen");
- pte6.af = AF_INET6;
pte6.prefixlen = prefixlen;
inet6applymask(&pte6.prefix6, &prefix->v6, prefixlen);
return ((struct pt_entry *)&pte6);
default:
- log_warnx("pt_get: unknown af");
+ log_warnx("pt_fill: unknown af");
return (NULL);
}
}
@@ -131,34 +133,9 @@ struct pt_entry *
pt_add(struct bgpd_addr *prefix, int prefixlen)
{
struct pt_entry *p = NULL;
- struct pt_entry4 *p4;
- struct pt_entry6 *p6;
- in_addr_t addr_hbo;
- switch (prefix->af) {
- case AF_INET:
- p4 = pt_alloc4();
- if (prefixlen > 32)
- fatalx("pt_add: bad IPv4 prefixlen");
- p4->af = AF_INET;
- p4->prefixlen = prefixlen;
- addr_hbo = ntohl(prefix->v4.s_addr);
- p4->prefix4.s_addr = htonl(addr_hbo &
- prefixlen2mask(prefixlen));
- p = (struct pt_entry *)p4;
- break;
- case AF_INET6:
- p6 = pt_alloc6();
- if (prefixlen > 128)
- fatalx("pt_add: bad IPv6 prefixlen");
- p6->af = AF_INET6;
- p6->prefixlen = prefixlen;
- inet6applymask(&p6->prefix6, &prefix->v6, prefixlen);
- p = (struct pt_entry *)p6;
- break;
- default:
- fatalx("pt_add: unknown af");
- }
+ p = pt_fill(prefix, prefixlen);
+ p = pt_alloc(p);
if (RB_INSERT(pt_tree, &pttable, p) != NULL) {
log_warnx("pt_add: insert failed");
@@ -185,11 +162,11 @@ pt_lookup(struct bgpd_addr *addr)
struct pt_entry *p;
int i;
- switch (addr->af) {
- case AF_INET:
+ switch (addr->aid) {
+ case AID_INET:
i = 32;
break;
- case AF_INET6:
+ case AID_INET6:
i = 128;
break;
default:
@@ -210,13 +187,13 @@ pt_prefix_cmp(const struct pt_entry *a, const struct pt_entry *b)
const struct pt_entry6 *a6, *b6;
int i;
- if (a->af > b->af)
+ if (a->aid > b->aid)
return (1);
- if (a->af < b->af)
+ if (a->aid < b->aid)
return (-1);
- switch (a->af) {
- case AF_INET:
+ switch (a->aid) {
+ case AID_INET:
a4 = (const struct pt_entry4 *)a;
b4 = (const struct pt_entry4 *)b;
if (ntohl(a4->prefix4.s_addr) > ntohl(b4->prefix4.s_addr))
@@ -228,7 +205,7 @@ pt_prefix_cmp(const struct pt_entry *a, const struct pt_entry *b)
if (a4->prefixlen < b4->prefixlen)
return (-1);
return (0);
- case AF_INET6:
+ case AID_INET6:
a6 = (const struct pt_entry6 *)a;
b6 = (const struct pt_entry6 *)b;
@@ -248,43 +225,27 @@ pt_prefix_cmp(const struct pt_entry *a, const struct pt_entry *b)
return (-1);
}
-/* returns a zeroed pt_entry function may not return on fail */
-static struct pt_entry4 *
-pt_alloc4(void)
+/*
+ * Returns a pt_entry cloned from the one passed in.
+ * Function may not return on failure.
+ */
+static struct pt_entry *
+pt_alloc(struct pt_entry *op)
{
- struct pt_entry4 *p;
+ struct pt_entry *p;
- p = calloc(1, sizeof(*p));
+ p = malloc(pt_sizes[op->aid]);
if (p == NULL)
fatal("pt_alloc");
- rdemem.pt4_cnt++;
- return (p);
-}
-
-static struct pt_entry6 *
-pt_alloc6(void)
-{
- struct pt_entry6 *p;
+ rdemem.pt_cnt[op->aid]++;
+ memcpy(p, op, pt_sizes[op->aid]);
- p = calloc(1, sizeof(*p));
- if (p == NULL)
- fatal("pt_alloc");
- rdemem.pt6_cnt++;
return (p);
}
static void
pt_free(struct pt_entry *pte)
{
- switch (pte->af) {
- case AF_INET:
- rdemem.pt4_cnt--;
- break;
- case AF_INET6:
- rdemem.pt6_cnt--;
- break;
- default:
- break;
- }
+ rdemem.pt_cnt[pte->aid]--;
free(pte);
}