matanp has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-sgsn/+/35781?usp=email )
Change subject: ctrl: Add ctrl trap on PDP Context changes ......................................................................
ctrl: Add ctrl trap on PDP Context changes
This change allows to easily understand PDP context status changes. The trap sent contains the following (in a comma delimited format): status, IMSI, SAPI, NSAPI, TI, APN if found, IP address if found, IPv6 address in case the MS has both.
Change-Id: Ie0ab550125372047e8267f008fe1dfd0cc70148a --- M include/osmocom/sgsn/sgsn.h M src/sgsn/sgsn.c M src/sgsn/sgsn_ctrl.c 3 files changed, 94 insertions(+), 3 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-sgsn refs/changes/81/35781/1
diff --git a/include/osmocom/sgsn/sgsn.h b/include/osmocom/sgsn/sgsn.h index 6e93178..75a70ec 100644 --- a/include/osmocom/sgsn/sgsn.h +++ b/include/osmocom/sgsn/sgsn.h @@ -169,7 +169,7 @@ /* * ctrl interface related work (sgsn_ctrl.c) */ -int sgsn_ctrl_cmds_install(void); +int sgsn_ctrl_cmds_install(struct sgsn_instance *sgsn);
/* sgsn_vty.c */
diff --git a/src/sgsn/sgsn.c b/src/sgsn/sgsn.c index 6619bf2..99ad031 100644 --- a/src/sgsn/sgsn.c +++ b/src/sgsn/sgsn.c @@ -200,7 +200,7 @@ return -EIO; }
- rc = sgsn_ctrl_cmds_install(); + rc = sgsn_ctrl_cmds_install(sgsn); if (rc != 0) { LOGP(DGPRS, LOGL_ERROR, "Failed to install CTRL commands.\n"); return -EFAULT; diff --git a/src/sgsn/sgsn_ctrl.c b/src/sgsn/sgsn_ctrl.c index 069304a..addb85e 100644 --- a/src/sgsn/sgsn_ctrl.c +++ b/src/sgsn/sgsn_ctrl.c @@ -25,6 +25,8 @@ #include <osmocom/sgsn/pdpctx.h> #include <osmocom/sgsn/sgsn.h> #include <osmocom/sgsn/debug.h> +#include <osmocom/sgsn/signal.h> +#include <osmocom/gsm/apn.h>
#include <pdp.h>
@@ -53,9 +55,84 @@ } CTRL_CMD_DEFINE_RO(subscriber_list, "subscriber-list-active-v1");
-int sgsn_ctrl_cmds_install(void) +/* Sends trap for PDP context status changes. + * format: <status>,<imsi>,<sapi>,<nsapi>,<ti>,<apn>,<ip>[,<ipv6>] + */ +static int handle_pdp_status_change(unsigned int subsys, unsigned int signal, + void *handler_data, void *_signal_data) +{ + struct sgsn_signal_data *signal_data = _signal_data; + struct sgsn_instance *inst = handler_data; + struct sgsn_pdp_ctx *pdp = signal_data->pdp; + struct ctrl_cmd *cmd; + char *status, *imsi; + char apnbuf[APN_MAXLEN + 1]; + + if (subsys != SS_SGSN) + return 0; + + if (!pdp) + return 0; + + switch (signal) { + case S_SGSN_PDP_ACT: + status = "activate"; + break; + case S_SGSN_PDP_DEACT: + status = "deactivate"; + break; + case S_SGSN_PDP_TERMINATE: + status = "terminate"; + break; + case S_SGSN_PDP_FREE: + status = "free"; + break; + default: + return 0; + } + + cmd = ctrl_cmd_create(NULL, CTRL_TYPE_TRAP); + if (!cmd) + goto err; + + cmd->id = "0"; + cmd->node = inst; + cmd->variable = "pdp_status"; + + imsi = pdp->mm ? pdp->mm->imsi : ""; + cmd->reply = talloc_asprintf(cmd, "%s,%s,%u,%u,%u", status, imsi, pdp->sapi, pdp->nsapi, pdp->ti); + + if (!cmd->reply) + goto err; + + if (pdp->lib) { + cmd->reply = talloc_asprintf_append(cmd->reply, ",%s,%s", + osmo_apn_to_str(apnbuf, pdp->lib->apn_use.v, pdp->lib->apn_use.l), + gprs_pdpaddr2str(pdp->lib->eua.v, pdp->lib->eua.l, false)); + if (!cmd->reply) + goto err; + + if (pdp->lib->eua.v[1] == PDP_TYPE_N_IETF_IPv4v6) { + cmd->reply = talloc_asprintf_append(cmd->reply, ",%s", + gprs_pdpaddr2str(pdp->lib->eua.v, pdp->lib->eua.l, true)); + if (!cmd->reply) + goto err; + } + } + + ctrl_cmd_send_to_all(inst->ctrlh, cmd); + talloc_free(cmd); + return 0; + +err: + LOGP(DCTRL, LOGL_ERROR, "Trap creation failed.\n"); + return 0; +} + +int sgsn_ctrl_cmds_install(struct sgsn_instance *sgsn) { int rc = 0; rc |= ctrl_cmd_install(CTRL_NODE_ROOT, &cmd_subscriber_list); + rc |= osmo_signal_register_handler(SS_SGSN, handle_pdp_status_change, sgsn); return rc; }