summaryrefslogtreecommitdiff
path: root/net/openbgpd/files/patch-bgpd_rde_prefix.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/openbgpd/files/patch-bgpd_rde_prefix.c')
-rw-r--r--net/openbgpd/files/patch-bgpd_rde_prefix.c301
1 files changed, 301 insertions, 0 deletions
diff --git a/net/openbgpd/files/patch-bgpd_rde_prefix.c b/net/openbgpd/files/patch-bgpd_rde_prefix.c
new file mode 100644
index 000000000000..daea5cf62272
--- /dev/null
+++ b/net/openbgpd/files/patch-bgpd_rde_prefix.c
@@ -0,0 +1,301 @@
+Index: bgpd/rde_prefix.c
+===================================================================
+RCS file: /home/cvs/private/hrs/openbgpd/bgpd/rde_prefix.c,v
+retrieving revision 1.1.1.6
+retrieving revision 1.6
+diff -u -p -r1.1.1.6 -r1.6
+--- bgpd/rde_prefix.c 14 Feb 2010 20:19:57 -0000 1.1.1.6
++++ bgpd/rde_prefix.c 13 Oct 2012 18:36:00 -0000 1.6
+@@ -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.31 2010/01/13 06:02:37 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,17 +71,24 @@ 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 ??? */
+ 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_fill(struct bgpd_addr *prefix, int prefixlen)
+ {
+- 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:
++ 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;
++ 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));
++ pte6.aid = prefix->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);
++ 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);
++ fatalx("pt_fill: unknown af");
+ }
++ /* NOT REACHED */
++ return (NULL);
+ }
+
+ struct pt_entry *
+@@ -131,39 +155,12 @@ 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");
+- }
+
+- if (RB_INSERT(pt_tree, &pttable, p) != NULL) {
+- log_warnx("pt_add: insert failed");
+- return (NULL);
+- }
++ p = pt_fill(prefix, prefixlen);
++ p = pt_alloc(p);
++
++ if (RB_INSERT(pt_tree, &pttable, p) != NULL)
++ fatalx("pt_add: insert failed");
+
+ return (p);
+ }
+@@ -183,13 +180,14 @@ struct pt_entry *
+ pt_lookup(struct bgpd_addr *addr)
+ {
+ struct pt_entry *p;
+- int i;
++ int i = 0;
+
+- switch (addr->af) {
+- case AF_INET:
++ switch (addr->aid) {
++ case AID_INET:
++ case AID_VPN_IPv4:
+ i = 32;
+ break;
+- case AF_INET6:
++ case AID_INET6:
+ i = 128;
+ break;
+ default:
+@@ -206,17 +204,18 @@ pt_lookup(struct bgpd_addr *addr)
+ int
+ 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)
++ 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 +227,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 +241,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");
+ }
+ 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);
+-}
++ rdemem.pt_cnt[op->aid]++;
++ memcpy(p, op, pt_sizes[op->aid]);
+
+-static struct pt_entry6 *
+-pt_alloc6(void)
+-{
+- struct pt_entry6 *p;
+-
+- 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);
+ }