summaryrefslogtreecommitdiff
path: root/nhrpd/nhrp_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'nhrpd/nhrp_cache.c')
-rw-r--r--nhrpd/nhrp_cache.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/nhrpd/nhrp_cache.c b/nhrpd/nhrp_cache.c
index f7c71c2218..1c8fee8b07 100644
--- a/nhrpd/nhrp_cache.c
+++ b/nhrpd/nhrp_cache.c
@@ -16,6 +16,7 @@
#include "netlink.h"
DEFINE_MTYPE_STATIC(NHRPD, NHRP_CACHE, "NHRP cache entry")
+DEFINE_MTYPE_STATIC(NHRPD, NHRP_CACHE_CONFIG, "NHRP cache config entry")
unsigned long nhrp_cache_counts[NHRP_CACHE_NUM_TYPES];
@@ -77,6 +78,68 @@ static void nhrp_cache_free(struct nhrp_cache *c)
XFREE(MTYPE_NHRP_CACHE, c);
}
+static unsigned int nhrp_cache_config_protocol_key(const void *peer_data)
+{
+ const struct nhrp_cache_config *p = peer_data;
+ return sockunion_hash(&p->remote_addr);
+}
+
+static bool nhrp_cache_config_protocol_cmp(const void *cache_data,
+ const void *key_data)
+{
+ const struct nhrp_cache_config *a = cache_data;
+ const struct nhrp_cache_config *b = key_data;
+
+ if (!sockunion_same(&a->remote_addr, &b->remote_addr))
+ return false;
+ if (a->ifp != b->ifp)
+ return false;
+ return true;
+}
+
+static void *nhrp_cache_config_alloc(void *data)
+{
+ struct nhrp_cache_config *p, *key = data;
+
+ p = XCALLOC(MTYPE_NHRP_CACHE_CONFIG, sizeof(struct nhrp_cache_config));
+
+ *p = (struct nhrp_cache_config){
+ .remote_addr = key->remote_addr,
+ .ifp = key->ifp,
+ };
+ return p;
+}
+
+void nhrp_cache_config_free(struct nhrp_cache_config *c)
+{
+ struct nhrp_interface *nifp = c->ifp->info;
+
+ hash_release(nifp->cache_config_hash, c);
+ XFREE(MTYPE_NHRP_CACHE_CONFIG, c);
+}
+
+struct nhrp_cache_config *nhrp_cache_config_get(struct interface *ifp,
+ union sockunion *remote_addr,
+ int create)
+{
+ struct nhrp_interface *nifp = ifp->info;
+ struct nhrp_cache_config key;
+
+ if (!nifp->cache_config_hash) {
+ nifp->cache_config_hash =
+ hash_create(nhrp_cache_config_protocol_key,
+ nhrp_cache_config_protocol_cmp,
+ "NHRP Config Cache");
+ if (!nifp->cache_config_hash)
+ return NULL;
+ }
+ key.remote_addr = *remote_addr;
+ key.ifp = ifp;
+
+ return hash_get(nifp->cache_config_hash, &key,
+ create ? nhrp_cache_config_alloc : NULL);
+}
+
struct nhrp_cache *nhrp_cache_get(struct interface *ifp,
union sockunion *remote_addr, int create)
{
@@ -424,12 +487,23 @@ struct nhrp_cache_iterator_ctx {
void *ctx;
};
+struct nhrp_cache_config_iterator_ctx {
+ void (*cb)(struct nhrp_cache_config *, void *);
+ void *ctx;
+};
+
static void nhrp_cache_iterator(struct hash_bucket *b, void *ctx)
{
struct nhrp_cache_iterator_ctx *ic = ctx;
ic->cb(b->data, ic->ctx);
}
+static void nhrp_cache_config_iterator(struct hash_bucket *b, void *ctx)
+{
+ struct nhrp_cache_config_iterator_ctx *ic = ctx;
+ ic->cb(b->data, ic->ctx);
+}
+
void nhrp_cache_foreach(struct interface *ifp,
void (*cb)(struct nhrp_cache *, void *), void *ctx)
{
@@ -442,6 +516,18 @@ void nhrp_cache_foreach(struct interface *ifp,
hash_iterate(nifp->cache_hash, nhrp_cache_iterator, &ic);
}
+void nhrp_cache_config_foreach(struct interface *ifp,
+ void (*cb)(struct nhrp_cache_config *, void *), void *ctx)
+{
+ struct nhrp_interface *nifp = ifp->info;
+ struct nhrp_cache_config_iterator_ctx ic = {
+ .cb = cb, .ctx = ctx,
+ };
+
+ if (nifp->cache_config_hash)
+ hash_iterate(nifp->cache_config_hash, nhrp_cache_config_iterator, &ic);
+}
+
void nhrp_cache_notify_add(struct nhrp_cache *c, struct notifier_block *n,
notifier_fn_t fn)
{