-/* $OpenBSD: rde.c,v 1.566 2022/08/29 14:57:27 claudio Exp $ */
+/* $OpenBSD: rde.c,v 1.567 2022/08/29 16:43:07 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
/* initialize the RIB structures */
pt_init();
- path_init(pathhashsize);
aspath_init(pathhashsize);
communities_init(attrhashsize);
attr_init(attrhashsize);
case IMSG_CTL_SHOW_RIB_MEM:
imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_RIB_MEM, 0,
imsg.hdr.pid, -1, &rdemem, sizeof(rdemem));
- path_hash_stats(&rdehash);
- imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_RIB_HASH, 0,
- imsg.hdr.pid, -1, &rdehash, sizeof(rdehash));
aspath_hash_stats(&rdehash);
imsg_compose(ibuf_se_ctl, IMSG_CTL_SHOW_RIB_HASH, 0,
imsg.hdr.pid, -1, &rdehash, sizeof(rdehash));
-/* $OpenBSD: rde.h,v 1.263 2022/08/26 14:10:52 claudio Exp $ */
+/* $OpenBSD: rde.h,v 1.264 2022/08/29 16:43:07 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and
LIST_HEAD(rde_peer_head, rde_peer);
LIST_HEAD(aspath_list, aspath);
LIST_HEAD(attr_list, attr);
-LIST_HEAD(aspath_head, rde_aspath);
RB_HEAD(prefix_tree, prefix);
RB_HEAD(prefix_index, prefix);
struct iq;
#define DEFAULT_LPREF 100
struct rde_aspath {
- LIST_ENTRY(rde_aspath) path_l;
+ RB_ENTRY(rde_aspath) entry;
struct attr **others;
struct aspath *aspath;
uint64_t hash;
int refcnt;
uint32_t flags; /* internally used */
-#define aspath_hashstart med
uint32_t med; /* multi exit disc */
uint32_t lpref; /* local pref */
uint32_t weight; /* low prio lpref */
uint16_t rtlabelid; /* route label id */
uint16_t pftableid; /* pf table id */
uint8_t origin;
-#define aspath_hashend others_len
uint8_t others_len;
};
return rib_byid(re->rib_id);
}
-void path_init(uint32_t);
void path_shutdown(void);
-void path_hash_stats(struct rde_hashstats *);
-int path_compare(struct rde_aspath *, struct rde_aspath *);
uint32_t path_remove_stale(struct rde_aspath *, uint8_t, time_t);
struct rde_aspath *path_copy(struct rde_aspath *, const struct rde_aspath *);
struct rde_aspath *path_prep(struct rde_aspath *);
-/* $OpenBSD: rde_rib.c,v 1.244 2022/08/25 08:10:25 claudio Exp $ */
+/* $OpenBSD: rde_rib.c,v 1.245 2022/08/29 16:43:07 claudio Exp $ */
/*
* Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org>
/* path specific functions */
static struct rde_aspath *path_lookup(struct rde_aspath *);
-static uint64_t path_hash(struct rde_aspath *);
static void path_link(struct rde_aspath *);
static void path_unlink(struct rde_aspath *);
-struct path_table {
- struct aspath_head *path_hashtbl;
- uint64_t path_hashmask;
-} pathtable;
-
-SIPHASH_KEY pathtablekey;
-
-#define PATH_HASH(x) &pathtable.path_hashtbl[x & pathtable.path_hashmask]
-
-static inline struct rde_aspath *
-path_ref(struct rde_aspath *asp)
-{
- if ((asp->flags & F_ATTR_LINKED) == 0)
- fatalx("%s: unlinked object", __func__);
- asp->refcnt++;
- rdemem.path_refs++;
-
- return asp;
-}
-
-static inline void
-path_unref(struct rde_aspath *asp)
-{
- if (asp == NULL)
- return;
- if ((asp->flags & F_ATTR_LINKED) == 0)
- fatalx("%s: unlinked object", __func__);
- asp->refcnt--;
- rdemem.path_refs--;
- if (asp->refcnt <= 0)
- path_unlink(asp);
-}
-
-void
-path_init(uint32_t hashsize)
-{
- uint32_t hs, i;
-
- for (hs = 1; hs < hashsize; hs <<= 1)
- ;
- pathtable.path_hashtbl = calloc(hs, sizeof(*pathtable.path_hashtbl));
- if (pathtable.path_hashtbl == NULL)
- fatal("path_init");
-
- for (i = 0; i < hs; i++)
- LIST_INIT(&pathtable.path_hashtbl[i]);
-
- pathtable.path_hashmask = hs - 1;
- arc4random_buf(&pathtablekey, sizeof(pathtablekey));
-}
-
-void
-path_shutdown(void)
-{
- uint32_t i;
-
- for (i = 0; i <= pathtable.path_hashmask; i++)
- if (!LIST_EMPTY(&pathtable.path_hashtbl[i]))
- log_warnx("path_free: free non-free table");
-
- free(pathtable.path_hashtbl);
-}
-
-void
-path_hash_stats(struct rde_hashstats *hs)
-{
- struct rde_aspath *a;
- uint32_t i;
- int64_t n;
-
- memset(hs, 0, sizeof(*hs));
- strlcpy(hs->name, "path hash", sizeof(hs->name));
- hs->min = LLONG_MAX;
- hs->num = pathtable.path_hashmask + 1;
-
- for (i = 0; i <= pathtable.path_hashmask; i++) {
- n = 0;
- LIST_FOREACH(a, &pathtable.path_hashtbl[i], path_l)
- n++;
- if (n < hs->min)
- hs->min = n;
- if (n > hs->max)
- hs->max = n;
- hs->sum += n;
- hs->sumq += n * n;
- }
-}
-
-int
+static inline int
path_compare(struct rde_aspath *a, struct rde_aspath *b)
{
int r;
return (attr_compare(a, b));
}
-static uint64_t
-path_hash(struct rde_aspath *asp)
-{
- SIPHASH_CTX ctx;
- uint64_t hash;
+RB_HEAD(path_tree, rde_aspath) pathtable = RB_INITIALIZER(&pathtable);
+RB_GENERATE_STATIC(path_tree, rde_aspath, entry, path_compare);
- SipHash24_Init(&ctx, &pathtablekey);
- SipHash24_Update(&ctx, &asp->aspath_hashstart,
- (char *)&asp->aspath_hashend - (char *)&asp->aspath_hashstart);
+static inline struct rde_aspath *
+path_ref(struct rde_aspath *asp)
+{
+ if ((asp->flags & F_ATTR_LINKED) == 0)
+ fatalx("%s: unlinked object", __func__);
+ asp->refcnt++;
+ rdemem.path_refs++;
- if (asp->aspath)
- SipHash24_Update(&ctx, asp->aspath->data, asp->aspath->len);
+ return asp;
+}
- hash = attr_hash(asp);
- SipHash24_Update(&ctx, &hash, sizeof(hash));
+static inline void
+path_unref(struct rde_aspath *asp)
+{
+ if (asp == NULL)
+ return;
+ if ((asp->flags & F_ATTR_LINKED) == 0)
+ fatalx("%s: unlinked object", __func__);
+ asp->refcnt--;
+ rdemem.path_refs--;
+ if (asp->refcnt <= 0)
+ path_unlink(asp);
+}
- return (SipHash24_End(&ctx));
+void
+path_shutdown(void)
+{
+ if (!RB_EMPTY(&pathtable))
+ log_warnx("path_free: free non-free table");
}
static struct rde_aspath *
path_lookup(struct rde_aspath *aspath)
{
- struct aspath_head *head;
- struct rde_aspath *asp;
- uint64_t hash;
-
- hash = path_hash(aspath);
- head = PATH_HASH(hash);
-
- LIST_FOREACH(asp, head, path_l) {
- if (asp->hash == hash && path_compare(aspath, asp) == 0)
- return (asp);
- }
- return (NULL);
+ return (RB_FIND(path_tree, &pathtable, aspath));
}
/*
static void
path_link(struct rde_aspath *asp)
{
- struct aspath_head *head;
-
- asp->hash = path_hash(asp);
- head = PATH_HASH(asp->hash);
-
- LIST_INSERT_HEAD(head, asp, path_l);
+ if (RB_INSERT(path_tree, &pathtable, asp) != NULL)
+ fatalx("%s: already linked object", __func__);
asp->flags |= F_ATTR_LINKED;
}
if (asp->refcnt != 0)
fatalx("%s: still holds references", __func__);
- LIST_REMOVE(asp, path_l);
+ RB_REMOVE(path_tree, &pathtable, asp);
asp->flags &= ~F_ATTR_LINKED;
path_put(asp);