-/* $OpenBSD: rde_prefix.c,v 1.46 2023/03/28 17:47:29 claudio Exp $ */
+/* $OpenBSD: rde_prefix.c,v 1.47 2023/03/30 12:11:18 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
#include <endian.h>
#include <errno.h>
-#include <limits.h>
+#include <stdint.h>
#include <stdlib.h>
#include <string.h>
*/
/* internal prototypes */
-static struct pt_entry *pt_alloc(struct pt_entry *);
+static struct pt_entry *pt_alloc(struct pt_entry *, int len);
static void pt_free(struct pt_entry *);
struct pt_entry4 {
RB_ENTRY(pt_entry) pt_e;
uint8_t aid;
uint8_t prefixlen;
- uint16_t refcnt;
+ uint16_t len;
+ uint32_t refcnt;
struct in_addr prefix4;
};
RB_ENTRY(pt_entry) pt_e;
uint8_t aid;
uint8_t prefixlen;
- uint16_t refcnt;
+ uint16_t len;
+ uint32_t refcnt;
struct in6_addr prefix6;
};
RB_ENTRY(pt_entry) pt_e;
uint8_t aid;
uint8_t prefixlen;
- uint16_t refcnt;
- struct in_addr prefix4;
+ uint16_t len;
+ uint32_t refcnt;
uint64_t rd;
+ struct in_addr prefix4;
uint8_t labelstack[21];
uint8_t labellen;
uint8_t pad1;
RB_ENTRY(pt_entry) pt_e;
uint8_t aid;
uint8_t prefixlen;
- uint16_t refcnt;
- struct in6_addr prefix6;
+ uint16_t len;
+ uint32_t refcnt;
uint64_t rd;
+ struct in6_addr prefix6;
uint8_t labelstack[21];
uint8_t labellen;
uint8_t pad1;
uint8_t pad2;
};
-size_t pt_sizes[AID_MAX] = {
- 0,
- sizeof(struct pt_entry4),
- sizeof(struct pt_entry6),
- sizeof(struct pt_entry_vpn4),
- sizeof(struct pt_entry_vpn6)
-};
RB_HEAD(pt_tree, pt_entry);
RB_PROTOTYPE(pt_tree, pt_entry, pt_e, pt_prefix_cmp);
switch (prefix->aid) {
case AID_INET:
memset(&pte4, 0, sizeof(pte4));
- pte4.refcnt = USHRT_MAX;
+ pte4.len = sizeof(pte4);
+ pte4.refcnt = UINT32_MAX;
pte4.aid = prefix->aid;
if (prefixlen > 32)
fatalx("pt_fill: bad IPv4 prefixlen");
return ((struct pt_entry *)&pte4);
case AID_INET6:
memset(&pte6, 0, sizeof(pte6));
- pte6.refcnt = USHRT_MAX;
+ pte6.len = sizeof(pte6);
+ pte6.refcnt = UINT32_MAX;
pte6.aid = prefix->aid;
if (prefixlen > 128)
fatalx("pt_fill: bad IPv6 prefixlen");
return ((struct pt_entry *)&pte6);
case AID_VPN_IPv4:
memset(&pte_vpn4, 0, sizeof(pte_vpn4));
- pte_vpn4.refcnt = USHRT_MAX;
+ pte_vpn4.len = sizeof(pte_vpn4);
+ pte_vpn4.refcnt = UINT32_MAX;
pte_vpn4.aid = prefix->aid;
if (prefixlen > 32)
fatalx("pt_fill: bad IPv4 prefixlen");
return ((struct pt_entry *)&pte_vpn4);
case AID_VPN_IPv6:
memset(&pte_vpn6, 0, sizeof(pte_vpn6));
- pte_vpn6.refcnt = USHRT_MAX;
+ pte_vpn6.len = sizeof(pte_vpn6);
+ pte_vpn6.refcnt = UINT32_MAX;
pte_vpn6.aid = prefix->aid;
if (prefixlen > 128)
fatalx("pt_get: bad IPv6 prefixlen");
{
struct pt_entry *p = NULL;
- p = pt_alloc(pt_fill(prefix, prefixlen));
+ p = pt_fill(prefix, prefixlen);
+ p = pt_alloc(p, p->len);
if (RB_INSERT(pt_tree, &pttable, p) != NULL)
fatalx("pt_add: insert failed");
* Function may not return on failure.
*/
static struct pt_entry *
-pt_alloc(struct pt_entry *op)
+pt_alloc(struct pt_entry *op, int len)
{
struct pt_entry *p;
- p = malloc(pt_sizes[op->aid]);
+ p = malloc(len);
if (p == NULL)
fatal("pt_alloc");
rdemem.pt_cnt[op->aid]++;
- rdemem.pt_size[op->aid] += pt_sizes[op->aid];
- memcpy(p, op, pt_sizes[op->aid]);
+ rdemem.pt_size[op->aid] += len;
+ memcpy(p, op, len);
p->refcnt = 0;
return (p);
pt_free(struct pt_entry *pte)
{
rdemem.pt_cnt[pte->aid]--;
- rdemem.pt_size[pte->aid] -= pt_sizes[pte->aid];
+ rdemem.pt_size[pte->aid] -= pte->len;
free(pte);
}