mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-ggsn.git
synced 2025-10-23 00:12:08 +00:00
ggsn: kernel gtpu: Support updating pdp ctx remote IP address and TEID
Whenever the SGSN sends the GGSN a UpdatePDPCtxReq, it may offer a new remote IP address or/and remote TEID, eg. because it wants to establish a Direct Tunnel and point the GTPU towards the RNC, or to point it back to itself. If the gtpu kernel is used, osmo-ggsn lacked updating the kernel with the new remote data. The gtp kernel module doesn't provide an efficient/explicit way to update a pdp context keeping the4 same local IP+TEID and changing only the remote remote IP+TEID, hence first destroy the pdp ctx in the gtp kernel module and then recreate it. This fixes test GGSN_Tests_v4_only.TC_pdp4_act_update_teid in ttcn3-ggsn-test-kernel-net-next. Related: OS#6523 Change-Id: I1fc48be5c0f177ccf6fbe97c003b4df44809c0fe
This commit is contained in:
38
ggsn/ggsn.c
38
ggsn/ggsn.c
@@ -582,6 +582,41 @@ err_wrong_af:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int update_context_ind(struct pdp_t *pdp)
|
||||
{
|
||||
char apn_name[256];
|
||||
struct gsn_t *gsn = pdp->gsn;
|
||||
struct ggsn_ctx *ggsn = gsn->priv;
|
||||
struct apn_ctx *apn;
|
||||
bool apn_found = false;
|
||||
int rc;
|
||||
|
||||
if (!osmo_apn_to_str(apn_name, pdp->apn_use.v, pdp->apn_use.l)) {
|
||||
LOGPPDP(LOGL_ERROR, pdp, "Unable to decode associated APN len=%d buf: %s\n",
|
||||
pdp->apn_use.l, osmo_hexdump(pdp->apn_use.v, pdp->apn_use.l));
|
||||
return gtp_update_context_resp(ggsn->gsn, pdp, GTPCAUSE_MISSING_APN);
|
||||
}
|
||||
|
||||
llist_for_each_entry (apn, &ggsn->apn_list, list) {
|
||||
if (strncmp(apn_name, apn->cfg.name, sizeof(apn_name)) != 0)
|
||||
continue;
|
||||
apn_found = true;
|
||||
break;
|
||||
}
|
||||
if (!apn_found) {
|
||||
LOGPPDP(LOGL_ERROR, pdp, "Unable to find associated APN %s\n", apn_name);
|
||||
return gtp_update_context_resp(ggsn->gsn, pdp, GTPCAUSE_MISSING_APN);
|
||||
}
|
||||
|
||||
if (apn->cfg.gtpu_mode == APN_GTPU_MODE_KERNEL_GTP) {
|
||||
/* Update the kernel with the potentially new remote data IP address + TEID */
|
||||
gtp_kernel_tunnel_del(pdp, apn->tun.cfg.dev_name);
|
||||
gtp_kernel_tunnel_add(pdp, apn->tun.cfg.dev_name);
|
||||
}
|
||||
rc = gtp_update_context_resp(ggsn->gsn, pdp, GTPCAUSE_ACC_REQ);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Internet-originated IP packet, needs to be sent via GTP towards MS */
|
||||
static int cb_tun_ind(struct tun_t *tun, void *pack, unsigned len)
|
||||
{
|
||||
@@ -848,8 +883,9 @@ int ggsn_start(struct ggsn_ctx *ggsn)
|
||||
OSMO_ASSERT(rc == 0);
|
||||
|
||||
gtp_set_cb_data_ind(ggsn->gsn, encaps_tun);
|
||||
gtp_set_cb_delete_context(ggsn->gsn, delete_context);
|
||||
gtp_set_cb_create_context_ind(ggsn->gsn, create_context_ind);
|
||||
gtp_set_cb_update_context_ind(ggsn->gsn, update_context_ind);
|
||||
gtp_set_cb_delete_context(ggsn->gsn, delete_context);
|
||||
gtp_set_cb_conf(ggsn->gsn, cb_conf);
|
||||
gtp_set_cb_recovery3(ggsn->gsn, cb_recovery3);
|
||||
|
||||
|
Reference in New Issue
Block a user