diff options
Diffstat (limited to 'nhrpd/nhrp_cache.c')
| -rw-r--r-- | nhrpd/nhrp_cache.c | 86 | 
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)  {  | 
