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
This commit is contained in:
Matan Perelman 2024-02-02 14:39:59 +02:00
parent dc4c294f94
commit 4c7020f376
3 changed files with 80 additions and 3 deletions

View File

@ -169,7 +169,7 @@ extern void *tall_sgsn_ctx;
/*
* 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 */

View File

@ -200,7 +200,7 @@ int sgsn_inst_init(struct sgsn_instance *sgsn)
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;

View File

@ -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 @@ static int get_subscriber_list(struct ctrl_cmd *cmd, void *d)
}
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;
}