diff options
author | Hiroki Sato <hrs@FreeBSD.org> | 2010-02-16 19:27:03 +0000 |
---|---|---|
committer | Hiroki Sato <hrs@FreeBSD.org> | 2010-02-16 19:27:03 +0000 |
commit | 7ab9a19af615666cef45e1b4538c8460d19e1ec0 (patch) | |
tree | 301a68c22691daf3b616754a383cd1730c23dae7 /net/openbgpd/files/patch-bgpd_rde_prefix.c | |
parent | Add updating instructions for sysutils/bacula-{server,client}. (diff) |
Update to 4.6.20100215.
Feature safe: yes
Notes
Notes:
svn path=/head/; revision=249966
Diffstat (limited to 'net/openbgpd/files/patch-bgpd_rde_prefix.c')
-rw-r--r-- | net/openbgpd/files/patch-bgpd_rde_prefix.c | 498 |
1 files changed, 230 insertions, 268 deletions
diff --git a/net/openbgpd/files/patch-bgpd_rde_prefix.c b/net/openbgpd/files/patch-bgpd_rde_prefix.c index 60093010f27a..7df1c4ee65e0 100644 --- a/net/openbgpd/files/patch-bgpd_rde_prefix.c +++ b/net/openbgpd/files/patch-bgpd_rde_prefix.c @@ -1,332 +1,294 @@ Index: bgpd/rde_prefix.c =================================================================== RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde_prefix.c,v -retrieving revision 1.1.1.1 -retrieving revision 1.3 -diff -u -p -r1.1.1.1 -r1.3 ---- bgpd/rde_prefix.c 30 Jun 2009 05:46:15 -0000 1.1.1.1 -+++ bgpd/rde_prefix.c 9 Jul 2009 17:22:14 -0000 1.3 +retrieving revision 1.1.1.6 +retrieving revision 1.4 +diff -u -p -r1.1.1.6 -r1.4 +--- bgpd/rde_prefix.c 14 Feb 2010 20:19:57 -0000 1.1.1.6 ++++ bgpd/rde_prefix.c 4 Feb 2010 16:22:23 -0000 1.4 @@ -1,4 +1,4 @@ --/* $OpenBSD: rde_prefix.c,v 1.25 2007/05/11 11:27:59 claudio Exp $ */ -+/* $OpenBSD: rde_prefix.c,v 1.29 2009/05/30 18:27:17 claudio Exp $ */ +-/* $OpenBSD: rde_prefix.c,v 1.29 2009/05/30 18:27:17 claudio Exp $ */ ++/* $OpenBSD: rde_prefix.c,v 1.31 2010/01/13 06:02:37 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> -@@ -40,46 +40,30 @@ +@@ -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_alloc: allocate a AF specific pt_entry. Internal function. * pt_free: free a pt_entry. Internal function. -- * pt_restart used to restart a tree walk at the spot it was aborted earlier. */ /* internal prototypes */ - static struct pt_entry4 *pt_alloc4(void); - static struct pt_entry6 *pt_alloc6(void); +-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 *); --static struct pt_entry *pt_restart(struct pt_context *); --int pt_prefix_cmp(const struct pt_entry *, const struct pt_entry *); -- --#define MIN_PREFIX 0 --#define MAX_PREFIX 32 ++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); - --struct pt_tree pttable4; --struct pt_tree pttable6; -+struct pt_tree pttable; - - void - pt_init(void) +@@ -70,17 +71,24 @@ void + pt_getaddr(struct pt_entry *pte, struct bgpd_addr *addr) { -- RB_INIT(&pttable4); -- RB_INIT(&pttable6); -+ RB_INIT(&pttable); - } - - void - pt_shutdown(void) - { -- if (!RB_EMPTY(&pttable4)) -- log_debug("pt_shutdown: IPv4 tree is not empty."); -- if (!RB_EMPTY(&pttable6)) -- log_debug("pt_shutdown: IPv6 tree is not empty."); --} -- --int --pt_empty(struct pt_entry *pte) --{ -- return LIST_EMPTY(&pte->prefix_h); -+ if (!RB_EMPTY(&pttable)) -+ log_debug("pt_shutdown: tree is not empty."); - } - - void -@@ -103,14 +87,15 @@ pt_getaddr(struct pt_entry *pte, struct - } - + 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 ??? */ + break; ++ case AID_VPN_IPv4: ++ addr->vpn4.addr = ((struct pt_entry_vpn4 *)pte)->prefix4; ++ addr->vpn4.rd = ((struct pt_entry_vpn4 *)pte)->rd; ++ addr->vpn4.labellen = ((struct pt_entry_vpn4 *)pte)->labellen; ++ memcpy(addr->vpn4.labelstack, ++ ((struct pt_entry_vpn4 *)pte)->labelstack, ++ addr->vpn4.labellen); ++ break; + default: + fatalx("pt_getaddr: unknown af"); + } +@@ -89,33 +97,49 @@ pt_getaddr(struct pt_entry *pte, struct struct pt_entry * --pt_get(struct bgpd_addr *prefix, int prefixlen) -+pt_fill(struct bgpd_addr *prefix, int prefixlen) + pt_fill(struct bgpd_addr *prefix, int prefixlen) { -- struct pt_entry4 pte4; -- struct pt_entry6 pte6; -+ static struct pt_entry4 pte4; -+ static struct pt_entry6 pte6; - in_addr_t addr_hbo; +- static struct pt_entry4 pte4; +- static struct pt_entry6 pte6; +- in_addr_t addr_hbo; ++ static struct pt_entry4 pte4; ++ static struct pt_entry6 pte6; ++ static struct pt_entry_vpn4 pte_vpn4; ++ in_addr_t addr_hbo; - switch (prefix->af) { - case AF_INET: -+ bzero(&pte4, sizeof(pte4)); +- switch (prefix->af) { +- case AF_INET: ++ switch (prefix->aid) { ++ case AID_INET: + bzero(&pte4, sizeof(pte4)); ++ pte4.aid = prefix->aid; if (prefixlen > 32) - fatalx("pt_get: bad IPv4 prefixlen"); - pte4.af = AF_INET; -@@ -118,24 +103,33 @@ pt_get(struct bgpd_addr *prefix, int pre +- 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 RB_FIND(pt_tree, &pttable4, (struct pt_entry *)&pte4); -+ return ((struct pt_entry *)&pte4); - case AF_INET6: -+ bzero(&pte6, sizeof(pte6)); + return ((struct pt_entry *)&pte4); +- case AF_INET6: ++ case AID_INET6: + bzero(&pte6, sizeof(pte6)); ++ pte6.aid = prefix->aid; if (prefixlen > 128) fatalx("pt_get: bad IPv6 prefixlen"); - pte6.af = AF_INET6; +- pte6.af = AF_INET6; pte6.prefixlen = prefixlen; inet6applymask(&pte6.prefix6, &prefix->v6, prefixlen); -- return RB_FIND(pt_tree, &pttable6, (struct pt_entry *)&pte6); -+ return ((struct pt_entry *)&pte6); + return ((struct pt_entry *)&pte6); ++ case AID_VPN_IPv4: ++ bzero(&pte_vpn4, sizeof(pte_vpn4)); ++ pte_vpn4.aid = prefix->aid; ++ if (prefixlen > 32) ++ fatalx("pt_fill: bad IPv4 prefixlen"); ++ addr_hbo = ntohl(prefix->vpn4.addr.s_addr); ++ pte_vpn4.prefix4.s_addr = htonl(addr_hbo & ++ prefixlen2mask(prefixlen)); ++ pte_vpn4.prefixlen = prefixlen; ++ pte_vpn4.rd = prefix->vpn4.rd; ++ pte_vpn4.labellen = prefix->vpn4.labellen; ++ memcpy(pte_vpn4.labelstack, prefix->vpn4.labelstack, ++ prefix->vpn4.labellen); ++ return ((struct pt_entry *)&pte_vpn4); default: - log_warnx("pt_get: unknown af"); -+ return (NULL); +- log_warnx("pt_get: unknown af"); +- return (NULL); ++ fatalx("pt_fill: unknown af"); } -- return (NULL); -+} -+ -+struct pt_entry * -+pt_get(struct bgpd_addr *prefix, int prefixlen) -+{ -+ struct pt_entry *pte; -+ -+ pte = pt_fill(prefix, prefixlen); -+ return RB_FIND(pt_tree, &pttable, pte); ++ /* NOT REACHED */ ++ return (NULL); } struct pt_entry * +@@ -131,34 +155,9 @@ struct pt_entry * pt_add(struct bgpd_addr *prefix, int prefixlen) { -- struct pt_tree *tree = NULL; struct pt_entry *p = NULL; - struct pt_entry4 *p4; - struct pt_entry6 *p6; -@@ -152,7 +146,6 @@ pt_add(struct bgpd_addr *prefix, int pre - p4->prefix4.s_addr = htonl(addr_hbo & - prefixlen2mask(prefixlen)); - p = (struct pt_entry *)p4; -- tree = &pttable4; - break; - case AF_INET6: - p6 = pt_alloc6(); -@@ -162,15 +155,13 @@ pt_add(struct bgpd_addr *prefix, int pre - p6->prefixlen = prefixlen; - inet6applymask(&p6->prefix6, &prefix->v6, prefixlen); - p = (struct pt_entry *)p6; -- tree = &pttable6; - break; - default: - fatalx("pt_add: unknown af"); - } -- LIST_INIT(&p->prefix_h); - -- if (RB_INSERT(pt_tree, tree, p) != NULL) { -- log_warnx("prefix_add: insert failed"); -+ if (RB_INSERT(pt_tree, &pttable, p) != NULL) { -+ log_warnx("pt_add: insert failed"); - return (NULL); - } - -@@ -181,101 +172,35 @@ void - pt_remove(struct pt_entry *pte) - { - if (!pt_empty(pte)) -- fatalx("pt_remove: entry not empty"); +- struct pt_entry4 *p4; +- struct pt_entry6 *p6; +- in_addr_t addr_hbo; - -- switch (pte->af) { +- switch (prefix->af) { - case AF_INET: -- if (RB_REMOVE(pt_tree, &pttable4, pte) == NULL) -- log_warnx("pt_remove: remove failed."); +- 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: -- if (RB_REMOVE(pt_tree, &pttable6, pte) == NULL) -- log_warnx("pt_remove: remove failed."); +- 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_remove: unknown af"); +- fatalx("pt_add: unknown af"); - } -+ fatalx("pt_remove: entry still holds references"); - -+ if (RB_REMOVE(pt_tree, &pttable, pte) == NULL) -+ log_warnx("pt_remove: remove failed."); - pt_free(pte); - } ++ ++ p = pt_fill(prefix, prefixlen); ++ p = pt_alloc(p); - struct pt_entry * --pt_lookup(struct bgpd_addr *prefix) -+pt_lookup(struct bgpd_addr *addr) + if (RB_INSERT(pt_tree, &pttable, p) != NULL) { + log_warnx("pt_add: insert failed"); +@@ -183,13 +182,14 @@ struct pt_entry * + pt_lookup(struct bgpd_addr *addr) { struct pt_entry *p; - int i; +- int i; ++ int i = 0; -- switch (prefix->af) { -+ switch (addr->af) { - case AF_INET: -- for (i = 32; i >= 0; i--) { -- p = pt_get(prefix, i); -- if (p != NULL) -- return (p); -- } -+ i = 32; +- switch (addr->af) { +- case AF_INET: ++ switch (addr->aid) { ++ case AID_INET: ++ case AID_VPN_IPv4: + i = 32; break; - case AF_INET6: -- for (i = 128; i >= 0; i--) { -- p = pt_get(prefix, i); -- if (p != NULL) -- return (p); -- } -+ i = 128; +- case AF_INET6: ++ case AID_INET6: + i = 128; break; default: - fatalx("pt_lookup: unknown af"); - } -- return (NULL); --} -- --void --pt_dump(void (*upcall)(struct pt_entry *, void *), void *arg, sa_family_t af) --{ -- if (af == AF_INET || af == AF_UNSPEC) -- pt_dump_r(upcall, arg, AF_INET, NULL); -- if (af == AF_INET6 || af == AF_UNSPEC) -- pt_dump_r(upcall, arg, AF_INET6, NULL); --} -- --void --pt_dump_r(void (*upcall)(struct pt_entry *, void *), void *arg, -- sa_family_t af, struct pt_context *ctx) --{ -- struct pt_entry *p; -- unsigned int i; -- -- if (ctx == NULL || ctx->ctx_p.af != af) { -- switch (af) { -- case AF_INET: -- p = RB_MIN(pt_tree, &pttable4); -- break; -- case AF_INET6: -- p = RB_MIN(pt_tree, &pttable6); -- break; -- default: -- return; -- } -- } else -- p = pt_restart(ctx); -- -- for (i = 0; p != NULL; p = RB_NEXT(pt_tree, unused, p)) { -- if (ctx && i++ >= ctx->count) { -- /* store next start point */ -- switch (p->af) { -- case AF_INET: -- ctx->ctx_p4 = *(struct pt_entry4 *)p; -- break; -- case AF_INET6: -- ctx->ctx_p6 = *(struct pt_entry6 *)p; -- break; -- default: -- fatalx("pt_dump_r: unknown af"); -- } -- return; -- } -- upcall(p, arg); -+ for (; i >= 0; i--) { -+ p = pt_get(addr, i); -+ if (p != NULL) -+ return (p); - } -- -- if (ctx) -- ctx->done = 1; -+ return (NULL); - } - +@@ -206,17 +206,18 @@ pt_lookup(struct bgpd_addr *addr) int -@@ -285,8 +210,10 @@ pt_prefix_cmp(const struct pt_entry *a, - const struct pt_entry6 *a6, *b6; - int i; + pt_prefix_cmp(const struct pt_entry *a, const struct pt_entry *b) + { +- const struct pt_entry4 *a4, *b4; +- const struct pt_entry6 *a6, *b6; +- int i; ++ const struct pt_entry4 *a4, *b4; ++ const struct pt_entry6 *a6, *b6; ++ const struct pt_entry_vpn4 *va4, *vb4; ++ int i; -- if (a->af != b->af) -- fatalx("king bula sez: comparing pears with apples"); -+ if (a->af > b->af) -+ return (1); -+ if (a->af < b->af) -+ return (-1); +- 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: -@@ -361,56 +288,3 @@ pt_free(struct pt_entry *pte) +- 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 +229,7 @@ pt_prefix_cmp(const struct pt_entry *a, + 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; + +@@ -242,49 +243,49 @@ pt_prefix_cmp(const struct pt_entry *a, + if (a6->prefixlen > b6->prefixlen) + return (1); + return (0); ++ case AID_VPN_IPv4: ++ va4 = (const struct pt_entry_vpn4 *)a; ++ vb4 = (const struct pt_entry_vpn4 *)b; ++ if (ntohl(va4->prefix4.s_addr) > ntohl(vb4->prefix4.s_addr)) ++ return (1); ++ if (ntohl(va4->prefix4.s_addr) < ntohl(vb4->prefix4.s_addr)) ++ return (-1); ++ if (va4->prefixlen > vb4->prefixlen) ++ return (1); ++ if (va4->prefixlen < vb4->prefixlen) ++ return (-1); ++ if (betoh64(va4->rd) > betoh64(vb4->rd)) ++ return (1); ++ if (betoh64(va4->rd) < betoh64(vb4->rd)) ++ return (-1); ++ return (0); + default: + fatalx("pt_prefix_cmp: unknown af"); } - free(pte); + return (-1); } -- --static struct pt_entry * --pt_restart(struct pt_context *ctx) + +-/* 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); +-} ++ rdemem.pt_cnt[op->aid]++; ++ memcpy(p, op, pt_sizes[op->aid]); + +-static struct pt_entry6 * +-pt_alloc6(void) -{ -- struct pt_entry *tmp, *prev = NULL; -- int comp; +- struct pt_entry6 *p; - -- /* first select correct tree */ -- switch (ctx->ctx_p.af) { +- 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: -- tmp = RB_ROOT(&pttable4); +- rdemem.pt4_cnt--; - break; - case AF_INET6: -- tmp = RB_ROOT(&pttable6); +- rdemem.pt6_cnt--; - break; - default: -- fatalx("pt_restart: unknown af"); -- } -- -- /* then try to find the element */ -- while (tmp) { -- prev = tmp; -- comp = pt_prefix_cmp(&ctx->ctx_p, tmp); -- if (comp < 0) -- tmp = RB_LEFT(tmp, pt_e); -- else if (comp > 0) -- tmp = RB_RIGHT(tmp, pt_e); -- else -- return (tmp); +- break; - } -- -- /* no match, empty tree */ -- if (prev == NULL) -- return (NULL); -- -- /* -- * no perfect match -- * if last element was bigger use that as new start point -- */ -- if (comp < 0) -- return (prev); -- -- /* backtrack until parent is bigger */ -- do { -- prev = RB_PARENT(prev, pt_e); -- if (prev == NULL) -- /* all elements in the tree are smaler */ -- return (NULL); -- comp = pt_prefix_cmp(&ctx->ctx_p, prev); -- } while (comp > 0); -- -- return (prev); --} ++ rdemem.pt_cnt[pte->aid]--; + free(pte); + } |