Add default APN for each EUA Type
MS may request an unknown APN. In this case we will use the APN configured in the vty as default-apn but if the type support does not match the request we will fail. The commit adds two more vty commands to configure a default vpn for v6 and for v4v6 Change-Id: I03fcf8a1532bd9988ea99a6afd3dc325174ce9d6 Fixes: OS#4511
This commit is contained in:
parent
04715d284f
commit
a6a8cc1442
46
ggsn/ggsn.c
46
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... */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue