mirror of
https://github.com/openbsd/src.git
synced 2025-01-10 06:47:55 -08:00
Instead of a global aspath cache copy the aspath attribute per rde_aspath
struct. It uses a bit more memory but improves performance a lot on really big systems because aspath_get() becomes a very hot function. OK tb@
This commit is contained in:
parent
69acb4a308
commit
3487a0407f
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: bgpd.h,v 1.450 2022/08/26 14:10:52 claudio Exp $ */
|
||||
/* $OpenBSD: bgpd.h,v 1.451 2022/08/29 18:18:55 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@ -1193,7 +1193,6 @@ struct rde_memstats {
|
||||
long long nexthop_cnt;
|
||||
long long aspath_cnt;
|
||||
long long aspath_size;
|
||||
long long aspath_refs;
|
||||
long long comm_cnt;
|
||||
long long comm_nmemb;
|
||||
long long comm_size;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: rde.c,v 1.568 2022/08/29 16:44:47 claudio Exp $ */
|
||||
/* $OpenBSD: rde.c,v 1.569 2022/08/29 18:18:55 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
@ -197,7 +197,6 @@ rde_main(int debug, int verbose)
|
||||
|
||||
/* initialize the RIB structures */
|
||||
pt_init();
|
||||
aspath_init(pathhashsize);
|
||||
attr_init(attrhashsize);
|
||||
nexthop_init(nexthophashsize);
|
||||
peer_init(peerhashsize);
|
||||
@ -630,9 +629,6 @@ badnetdel:
|
||||
case IMSG_CTL_SHOW_RIB_MEM:
|
||||
imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_RIB_MEM, 0,
|
||||
imsg.hdr.pid, -1, &rdemem, sizeof(rdemem));
|
||||
aspath_hash_stats(&rdehash);
|
||||
imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_RIB_HASH, 0,
|
||||
imsg.hdr.pid, -1, &rdehash, sizeof(rdehash));
|
||||
attr_hash_stats(&rdehash);
|
||||
imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_RIB_HASH, 0,
|
||||
imsg.hdr.pid, -1, &rdehash, sizeof(rdehash));
|
||||
@ -1631,7 +1627,9 @@ pathid_assign(struct rde_peer *peer, uint32_t path_id,
|
||||
struct prefix *p = NULL;
|
||||
uint32_t path_id_tx;
|
||||
|
||||
/* Assign a send side path_id to all paths */
|
||||
/*
|
||||
* Assign a send side path_id to all paths.
|
||||
*/
|
||||
re = rib_get(rib_byid(RIB_ADJ_IN), prefix, prefixlen);
|
||||
if (re != NULL)
|
||||
p = prefix_bypeer(re, peer, path_id);
|
||||
@ -4308,7 +4306,6 @@ rde_shutdown(void)
|
||||
rib_shutdown();
|
||||
nexthop_shutdown();
|
||||
path_shutdown();
|
||||
aspath_shutdown();
|
||||
attr_shutdown();
|
||||
pt_shutdown();
|
||||
peer_shutdown();
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: rde.h,v 1.265 2022/08/29 16:44:47 claudio Exp $ */
|
||||
/* $OpenBSD: rde.h,v 1.266 2022/08/29 18:18:55 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
|
||||
@ -71,7 +71,6 @@ struct rib {
|
||||
* Currently I assume that we can do that with the neighbor_ip...
|
||||
*/
|
||||
LIST_HEAD(rde_peer_head, rde_peer);
|
||||
LIST_HEAD(aspath_list, aspath);
|
||||
LIST_HEAD(attr_list, attr);
|
||||
RB_HEAD(prefix_tree, prefix);
|
||||
RB_HEAD(prefix_index, prefix);
|
||||
@ -122,9 +121,7 @@ struct rde_peer {
|
||||
#define ASPATH_HEADER_SIZE (offsetof(struct aspath, data))
|
||||
|
||||
struct aspath {
|
||||
LIST_ENTRY(aspath) entry;
|
||||
uint32_t source_as; /* cached source_as */
|
||||
int refcnt; /* reference count */
|
||||
uint16_t len; /* total length of aspath in octets */
|
||||
uint16_t ascnt; /* number of AS hops in data */
|
||||
u_char data[1]; /* placeholder for actual data */
|
||||
@ -446,10 +443,8 @@ void attr_free(struct rde_aspath *, struct attr *);
|
||||
#define attr_optlen(x) \
|
||||
((x)->len > 255 ? (x)->len + 4 : (x)->len + 3)
|
||||
|
||||
void aspath_init(uint32_t);
|
||||
void aspath_shutdown(void);
|
||||
void aspath_hash_stats(struct rde_hashstats *);
|
||||
struct aspath *aspath_get(void *, uint16_t);
|
||||
struct aspath *aspath_copy(struct aspath *);
|
||||
void aspath_put(struct aspath *);
|
||||
u_char *aspath_deflate(u_char *, uint16_t *, int *);
|
||||
void aspath_merge(struct rde_aspath *, struct attr *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: rde_attr.c,v 1.128 2022/08/29 18:04:51 claudio Exp $ */
|
||||
/* $OpenBSD: rde_attr.c,v 1.129 2022/08/29 18:18:55 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org>
|
||||
@ -446,102 +446,57 @@ static uint32_t aspath_extract_origin(const void *, uint16_t);
|
||||
static uint16_t aspath_countlength(struct aspath *, uint16_t, int);
|
||||
static void aspath_countcopy(struct aspath *, uint16_t, uint8_t *,
|
||||
uint16_t, int);
|
||||
struct aspath *aspath_lookup(const void *, uint16_t);
|
||||
|
||||
struct aspath_table {
|
||||
struct aspath_list *hashtbl;
|
||||
uint32_t hashmask;
|
||||
} astable;
|
||||
|
||||
SIPHASH_KEY astablekey;
|
||||
|
||||
#define ASPATH_HASH(x) \
|
||||
&astable.hashtbl[(x) & astable.hashmask]
|
||||
|
||||
void
|
||||
aspath_init(uint32_t hashsize)
|
||||
int
|
||||
aspath_compare(struct aspath *a1, struct aspath *a2)
|
||||
{
|
||||
uint32_t hs, i;
|
||||
int r;
|
||||
|
||||
for (hs = 1; hs < hashsize; hs <<= 1)
|
||||
;
|
||||
astable.hashtbl = calloc(hs, sizeof(struct aspath_list));
|
||||
if (astable.hashtbl == NULL)
|
||||
fatal("aspath_init");
|
||||
|
||||
for (i = 0; i < hs; i++)
|
||||
LIST_INIT(&astable.hashtbl[i]);
|
||||
|
||||
astable.hashmask = hs - 1;
|
||||
arc4random_buf(&astablekey, sizeof(astablekey));
|
||||
}
|
||||
|
||||
void
|
||||
aspath_shutdown(void)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i <= astable.hashmask; i++)
|
||||
if (!LIST_EMPTY(&astable.hashtbl[i]))
|
||||
log_warnx("aspath_shutdown: free non-free table");
|
||||
|
||||
free(astable.hashtbl);
|
||||
}
|
||||
|
||||
void
|
||||
aspath_hash_stats(struct rde_hashstats *hs)
|
||||
{
|
||||
struct aspath *a;
|
||||
uint32_t i;
|
||||
int64_t n;
|
||||
|
||||
memset(hs, 0, sizeof(*hs));
|
||||
strlcpy(hs->name, "aspath hash", sizeof(hs->name));
|
||||
hs->min = LLONG_MAX;
|
||||
hs->num = astable.hashmask + 1;
|
||||
|
||||
for (i = 0; i <= astable.hashmask; i++) {
|
||||
n = 0;
|
||||
LIST_FOREACH(a, &astable.hashtbl[i], entry)
|
||||
n++;
|
||||
if (n < hs->min)
|
||||
hs->min = n;
|
||||
if (n > hs->max)
|
||||
hs->max = n;
|
||||
hs->sum += n;
|
||||
hs->sumq += n * n;
|
||||
}
|
||||
if (a1->len > a2->len)
|
||||
return (1);
|
||||
if (a1->len < a2->len)
|
||||
return (-1);
|
||||
r = memcmp(a1->data, a2->data, a1->len);
|
||||
if (r > 0)
|
||||
return (1);
|
||||
if (r < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct aspath *
|
||||
aspath_get(void *data, uint16_t len)
|
||||
{
|
||||
struct aspath_list *head;
|
||||
struct aspath *aspath;
|
||||
|
||||
/* The aspath must already have been checked for correctness. */
|
||||
aspath = aspath_lookup(data, len);
|
||||
if (aspath == NULL) {
|
||||
aspath = malloc(ASPATH_HEADER_SIZE + len);
|
||||
if (aspath == NULL)
|
||||
fatal("aspath_get");
|
||||
aspath = malloc(ASPATH_HEADER_SIZE + len);
|
||||
if (aspath == NULL)
|
||||
fatal("%s", __func__);
|
||||
|
||||
rdemem.aspath_cnt++;
|
||||
rdemem.aspath_size += ASPATH_HEADER_SIZE + len;
|
||||
rdemem.aspath_cnt++;
|
||||
rdemem.aspath_size += ASPATH_HEADER_SIZE + len;
|
||||
|
||||
aspath->refcnt = 0;
|
||||
aspath->len = len;
|
||||
aspath->ascnt = aspath_count(data, len);
|
||||
aspath->source_as = aspath_extract_origin(data, len);
|
||||
memcpy(aspath->data, data, len);
|
||||
aspath->len = len;
|
||||
aspath->ascnt = aspath_count(data, len);
|
||||
aspath->source_as = aspath_extract_origin(data, len);
|
||||
memcpy(aspath->data, data, len);
|
||||
|
||||
/* link */
|
||||
head = ASPATH_HASH(SipHash24(&astablekey, aspath->data,
|
||||
aspath->len));
|
||||
LIST_INSERT_HEAD(head, aspath, entry);
|
||||
}
|
||||
aspath->refcnt++;
|
||||
rdemem.aspath_refs++;
|
||||
return (aspath);
|
||||
}
|
||||
|
||||
struct aspath *
|
||||
aspath_copy(struct aspath *a)
|
||||
{
|
||||
struct aspath *aspath;
|
||||
|
||||
aspath = malloc(ASPATH_HEADER_SIZE + a->len);
|
||||
if (aspath == NULL)
|
||||
fatal("%s", __func__);
|
||||
|
||||
rdemem.aspath_cnt++;
|
||||
rdemem.aspath_size += ASPATH_HEADER_SIZE + a->len;
|
||||
|
||||
memcpy(aspath, a, ASPATH_HEADER_SIZE + a->len);
|
||||
|
||||
return (aspath);
|
||||
}
|
||||
@ -552,15 +507,6 @@ aspath_put(struct aspath *aspath)
|
||||
if (aspath == NULL)
|
||||
return;
|
||||
|
||||
rdemem.aspath_refs--;
|
||||
if (--aspath->refcnt > 0) {
|
||||
/* somebody still holds a reference */
|
||||
return;
|
||||
}
|
||||
|
||||
/* unlink */
|
||||
LIST_REMOVE(aspath, entry);
|
||||
|
||||
rdemem.aspath_cnt--;
|
||||
rdemem.aspath_size -= ASPATH_HEADER_SIZE + aspath->len;
|
||||
free(aspath);
|
||||
@ -850,41 +796,6 @@ aspath_loopfree(struct aspath *aspath, uint32_t myAS)
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
aspath_compare(struct aspath *a1, struct aspath *a2)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (a1->len > a2->len)
|
||||
return (1);
|
||||
if (a1->len < a2->len)
|
||||
return (-1);
|
||||
r = memcmp(a1->data, a2->data, a1->len);
|
||||
if (r > 0)
|
||||
return (1);
|
||||
if (r < 0)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct aspath *
|
||||
aspath_lookup(const void *data, uint16_t len)
|
||||
{
|
||||
struct aspath_list *head;
|
||||
struct aspath *aspath;
|
||||
uint32_t hash;
|
||||
|
||||
hash = SipHash24(&astablekey, data, len);
|
||||
head = ASPATH_HASH(hash);
|
||||
|
||||
LIST_FOREACH(aspath, head, entry) {
|
||||
if (len == aspath->len && memcmp(data, aspath->data, len) == 0)
|
||||
return (aspath);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
as_compare(struct filter_as *f, uint32_t as, uint32_t neighas)
|
||||
{
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: rde_rib.c,v 1.245 2022/08/29 16:43:07 claudio Exp $ */
|
||||
/* $OpenBSD: rde_rib.c,v 1.246 2022/08/29 18:18:55 claudio Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
|
||||
@ -678,11 +678,7 @@ path_unlink(struct rde_aspath *asp)
|
||||
struct rde_aspath *
|
||||
path_copy(struct rde_aspath *dst, const struct rde_aspath *src)
|
||||
{
|
||||
dst->aspath = src->aspath;
|
||||
if (dst->aspath != NULL) {
|
||||
dst->aspath->refcnt++;
|
||||
rdemem.aspath_refs++;
|
||||
}
|
||||
dst->aspath = aspath_copy(src->aspath);
|
||||
dst->hash = 0; /* not linked so no hash and no refcnt */
|
||||
dst->refcnt = 0;
|
||||
dst->flags = src->flags & ~F_ATTR_LINKED;
|
||||
@ -734,6 +730,7 @@ path_clean(struct rde_aspath *asp)
|
||||
rtlabel_unref(asp->rtlabelid);
|
||||
pftable_unref(asp->pftableid);
|
||||
aspath_put(asp->aspath);
|
||||
asp->aspath = NULL;
|
||||
attr_freeall(asp);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user