aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2017-10-16 14:52:25 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2017-10-17 19:10:24 +0200
commit859f9b0752419d43928d465bc96a87238c6d7940 (patch)
tree66a909a73315a126d790839160b5cbaed3b899bc /lib
parenta037e5908a84e8f438f8faef662f6bfcec305b16 (diff)
ippool: Implement and use blacklist instead of blindly using IPPOOL_NOGATEWAY
Commit dda21ed7d4a897c9284c69175d0da598598eae40 modified previous calls to ippool_new() removing the pass of flags to avoid allocating certain problematic IPs from the pool to MS, such as the network, gateway and broadcast IPs. Today I did some unsucessful tests with osmo-ggsn with a pool "ip prefix dynamic 176.16.222.0/24", and thus IP 176.16.222.0 was being assigned to the MS. De-capsulated DNS packets were received in the tun interface, but the Linux system in there was unable to correctly forward the packets to the gateway interface connected to the Internet. However, adding a second MS which got 176.16.222.1 had its packets forwarded correctly. However, previous implementation relies on flag IPPOOL_NOGATEWAY flag to blindly blacklist first IP after the network ip (ie, .0 and .1 are removed), which limits the IP reserved for the tun device to be .1. If a different IP in the range is assigned, it may cause issues. As a result, a blacklist is introduced in this commit to dynamically fetch the tun IP address and exlucde it from the pool of available IPs. Change-Id: I8e91f7280d60490c858a769dd578c1c8e54e9243
Diffstat (limited to 'lib')
-rw-r--r--lib/ippool.c36
-rw-r--r--lib/ippool.h4
2 files changed, 26 insertions, 14 deletions
diff --git a/lib/ippool.c b/lib/ippool.c
index 03323e2..55a41d0 100644
--- a/lib/ippool.c
+++ b/lib/ippool.c
@@ -184,9 +184,19 @@ void in46a_inc(struct in46_addr *addr)
}
}
+static bool addr_in_prefix_list(struct in46_addr *addr, struct in46_prefix *list, size_t list_size)
+{
+ int i;
+ for (i = 0; i < list_size; i++) {
+ if (in46a_prefix_equal(addr, &list[i].addr))
+ return true;
+ }
+ return false;
+}
+
/* Create new address pool */
int ippool_new(struct ippool_t **this, const struct in46_prefix *dyn, const struct in46_prefix *stat,
- int flags)
+ int flags, struct in46_prefix *blacklist, size_t blacklist_size)
{
/* Parse only first instance of pool for now */
@@ -210,18 +220,16 @@ int ippool_new(struct ippool_t **this, const struct in46_prefix *dyn, const stru
if (addr.len == sizeof(struct in6_addr))
addr.len = 64/8;
- /* Set IPPOOL_NONETWORK if IPPOOL_NOGATEWAY is set */
- if (flags & IPPOOL_NOGATEWAY) {
- flags |= IPPOOL_NONETWORK;
- }
-
dynsize = (1 << (addr.len*8 - addrprefixlen));
if (flags & IPPOOL_NONETWORK) /* Exclude network address from pool */
dynsize--;
- if (flags & IPPOOL_NOGATEWAY) /* Exclude gateway address from pool */
- dynsize--;
if (flags & IPPOOL_NOBROADCAST) /* Exclude broadcast address from pool */
dynsize--;
+ /* Exclude included blacklist addresses from pool */
+ for (i = 0; i < blacklist_size; i++) {
+ if (in46a_within_mask(&blacklist[i].addr, &addr, addrprefixlen))
+ dynsize--;
+ }
}
if (!stat || stat->addr.len == 0) {
@@ -278,13 +286,17 @@ int ippool_new(struct ippool_t **this, const struct in46_prefix *dyn, const stru
(*this)->firstdyn = NULL;
(*this)->lastdyn = NULL;
- if (flags & IPPOOL_NOGATEWAY) {
- in46a_inc(&addr);
- in46a_inc(&addr);
- } else if (flags & IPPOOL_NONETWORK) {
+ if (flags & IPPOOL_NONETWORK) {
in46a_inc(&addr);
}
for (i = 0; i < dynsize; i++) {
+ if (addr_in_prefix_list(&addr, blacklist, blacklist_size)) {
+ SYS_ERR(DIP, LOGL_DEBUG, 0,
+ "addr blacklisted from pool: %s", in46a_ntoa(&addr));
+ in46a_inc(&addr);
+ i--;
+ continue;
+ }
(*this)->member[i].addr = addr;
in46a_inc(&addr);
diff --git a/lib/ippool.h b/lib/ippool.h
index 56beb4e..efb274b 100644
--- a/lib/ippool.h
+++ b/lib/ippool.h
@@ -31,7 +31,6 @@
#define IPPOOL_NONETWORK 0x01
#define IPPOOL_NOBROADCAST 0x02
-#define IPPOOL_NOGATEWAY 0x04
#define IPPOOL_STATSIZE 0x10000
@@ -72,7 +71,8 @@ extern unsigned long int ippool_hash(struct in46_addr *addr);
/* Create new address pool */
extern int ippool_new(struct ippool_t **this, const struct in46_prefix *dyn,
- const struct in46_prefix *stat, int flags);
+ const struct in46_prefix *stat, int flags,
+ struct in46_prefix *blacklist, size_t blacklist_size);
/* Delete existing address pool */
extern int ippool_free(struct ippool_t *this);