aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2017-11-08 15:09:58 +0900
committerHarald Welte <laforge@gnumonks.org>2017-11-14 00:08:48 +0900
commit698a2339ebf0b2ebb753c572e2e81e208b2d6bdd (patch)
tree37df27b1212880d4e552c32e12da2926045f9b9e
parent490782d18e6bbab8b5f4f8dcef4d4f5ab310af6a (diff)
gtp-kernel: Get rid of hard-coded kernel GTP device name
The existing kernel GTP support code inherited from OpenGGSN was overly simplistic and didn't support multiple GTP devices or user-defined GTP device names. Let's remove that restriction in this patch Change-Id: I51df223788fd5b7cf8099463b8aa0ca4a4fd1c96
-rw-r--r--ggsn/ggsn.c9
-rw-r--r--ggsn/gtp-kernel.c27
-rw-r--r--ggsn/gtp-kernel.h16
3 files changed, 25 insertions, 27 deletions
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c
index 2937b04..6aa4210 100644
--- a/ggsn/ggsn.c
+++ b/ggsn/ggsn.c
@@ -266,7 +266,8 @@ int apn_start(struct apn_ctx *apn)
}
LOGPAPN(LOGL_ERROR, apn, "Setting up Kernel GTP\n");
/* use GTP kernel module for data packet encapsulation */
- if (gtp_kernel_init(apn->ggsn->gsn, &apn->v4.cfg.ifconfig_prefix, apn->tun.cfg.ipup_script) < 0) {
+ if (gtp_kernel_init(apn->ggsn->gsn, apn->tun.cfg.dev_name,
+ &apn->v4.cfg.ifconfig_prefix, apn->tun.cfg.ipup_script) < 0) {
return -1;
}
break;
@@ -334,6 +335,7 @@ static int delete_context(struct pdp_t *pdp)
{
struct gsn_t *gsn = pdp->gsn;
struct ippoolm_t *ipp = (struct ippoolm_t *)pdp->peer;
+ struct apn_ctx *apn = pdp->priv;
LOGPPDP(LOGL_INFO, pdp, "Deleting PDP context\n");
struct ippoolm_t *member = pdp->peer;
@@ -344,7 +346,7 @@ static int delete_context(struct pdp_t *pdp)
} else
LOGPPDP(LOGL_ERROR, pdp, "Cannot find/free IP Pool member\n");
- if (gtp_kernel_tunnel_del(pdp)) {
+ if (gtp_kernel_tunnel_del(pdp, apn->tun.cfg.dev_name)) {
LOGPPDP(LOGL_ERROR, pdp, "Cannot delete tunnel from kernel:%s\n",
strerror(errno));
}
@@ -567,7 +569,7 @@ int create_context_ind(struct pdp_t *pdp)
in46a_to_eua(&member->addr, &pdp->eua);
/* TODO: In IPv6, EUA doesn't contain the actual IP addr/prefix! */
- if (gtp_kernel_tunnel_add(pdp) < 0) {
+ if (gtp_kernel_tunnel_add(pdp, apn->tun.cfg.dev_name) < 0) {
LOGPPDP(LOGL_ERROR, pdp, "Cannot add tunnel to kernel: %s\n", strerror(errno));
gtp_create_context_resp(gsn, pdp, GTPCAUSE_SYS_FAIL);
return 0;
@@ -596,6 +598,7 @@ int create_context_ind(struct pdp_t *pdp)
pdp->peer = member;
pdp->ipif = apn->tun.tun; /* TODO */
+ pdp->priv = apn;
member->peer = pdp;
if (!send_trap(gsn, pdp, member, "imsi-ass-ip")) { /* TRAP with IP assignment */
diff --git a/ggsn/gtp-kernel.c b/ggsn/gtp-kernel.c
index a5708fc..102f0f7 100644
--- a/ggsn/gtp-kernel.c
+++ b/ggsn/gtp-kernel.c
@@ -54,10 +54,7 @@ static struct {
bool enabled;
} gtp_nl;
-/* Always forces the kernel to allocate gtp0. If it exists it hits EEXIST */
-#define GTP_DEVNAME "gtp0"
-
-int gtp_kernel_init(struct gsn_t *gsn, struct in46_prefix *prefix, const char *ipup)
+int gtp_kernel_init(struct gsn_t *gsn, const char *devname, struct in46_prefix *prefix, const char *ipup)
{
struct in_addr net;
const char *net_arg;
@@ -69,7 +66,7 @@ int gtp_kernel_init(struct gsn_t *gsn, struct in46_prefix *prefix, const char *i
}
net = prefix->addr.v4;
- if (gtp_dev_create(-1, GTP_DEVNAME, gsn->fd0, gsn->fd1u) < 0) {
+ if (gtp_dev_create(-1, devname, gsn->fd0, gsn->fd1u) < 0) {
SYS_ERR(DGGSN, LOGL_ERROR, 0,
"cannot create GTP tunnel device: %s\n",
strerror(errno));
@@ -94,10 +91,9 @@ int gtp_kernel_init(struct gsn_t *gsn, struct in46_prefix *prefix, const char *i
net_arg = in46p_ntoa(prefix);
- DEBUGP(DGGSN, "Setting route to reach %s via %s\n",
- net_arg, GTP_DEVNAME);
+ DEBUGP(DGGSN, "Setting route to reach %s via %s\n", net_arg, devname);
- if (gtp_dev_config(GTP_DEVNAME, &net, prefix->prefixlen) < 0) {
+ if (gtp_dev_config(devname, &net, prefix->prefixlen) < 0) {
SYS_ERR(DGGSN, LOGL_ERROR, 0,
"Cannot add route to reach network %s\n",
net_arg);
@@ -113,8 +109,7 @@ int gtp_kernel_init(struct gsn_t *gsn, struct in46_prefix *prefix, const char *i
int err;
/* eg. /home/ggsn/ipup gtp0 10.0.0.0/8 */
- snprintf(cmd, sizeof(cmd), "%s %s %s",
- ipup, GTP_DEVNAME, net_arg);
+ snprintf(cmd, sizeof(cmd), "%s %s %s", ipup, devname, net_arg);
cmd[sizeof(cmd)-1] = '\0';
err = system(cmd);
@@ -129,15 +124,15 @@ int gtp_kernel_init(struct gsn_t *gsn, struct in46_prefix *prefix, const char *i
return 0;
}
-void gtp_kernel_stop(void)
+void gtp_kernel_stop(const char *devname)
{
if (!gtp_nl.enabled)
return;
- gtp_dev_destroy(GTP_DEVNAME);
+ gtp_dev_destroy(devname);
}
-int gtp_kernel_tunnel_add(struct pdp_t *pdp)
+int gtp_kernel_tunnel_add(struct pdp_t *pdp, const char *devname)
{
struct in_addr ms, sgsn;
struct gtp_tunnel *t;
@@ -155,7 +150,7 @@ int gtp_kernel_tunnel_add(struct pdp_t *pdp)
memcpy(&ms, &pdp->eua.v[2], sizeof(struct in_addr));
memcpy(&sgsn, &pdp->gsnrc.v[0], sizeof(struct in_addr));
- gtp_tunnel_set_ifidx(t, if_nametoindex(GTP_DEVNAME));
+ gtp_tunnel_set_ifidx(t, if_nametoindex(devname));
gtp_tunnel_set_version(t, pdp->version);
gtp_tunnel_set_ms_ip4(t, &ms);
gtp_tunnel_set_sgsn_ip4(t, &sgsn);
@@ -175,7 +170,7 @@ int gtp_kernel_tunnel_add(struct pdp_t *pdp)
return ret;
}
-int gtp_kernel_tunnel_del(struct pdp_t *pdp)
+int gtp_kernel_tunnel_del(struct pdp_t *pdp, const char *devname)
{
struct gtp_tunnel *t;
int ret;
@@ -189,7 +184,7 @@ int gtp_kernel_tunnel_del(struct pdp_t *pdp)
if (t == NULL)
return -1;
- gtp_tunnel_set_ifidx(t, if_nametoindex(GTP_DEVNAME));
+ gtp_tunnel_set_ifidx(t, if_nametoindex(devname));
gtp_tunnel_set_version(t, pdp->version);
if (pdp->version == 0) {
gtp_tunnel_set_tid(t, pdp_gettid(pdp->imsi, pdp->nsapi));
diff --git a/ggsn/gtp-kernel.h b/ggsn/gtp-kernel.h
index ce57994..62a0cd2 100644
--- a/ggsn/gtp-kernel.h
+++ b/ggsn/gtp-kernel.h
@@ -7,29 +7,29 @@ extern int debug;
extern char *ipup;
#ifdef GTP_KERNEL
-int gtp_kernel_init(struct gsn_t *gsn, struct in46_prefix *prefix, const char *ipup);
-void gtp_kernel_stop(void);
+int gtp_kernel_init(struct gsn_t *gsn, const char *devname, struct in46_prefix *prefix, const char *ipup);
+void gtp_kernel_stop(const char *devname);
-int gtp_kernel_tunnel_add(struct pdp_t *pdp);
-int gtp_kernel_tunnel_del(struct pdp_t *pdp);
+int gtp_kernel_tunnel_add(struct pdp_t *pdp, const char *devname);
+int gtp_kernel_tunnel_del(struct pdp_t *pdp, const char *devname);
int gtp_kernel_enabled(void);
#else
-static inline int gtp_kernel_init(struct gsn_t *gsn, struct in46_prefix *prefix, const char *ipup)
+static inline int gtp_kernel_init(struct gsn_t *gsn, const char *devname, struct in46_prefix *prefix, const char *ipup)
{
SYS_ERR(DGGSN, LOGL_ERROR, 0, "ggsn compiled without GTP kernel support!\n");
return -1;
}
-static inline void gtp_kernel_stop(void) {}
+static inline void gtp_kernel_stop(const char *devname) {}
-static inline int gtp_kernel_tunnel_add(struct pdp_t *pdp)
+static inline int gtp_kernel_tunnel_add(struct pdp_t *pdp, const char *devname)
{
return 0;
}
-static inline int gtp_kernel_tunnel_del(struct pdp_t *pdp)
+static inline int gtp_kernel_tunnel_del(struct pdp_t *pdp, const char *devname)
{
return 0;
}