aboutsummaryrefslogtreecommitdiffstats
path: root/ggsn
diff options
context:
space:
mode:
Diffstat (limited to 'ggsn')
-rw-r--r--ggsn/ggsn.c46
-rw-r--r--ggsn/ggsn.h6
-rw-r--r--ggsn/ggsn_vty.c54
3 files changed, 77 insertions, 29 deletions
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c
index 159362f..81d8509 100644
--- a/ggsn/ggsn.c
+++ b/ggsn/ggsn.c
@@ -446,16 +446,44 @@ int create_context_ind(struct pdp_t *pdp)
LOGPPDP(LOGL_DEBUG, pdp, "Processing create PDP context request for APN '%s'\n",
apn_name ? name_buf : "(NONE)");
+ /* FIXME: we manually force all context requests to dynamic here! */
+ if (pdp->eua.l > 2)
+ pdp->eua.l = 2;
+
+ memset(addr, 0, sizeof(addr));
+ if ((num_addr = in46a_from_eua(&pdp->eua, addr)) < 0) {
+ LOGPPDP(LOGL_ERROR, pdp, "Cannot decode EUA from MS/SGSN: %s\n",
+ osmo_hexdump(pdp->eua.v, pdp->eua.l));
+ gtp_create_context_resp(gsn, pdp, GTPCAUSE_UNKNOWN_PDP);
+ return 0;
+ }
+
/* First find an exact APN name match */
if (apn_name != NULL)
apn = ggsn_find_apn(ggsn, name_buf);
/* ignore if the APN has not been started */
if (apn && !apn->started)
apn = NULL;
-
/* then try default (if any) */
- if (!apn)
- apn = ggsn->cfg.default_apn;
+ if (!apn) {
+ switch (num_addr) {
+ case 2:
+ apn = ggsn->cfg.default_apn_v4v6;
+ break;
+ case 1:
+ if (in46a_is_v4(&addr[0])) {
+ apn = ggsn->cfg.default_apn_v4;
+ } else {
+ apn = ggsn->cfg.default_apn_v6;
+ }
+ break;
+ default:
+ /* in46a_from_eua() returned other than 1 or 2 ? */
+ OSMO_ASSERT(0);
+ break;
+ }
+ }
+
/* ignore if the APN has not been started */
if (apn && !apn->started)
apn = NULL;
@@ -467,23 +495,11 @@ int create_context_ind(struct pdp_t *pdp)
return 0;
}
- /* FIXME: we manually force all context requests to dynamic here! */
- if (pdp->eua.l > 2)
- pdp->eua.l = 2;
-
memcpy(pdp->qos_neg0, pdp->qos_req0, sizeof(pdp->qos_req0));
memcpy(pdp->qos_neg.v, pdp->qos_req.v, pdp->qos_req.l); /* TODO */
pdp->qos_neg.l = pdp->qos_req.l;
- memset(addr, 0, sizeof(addr));
- if ((num_addr = in46a_from_eua(&pdp->eua, addr)) < 0) {
- LOGPPDP(LOGL_ERROR, pdp, "Cannot decode EUA from MS/SGSN: %s\n",
- osmo_hexdump(pdp->eua.v, pdp->eua.l));
- gtp_create_context_resp(gsn, pdp, GTPCAUSE_UNKNOWN_PDP);
- return 0;
- }
-
/* Store the actual APN for logging and the VTY */
rc = osmo_apn_from_str(pdp->apn_use.v, sizeof(pdp->apn_use.v), apn->cfg.name);
if (rc < 0) /* Unlikely this would happen, but anyway... */
diff --git a/ggsn/ggsn.h b/ggsn/ggsn.h
index 82984a0..51f4ec1 100644
--- a/ggsn/ggsn.h
+++ b/ggsn/ggsn.h
@@ -115,8 +115,10 @@ struct ggsn_ctx {
char *name;
/* Description string */
char *description;
- /* an APN that shall be used as default for any non-matching APN */
- struct apn_ctx *default_apn;
+ /* APNs that shall be used as default for any non-matching APN */
+ struct apn_ctx *default_apn_v4;
+ struct apn_ctx *default_apn_v6;
+ struct apn_ctx *default_apn_v4v6;
/* ADdress to which we listen for GTP */
struct in46_addr listen_addr;
/* Local GTP-C address advertised in GTP */
diff --git a/ggsn/ggsn_vty.c b/ggsn/ggsn_vty.c
index cb92a8a..740ac08 100644
--- a/ggsn/ggsn_vty.c
+++ b/ggsn/ggsn_vty.c
@@ -269,30 +269,55 @@ DEFUN(cfg_ggsn_no_apn, cfg_ggsn_no_apn_cmd,
return CMD_SUCCESS;
}
-DEFUN(cfg_ggsn_default_apn, cfg_ggsn_default_apn_cmd,
- "default-apn NAME",
+DEFUN(cfg_ggsn_default_apn_v4, cfg_ggsn_default_apn_v4_cmd,
+ "default-apn (v4|v6|v4v6) NAME",
"Set a default-APN to be used if no other APN matches\n"
+ "Set a default-APN to be used if no other APN v4 matches\n"
+ "Set a default-APN to be used if no other APN v6 matches\n"
+ "Set a default-APN to be used if no other APN v4v6 matches\n"
"APN Name\n")
{
struct ggsn_ctx *ggsn = (struct ggsn_ctx *) vty->index;
struct apn_ctx *apn;
- apn = ggsn_find_apn(ggsn, argv[0]);
+ /* backwards compatibility with 'default-apn NAME'. */
+ const char *apn_name = (argc > 1) ? argv[1] : argv[0];
+ const char *apn_type = (argc > 1) ? argv[0] : "v4";
+
+ apn = ggsn_find_apn(ggsn, apn_name);
if (!apn) {
- vty_out(vty, "%% No APN of name '%s' found%s", argv[0], VTY_NEWLINE);
+ vty_out(vty, "%% No APN of name '%s' found%s", apn_name, VTY_NEWLINE);
return CMD_WARNING;
}
- ggsn->cfg.default_apn = apn;
+ if (!strcmp(apn_type, "v4"))
+ ggsn->cfg.default_apn_v4 = apn;
+ if (!strcmp(apn_type, "v6"))
+ ggsn->cfg.default_apn_v6 = apn;
+ if (!strcmp(apn_type, "v4v6"))
+ ggsn->cfg.default_apn_v4v6 = apn;
return CMD_SUCCESS;
}
-DEFUN(cfg_ggsn_no_default_apn, cfg_ggsn_no_default_apn_cmd,
- "no default-apn",
- NO_STR "Remove default-APN to be used if no other APN matches\n")
+ALIAS_DEPRECATED(cfg_ggsn_default_apn_v4, cfg_ggsn_default_apn_cmd,
+ "default-apn NAME",
+ "Set a default-APN to be used if no other APN matches\n"
+ "APN Name\n")
+
+DEFUN(cfg_ggsn_no_default_apn_v4, cfg_ggsn_no_default_apn_v4_cmd,
+ "no default-apn (v4|v6|v4v6)",
+ NO_STR "Remove default-APN to be used if no other APN v4 matches\n"
+ "Remove default-APN to be used if no other APN v4 matches\n"
+ "Remove default-APN to be used if no other APN v6 matches\n"
+ "Remove default-APN to be used if no other APN v4v6 matches\n")
{
struct ggsn_ctx *ggsn = (struct ggsn_ctx *) vty->index;
- ggsn->cfg.default_apn = NULL;
+ if (!strcmp(argv[0], "v4"))
+ ggsn->cfg.default_apn_v4 = NULL;
+ if (!strcmp(argv[0], "v6"))
+ ggsn->cfg.default_apn_v6 = NULL;
+ if (!strcmp(argv[0], "v4v6"))
+ ggsn->cfg.default_apn_v4v6 = NULL;
return CMD_SUCCESS;
}
@@ -790,8 +815,12 @@ static int config_write_ggsn(struct vty *vty)
vty_out(vty, " gtp user-ip %s%s", in46a_ntoa(&ggsn->cfg.gtpu_addr), VTY_NEWLINE);
llist_for_each_entry(apn, &ggsn->apn_list, list)
config_write_apn(vty, apn);
- if (ggsn->cfg.default_apn)
- vty_out(vty, " default-apn %s%s", ggsn->cfg.default_apn->cfg.name, VTY_NEWLINE);
+ if (ggsn->cfg.default_apn_v4)
+ vty_out(vty, " default-apn v4 %s%s", ggsn->cfg.default_apn_v4->cfg.name, VTY_NEWLINE);
+ if (ggsn->cfg.default_apn_v6)
+ vty_out(vty, " default-apn v6 %s%s", ggsn->cfg.default_apn_v6->cfg.name, VTY_NEWLINE);
+ if (ggsn->cfg.default_apn_v4v6)
+ vty_out(vty, " default-apn v4v6 %s%s", ggsn->cfg.default_apn_v4v6->cfg.name, VTY_NEWLINE);
if (ggsn->cfg.echo_interval)
vty_out(vty, " echo-interval %u%s", ggsn->cfg.echo_interval, VTY_NEWLINE);
/* must be last */
@@ -1096,7 +1125,8 @@ int ggsn_vty_init(void)
install_element(GGSN_NODE, &cfg_ggsn_apn_cmd);
install_element(GGSN_NODE, &cfg_ggsn_no_apn_cmd);
install_element(GGSN_NODE, &cfg_ggsn_default_apn_cmd);
- install_element(GGSN_NODE, &cfg_ggsn_no_default_apn_cmd);
+ install_element(GGSN_NODE, &cfg_ggsn_default_apn_v4_cmd);
+ install_element(GGSN_NODE, &cfg_ggsn_no_default_apn_v4_cmd);
install_element(GGSN_NODE, &cfg_ggsn_show_sgsn_cmd);
install_element(GGSN_NODE, &cfg_ggsn_echo_interval_cmd);
install_element(GGSN_NODE, &cfg_ggsn_no_echo_interval_cmd);