diff options
author | Harald Welte <laforge@gnumonks.org> | 2017-08-08 18:10:43 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2017-08-09 22:09:34 +0200 |
commit | 714a41bf66932bb6b383cd4573d1eff51aaf50dd (patch) | |
tree | c9b31602ccb2cb0f0021b96f9d9cf5849ec0a41d /lib/ippool.c | |
parent | 365f8fa4628b371551d6f5b20651ac06239f905d (diff) |
ippool: Extend pool to work with /64 prefixes
In IPv6 GPRS, we actually don't want to allocate an individual v6
address (like in IPv4), but we want to allocate a prefix. The
standard prefix lengh is 8 bytes, i.e. a /64 prefix. This patch
extends the pool to be able to work with such v6 prefixes.
Change-Id: I0cf700b6baf195a2e5fbea000531f801acaaa443
Diffstat (limited to 'lib/ippool.c')
-rw-r--r-- | lib/ippool.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/lib/ippool.c b/lib/ippool.c index 007dc50..683d2d8 100644 --- a/lib/ippool.c +++ b/lib/ippool.c @@ -96,11 +96,10 @@ static unsigned long int ippool_hash4(struct in_addr *addr) return lookup((unsigned char *)&addr->s_addr, sizeof(addr->s_addr), 0); } -static unsigned long int ippool_hash6(struct in6_addr *addr) +static unsigned long int ippool_hash6(struct in6_addr *addr, unsigned int len) { /* TODO: Review hash spread for IPv6 */ - return lookup((unsigned char *)addr->s6_addr, sizeof(addr->s6_addr), - 0); + return lookup((unsigned char *)addr->s6_addr, len, 0); } unsigned long int ippool_hash(struct in46_addr *addr) @@ -108,7 +107,7 @@ unsigned long int ippool_hash(struct in46_addr *addr) if (addr->len == 4) return ippool_hash4(&addr->v4); else - return ippool_hash6(&addr->v6); + return ippool_hash6(&addr->v6, addr->len); } /* Get IP address and mask */ @@ -209,6 +208,10 @@ int ippool_new(struct ippool_t **this, const char *dyn, const char *stat, "Failed to parse dynamic pool"); return -1; } + /* we want to work with /64 prefixes, i.e. allocate /64 prefixes rather + * than /128 (single IPv6 addresses) */ + if (addr->len == sizeof(in6_addr)) + addr->len = 64/8; /* Set IPPOOL_NONETWORK if IPPOOL_NOGATEWAY is set */ if (flags & IPPOOL_NOGATEWAY) { @@ -348,7 +351,7 @@ int ippool_getip(struct ippool_t *this, struct ippoolm_t **member, /* Find in hash table */ hash = ippool_hash(addr) & this->hashmask; for (p = this->hash[hash]; p; p = p->nexthash) { - if (in46a_equal(&p->addr, addr)) { + if (in46a_prefix_equal(&p->addr, addr)) { if (member) *member = p; return 0; @@ -421,7 +424,7 @@ int ippool_newip(struct ippool_t *this, struct ippoolm_t **member, /* Find in hash table */ hash = ippool_hash(addr) & this->hashmask; for (p = this->hash[hash]; p; p = p->nexthash) { - if (in46a_equal(&p->addr, addr)) { + if (in46a_prefix_equal(&p->addr, addr)) { p2 = p; break; } |