aboutsummaryrefslogtreecommitdiffstats
path: root/ggsn/ggsn.c
diff options
context:
space:
mode:
authorPau Espin Pedrol <pespin@sysmocom.de>2017-10-13 14:32:09 +0200
committerPau Espin Pedrol <pespin@sysmocom.de>2017-10-13 15:10:04 +0200
commit503f468366fc28720208aeee957bfb32a50a60d8 (patch)
tree0851e43c00d3faef3411ee83220437a1a021ceec /ggsn/ggsn.c
parentd6ede37b7e62ca7e3544b7319b9234c564365dca (diff)
ippool: Implement and use blacklist instead of blindly using IPPOOL_NOGATEWAYpespin/ippool
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 'ggsn/ggsn.c')
-rw-r--r--ggsn/ggsn.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c
index 67d040f..9cfe085 100644
--- a/ggsn/ggsn.c
+++ b/ggsn/ggsn.c
@@ -149,6 +149,10 @@ int apn_stop(struct apn_ctx *apn, bool force)
/* actually start the APN with its current config */
int apn_start(struct apn_ctx *apn)
{
+ int ipv4_blacklist_size = 0, ipv6_blacklist_size = 0;
+ struct in46_prefix ipv4_tun_ip, ipv6_tun_ip, ipv6_tun_linklocal_ip;
+ int ippool_flags = IPPOOL_NONETWORK | IPPOOL_NOBROADCAST;
+
if (apn->started)
return 0;
@@ -201,12 +205,13 @@ int apn_start(struct apn_ctx *apn)
}
if (apn->cfg.apn_type_mask & (APN_TYPE_IPv6|APN_TYPE_IPv4v6)) {
- if (tun_ipv6_linklocal_get(apn->tun.tun, &apn->v6_lladdr) < 0) {
+ if (tun_ipv6_local_get(apn->tun.tun, &ipv6_tun_linklocal_ip, IPV6_TYPE_LINK) < 0) {
LOGPAPN(LOGL_ERROR, apn, "Cannot obtain IPv6 link-local address of "
"interface: %s\n", strerror(errno));
apn_stop(apn, false);
return -1;
}
+ apn->v6_lladdr = ipv6_tun_linklocal_ip.addr.v6;
}
/* set back-pointer from TUN device to APN */
@@ -229,8 +234,14 @@ int apn_start(struct apn_ctx *apn)
if (apn->v4.cfg.dynamic_prefix.addr.len) {
LOGPAPN(LOGL_INFO, apn, "Creating IPv4 pool %s\n",
in46p_ntoa(&apn->v4.cfg.dynamic_prefix));
+ if(tun_ipv4_local_get(apn->tun.tun, &ipv4_tun_ip) == 0) {
+ ipv4_blacklist_size = 1;
+ LOGPAPN(LOGL_INFO, apn, "Blacklist IPv4 tun IP %s\n",
+ in46p_ntoa(&ipv4_tun_ip));
+ }
if (ippool_new(&apn->v4.pool, &apn->v4.cfg.dynamic_prefix,
- &apn->v4.cfg.static_prefix, 0)) {
+ &apn->v4.cfg.static_prefix, ippool_flags,
+ &ipv4_tun_ip, ipv4_blacklist_size)) {
LOGPAPN(LOGL_ERROR, apn, "Failed to create IPv4 pool\n");
apn_stop(apn, false);
return -1;
@@ -241,8 +252,14 @@ int apn_start(struct apn_ctx *apn)
if (apn->v6.cfg.dynamic_prefix.addr.len) {
LOGPAPN(LOGL_INFO, apn, "Creating IPv6 pool %s\n",
in46p_ntoa(&apn->v6.cfg.dynamic_prefix));
+ if(tun_ipv6_local_get(apn->tun.tun, &ipv6_tun_ip, IPV6_TYPE_GLOBAL) == 0) {
+ ipv6_blacklist_size = 1;
+ LOGPAPN(LOGL_INFO, apn, "Blacklist IPv6 tun IP %s\n",
+ in46p_ntoa(&ipv6_tun_ip));
+ }
if (ippool_new(&apn->v6.pool, &apn->v6.cfg.dynamic_prefix,
- &apn->v6.cfg.static_prefix, 0)) {
+ &apn->v6.cfg.static_prefix, ippool_flags,
+ &ipv6_tun_ip, ipv6_blacklist_size)) {
LOGPAPN(LOGL_ERROR, apn, "Failed to create IPv6 pool\n");
apn_stop(apn, false);
return -1;