mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-ggsn.git
synced 2025-10-23 08:22:07 +00:00
gtp: Allow setting callback to receive update_context_ind
This will be used by: * SGSN: Get to know that RNC has gonne down according to GGSN (re-attempt Direct Tunnel or go back to tun SGSN<->GGSN). * GGSN: Maybe find out that Direct Flags are used (should be handled internally directly in the rx path probably) Related: OS#6512 Change-Id: Ic80a9a928c55b6ff85be96014920bb42793cb943
This commit is contained in:
@@ -8,3 +8,5 @@
|
||||
# If any interfaces have been removed or changed since the last public release: c:r:0.
|
||||
#library what description / commit summary line
|
||||
libgtp append new field dir_tun_flags in struct pdp_t (older users not using the field should be fine since struct pdp_t is allocated internally)
|
||||
libgtp ABI break new field cb_create_context_ind in struct gsn_t
|
||||
libgtp new API gtp_set_cb_update_context_ind(), gtp_update_context_resp()
|
@@ -497,6 +497,7 @@ int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen,
|
||||
|
||||
/* Initialise call back functions */
|
||||
(*gsn)->cb_create_context_ind = 0;
|
||||
(*gsn)->cb_update_context_ind = 0;
|
||||
(*gsn)->cb_delete_context = 0;
|
||||
(*gsn)->cb_unsup_ind = 0;
|
||||
(*gsn)->cb_conf = 0;
|
||||
@@ -563,6 +564,13 @@ int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gtp_set_cb_update_context_ind(struct gsn_t *gsn,
|
||||
int (*cb_update_context_ind)(struct pdp_t *pdp))
|
||||
{
|
||||
gsn->cb_update_context_ind = cb_update_context_ind;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gtp_retrans(struct gsn_t *gsn)
|
||||
{
|
||||
/* dummy API, deprecated. */
|
||||
|
86
gtp/gtp.c
86
gtp/gtp.c
@@ -1696,10 +1696,11 @@ int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp, void *cbp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Send Update PDP Context Response */
|
||||
static int gtp_update_pdp_resp(struct gsn_t *gsn, uint8_t version,
|
||||
struct sockaddr_in *peer, int fd,
|
||||
void *pack, unsigned len,
|
||||
uint16_t seq, uint64_t tid,
|
||||
struct pdp_t *pdp, uint8_t cause)
|
||||
{
|
||||
|
||||
@@ -1760,7 +1761,22 @@ static int gtp_update_pdp_resp(struct gsn_t *gsn, uint8_t version,
|
||||
}
|
||||
|
||||
return gtp_resp(version, gsn, pdp, &packet, length, peer,
|
||||
fd, get_seq(pack), get_tid(pack));
|
||||
fd, seq, tid);
|
||||
}
|
||||
|
||||
|
||||
/* API: Application response to context indication */
|
||||
int gtp_update_context_resp(struct gsn_t *gsn, struct pdp_t *pdp, int cause)
|
||||
{
|
||||
|
||||
/* Now send off a reply to the peer */
|
||||
gtp_update_pdp_resp(gsn, pdp->version, &pdp->sa_peer,
|
||||
pdp->fd, pdp->seq, pdp->tid, pdp, cause);
|
||||
|
||||
if (!gtp_cause_successful(cause))
|
||||
gtp_freepdp(gsn, pdp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Handle Update PDP Context Request */
|
||||
@@ -1768,13 +1784,15 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
struct sockaddr_in *peer, int fd,
|
||||
void *pack, unsigned len)
|
||||
{
|
||||
struct pdp_t *pdp;
|
||||
struct pdp_t *pdp = NULL;
|
||||
struct pdp_t pdp_backup;
|
||||
union gtpie_member *ie[GTPIE_SIZE];
|
||||
uint8_t recovery;
|
||||
int rc;
|
||||
|
||||
uint16_t seq = get_seq(pack);
|
||||
int hlen = get_hlen(pack);
|
||||
uint64_t tid = get_tid(pack);
|
||||
|
||||
uint64_t imsi;
|
||||
uint8_t nsapi;
|
||||
@@ -1792,8 +1810,8 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
if (0 == version)
|
||||
return EOF;
|
||||
else
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
|
||||
len, NULL,
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, seq,
|
||||
tid, NULL,
|
||||
GTPCAUSE_INVALID_MESSAGE);
|
||||
}
|
||||
|
||||
@@ -1808,8 +1826,8 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
|
||||
"Unknown PDP context: TID=0x%" PRIx64 "\n",
|
||||
get_tid(pack));
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
|
||||
len, NULL,
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, seq,
|
||||
tid, NULL,
|
||||
GTPCAUSE_NON_EXIST);
|
||||
}
|
||||
|
||||
@@ -1821,8 +1839,8 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
rate_ctr_inc2(gsn->ctrg, GSN_CTR_PKT_MISSING);
|
||||
GTP_LOGPKG(LOGL_ERROR, peer, pack,
|
||||
len, "Missing mandatory information field\n");
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
|
||||
len, NULL,
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, seq,
|
||||
tid, NULL,
|
||||
GTPCAUSE_MAN_IE_MISSING);
|
||||
}
|
||||
|
||||
@@ -1835,7 +1853,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
"Unknown PDP context: TEI=0x%" PRIx32 "\n",
|
||||
get_tei(pack));
|
||||
return gtp_update_pdp_resp(gsn, version, peer,
|
||||
fd, pack, len, NULL,
|
||||
fd, seq, tid, NULL,
|
||||
GTPCAUSE_NON_EXIST);
|
||||
}
|
||||
} else {
|
||||
@@ -1846,7 +1864,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
"Unknown PDP context: IMSI=0x%" PRIx64
|
||||
" NSAPI=%" PRIu8 "\n", imsi, nsapi);
|
||||
return gtp_update_pdp_resp(gsn, version, peer,
|
||||
fd, pack, len, NULL,
|
||||
fd, seq, tid, NULL,
|
||||
GTPCAUSE_NON_EXIST);
|
||||
}
|
||||
}
|
||||
@@ -1855,6 +1873,12 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/* Update internal state to be used when user calls gtp_update_context_resp(): */
|
||||
pdp->seq = seq;
|
||||
pdp->sa_peer = *peer;
|
||||
pdp->fd = fd;
|
||||
pdp->version = version;
|
||||
|
||||
/* Make a backup copy in case anything is wrong */
|
||||
memcpy(&pdp_backup, pdp, sizeof(pdp_backup));
|
||||
|
||||
@@ -1865,8 +1889,8 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
GTP_LOGPKG(LOGL_ERROR, peer, pack,
|
||||
len, "Missing mandatory information field\n");
|
||||
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
|
||||
len, pdp,
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, seq,
|
||||
tid, pdp,
|
||||
GTPCAUSE_MAN_IE_MISSING);
|
||||
}
|
||||
}
|
||||
@@ -1882,8 +1906,8 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
GTP_LOGPKG(LOGL_ERROR, peer, pack,
|
||||
len, "Missing mandatory information field\n");
|
||||
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
|
||||
len, pdp,
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, seq,
|
||||
tid, pdp,
|
||||
GTPCAUSE_MAN_IE_MISSING);
|
||||
}
|
||||
|
||||
@@ -1892,8 +1916,8 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
GTP_LOGPKG(LOGL_ERROR, peer, pack,
|
||||
len, "Missing mandatory information field\n");
|
||||
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
|
||||
len, pdp,
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, seq,
|
||||
tid, pdp,
|
||||
GTPCAUSE_MAN_IE_MISSING);
|
||||
}
|
||||
}
|
||||
@@ -1906,8 +1930,8 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
GTP_LOGPKG(LOGL_ERROR, peer, pack,
|
||||
len, "Missing mandatory information field\n");
|
||||
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
|
||||
len, pdp,
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, seq,
|
||||
tid, pdp,
|
||||
GTPCAUSE_MAN_IE_MISSING);
|
||||
}
|
||||
|
||||
@@ -1923,8 +1947,8 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
GTP_LOGPKG(LOGL_ERROR, peer, pack,
|
||||
len, "Missing mandatory information field\n");
|
||||
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
|
||||
len, pdp,
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, seq,
|
||||
tid, pdp,
|
||||
GTPCAUSE_MAN_IE_MISSING);
|
||||
}
|
||||
}
|
||||
@@ -1951,7 +1975,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
|
||||
"Missing mandatory information field\n");
|
||||
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len,
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, seq, tid,
|
||||
pdp, GTPCAUSE_MAN_IE_MISSING);
|
||||
}
|
||||
|
||||
@@ -1963,7 +1987,7 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
GTP_LOGPKG(LOGL_ERROR, peer, pack, len,
|
||||
"Missing mandatory information field\n");
|
||||
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len,
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, seq, tid,
|
||||
pdp, GTPCAUSE_MAN_IE_MISSING);
|
||||
}
|
||||
|
||||
@@ -1976,8 +2000,8 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
GTP_LOGPKG(LOGL_ERROR, peer, pack,
|
||||
len, "Missing mandatory information field\n");
|
||||
memcpy(pdp, &pdp_backup, sizeof(pdp_backup));
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, pack,
|
||||
len, pdp,
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, seq,
|
||||
tid, pdp,
|
||||
GTPCAUSE_MAN_IE_MISSING);
|
||||
}
|
||||
|
||||
@@ -1994,9 +2018,17 @@ static int gtp_update_pdp_ind(struct gsn_t *gsn, uint8_t version,
|
||||
}
|
||||
}
|
||||
|
||||
/* Callback function to validate login */
|
||||
if (gsn->cb_update_context_ind != 0)
|
||||
rc = gsn->cb_update_context_ind(pdp);
|
||||
else {
|
||||
/* Confirm to peer that things were "successful" */
|
||||
rc = gtp_update_pdp_resp(gsn, version, peer, fd, seq, tid, pdp,
|
||||
GTPCAUSE_ACC_REQ);
|
||||
}
|
||||
|
||||
/* Confirm to peer that things were "successful" */
|
||||
return gtp_update_pdp_resp(gsn, version, peer, fd, pack, len, pdp,
|
||||
GTPCAUSE_ACC_REQ);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Handle Update PDP Context Response */
|
||||
|
@@ -99,6 +99,7 @@ struct gsn_t {
|
||||
/* Call back functions */
|
||||
int (*cb_delete_context) (struct pdp_t *);
|
||||
int (*cb_create_context_ind) (struct pdp_t *);
|
||||
int (*cb_update_context_ind)(struct pdp_t *pdp);
|
||||
int (*cb_unsup_ind) (struct sockaddr_in * peer);
|
||||
int (*cb_extheader_ind) (struct sockaddr_in * peer);
|
||||
int (*cb_ran_info_relay_ind) (struct sockaddr_in *peer, union gtpie_member **ie);
|
||||
@@ -134,6 +135,8 @@ extern int gtp_set_cb_create_context_ind(struct gsn_t *gsn,
|
||||
int (*cb_create_context_ind) (struct
|
||||
pdp_t *
|
||||
pdp));
|
||||
extern int gtp_set_cb_update_context_ind(struct gsn_t *gsn,
|
||||
int (*cb_update_context_ind)(struct pdp_t *pdp));
|
||||
extern int gtp_set_cb_data_ind(struct gsn_t *gsn,
|
||||
int (*cb_data_ind) (struct pdp_t * pdp,
|
||||
void *pack, unsigned len));
|
||||
|
@@ -248,6 +248,9 @@ extern int gtp_create_context_resp(struct gsn_t *gsn, struct pdp_t *pdp,
|
||||
extern int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp,
|
||||
void *cbp, struct in_addr *inetaddr);
|
||||
|
||||
extern int gtp_update_context_resp(struct gsn_t *gsn, struct pdp_t *pdp,
|
||||
int cause);
|
||||
|
||||
extern int gtp_delete_context_req(struct gsn_t *gsn, struct pdp_t *pdp,
|
||||
void *cbp, int teardown)
|
||||
OSMO_DEPRECATED("Use gtp_delete_context_req2() instead, to avoid freeing pdp ctx before reply");
|
||||
|
Reference in New Issue
Block a user