Harald Welte has submitted this change and it was merged. ( https://gerrit.osmocom.org/c/osmo-ggsn/+/14296 )
Change subject: gtp: Introduce new pdp APIs (and deprecate old ones) to support multiple GSN ...................................................................... gtp: Introduce new pdp APIs (and deprecate old ones) to support multiple GSN Move static global pdp storage arrays to be per GSN. This way now several GSN per process are supported without collisions. * pdp_init() is defined in public API but it's actually only intended for use (and currently only used) internally in gtp_new(). So let's document that and re-use it for backward compatibility with now deprecated API, where only one GSN per process is supported. * Back pointer to gsn_t (pdp->gsn) moved from gtp.c:gtp_new() to gtp_pdp_newpdp(), since it makes more sense to have it there. This way backpointer is always set, even in case were app calls pdp_newpdp() API directly instead of creating them through gtp.c, like osmo-sgsn does. * Create new versions of required APIs with a pointer to gsn_t where the pdp ctx is to be created/found. Some APIs receiving a pointer to a pdp ctx can be left intact because we have a backpointer to its gsn_t. * pdp_getpdp() is nowhere used, and makes little sense now that we have pdpa reachable in gsn->pdpa, so let's deprecate it without adding a replacement. * Deprecate gtp.h gtp_newpdp(), since it's nowhere used and useless (does same as new gtp_pdp_newpdp() and doesn't allow for old_pdp to be passed as parameter). Fixes: OS#2873 Change-Id: I653cbdc185165592d985e3efab6e3f1add97877b --- M TODO-RELEASE M gtp/gtp.c M gtp/gtp.h M gtp/pdp.c M gtp/pdp.h 5 files changed, 90 insertions(+), 37 deletions(-) Approvals: Jenkins Builder: Verified Harald Welte: Looks good to me, approved diff --git a/TODO-RELEASE b/TODO-RELEASE index d0852fc..a3d63ac 100644 --- a/TODO-RELEASE +++ b/TODO-RELEASE @@ -7,3 +7,6 @@ # If any interfaces have been added since the last public release: c:r:a + 1. # If any interfaces have been removed or changed since the last public release: c:r:0. #library what description / commit summary line +libgtp Several new APIs added see I653cbdc185165592d985e3efab6e3f1add97877b +libgtp API (non-used externally) pdp_init modified see I653cbdc185165592d985e3efab6e3f1add97877b +libgtp Several pdp_* APIs marked as deprecated see I653cbdc185165592d985e3efab6e3f1add97877b diff --git a/gtp/gtp.c b/gtp/gtp.c index 2b14026..84b8844 100644 --- a/gtp/gtp.c +++ b/gtp/gtp.c @@ -131,16 +131,12 @@ { 0, NULL } }; -/* gtp_new */ -/* gtp_free */ - +/* Deprecated, use gtp_pdp_newpdp() instead */ int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi) { int rc; - rc = pdp_newpdp(pdp, imsi, nsapi, NULL); - if (!rc && *pdp) - (*pdp)->gsn = gsn; + rc = gtp_pdp_newpdp(gsn, pdp, imsi, nsapi, NULL); return rc; } @@ -849,7 +845,7 @@ queue_new(&(*gsn)->queue_resp); /* Initialise pdp table */ - pdp_init(); + pdp_init(*gsn); /* Initialise call back functions */ (*gsn)->cb_create_context_ind = 0; @@ -1681,9 +1677,7 @@ } } - pdp_newpdp(&pdp, pdp->imsi, pdp->nsapi, pdp); - if (pdp) - pdp->gsn = gsn; + gtp_pdp_newpdp(gsn, &pdp, pdp->imsi, pdp->nsapi, pdp); /* Callback function to validate login */ if (gsn->cb_create_context_ind != 0) diff --git a/gtp/gtp.h b/gtp/gtp.h index ec6aef3..c2c5122 100644 --- a/gtp/gtp.h +++ b/gtp/gtp.h @@ -15,6 +15,8 @@ #include <osmocom/core/utils.h> #include <osmocom/core/defs.h> +#include "pdp.h" + #define GTP_MODE_GGSN 1 #define GTP_MODE_SGSN 2 @@ -263,6 +265,9 @@ struct queue_t *queue_req; /* Request queue */ struct queue_t *queue_resp; /* Response queue */ + struct pdp_t pdpa[PDP_MAX]; /* PDP storage */ + struct pdp_t *hashtid[PDP_MAX]; /* Hash table for IMSI + NSAPI */ + /* Call back functions */ int (*cb_delete_context) (struct pdp_t *); int (*cb_create_context_ind) (struct pdp_t *); @@ -307,7 +312,7 @@ extern int gtp_free(struct gsn_t *gsn); extern int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp, - uint64_t imsi, uint8_t nsapi); + uint64_t imsi, uint8_t nsapi) OSMO_DEPRECATED("Use gtp_pdp_newpdp() instead"); extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp); extern int gtp_freepdp_teardown(struct gsn_t *gsn, struct pdp_t *pdp); diff --git a/gtp/pdp.c b/gtp/pdp.c index a5146e9..d745916 100644 --- a/gtp/pdp.c +++ b/gtp/pdp.c @@ -33,13 +33,6 @@ #include "lookupa.h" /* *********************************************************** - * Global variables TODO: most should be moved to gsn_t - *************************************************************/ - -static struct pdp_t pdpa[PDP_MAX]; /* PDP storage */ -static struct pdp_t *hashtid[PDP_MAX]; /* Hash table for IMSI + NSAPI */ - -/* *********************************************************** * Functions related to PDP storage * * Lifecycle @@ -111,11 +104,16 @@ * *************************************************************/ -int pdp_init() +static struct gsn_t *g_gsn; + +int pdp_init(struct gsn_t *gsn) { - memset(&pdpa, 0, sizeof(pdpa)); - memset(&hashtid, 0, sizeof(hashtid)); - /* memset(&haship, 0, sizeof(haship)); */ + if(!g_gsn) { + g_gsn = gsn; + } else { + LOGP(DLGTP, LOGL_FATAL, "This interface is depreacted and doesn't support multiple GGSN!"); + return -1; + } return 0; } @@ -123,6 +121,13 @@ int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi, struct pdp_t *pdp_old) { + return gtp_pdp_newpdp(g_gsn, pdp, imsi, nsapi, pdp_old); +} + +int gtp_pdp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi, + struct pdp_t *pdp_old) +{ + struct pdp_t *pdpa = gsn->pdpa; int n; for (n = 0; n < PDP_MAX; n++) { /* TODO: Need to do better than linear search */ if (pdpa[n].inuse == 0) { @@ -132,6 +137,7 @@ else memset(*pdp, 0, sizeof(struct pdp_t)); (*pdp)->inuse = 1; + (*pdp)->gsn = gsn; (*pdp)->imsi = imsi; (*pdp)->nsapi = nsapi; (*pdp)->fllc = (uint16_t) n + 1; @@ -159,6 +165,8 @@ int pdp_freepdp(struct pdp_t *pdp) { + struct pdp_t *pdpa = pdp->gsn->pdpa; + pdp_tiddel(pdp); /* Remove any references in primary context */ @@ -173,12 +181,20 @@ int pdp_getpdp(struct pdp_t **pdp) { - *pdp = &pdpa[0]; + *pdp = &g_gsn->pdpa[0]; return 0; } int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl) { + return gtp_pdp_getgtp0(g_gsn, pdp, fl); +} + + +int gtp_pdp_getgtp0(struct gsn_t *gsn, struct pdp_t **pdp, uint16_t fl) +{ + struct pdp_t *pdpa = gsn->pdpa; + if ((fl > PDP_MAX) || (fl < 1)) { return EOF; /* Not found */ } else { @@ -193,6 +209,13 @@ int pdp_getgtp1(struct pdp_t **pdp, uint32_t tei) { + return gtp_pdp_getgtp1(g_gsn, pdp, tei); +} + +int gtp_pdp_getgtp1(struct gsn_t *gsn, struct pdp_t **pdp, uint32_t tei) +{ + struct pdp_t *pdpa = gsn->pdpa; + if ((tei > PDP_MAX) || (tei < 1)) { return EOF; /* Not found */ } else { @@ -208,6 +231,12 @@ /* get a PDP based on the *peer* address + TEI-Data. Used for matching inbound Error Ind */ int pdp_getgtp1_peer_d(struct pdp_t **pdp, const struct sockaddr_in *peer, uint32_t teid_gn) { + return gtp_pdp_getgtp1_peer_d(g_gsn, pdp, peer, teid_gn); +} + +int gtp_pdp_getgtp1_peer_d(struct gsn_t *gsn, struct pdp_t **pdp, const struct sockaddr_in *peer, uint32_t teid_gn) +{ + struct pdp_t *pdpa = gsn->pdpa; unsigned int i; /* this is O(n) but we don't have (nor want) another hash... */ @@ -230,6 +259,7 @@ int pdp_tidset(struct pdp_t *pdp, uint64_t tid) { + struct pdp_t **hashtid = pdp->gsn->hashtid; int hash = pdp_tidhash(tid); struct pdp_t *pdp2; struct pdp_t *pdp_prev = NULL; @@ -248,6 +278,7 @@ int pdp_tiddel(struct pdp_t *pdp) { + struct pdp_t **hashtid = pdp->gsn->hashtid; int hash = pdp_tidhash(pdp->tid); struct pdp_t *pdp2; struct pdp_t *pdp_prev = NULL; @@ -269,6 +300,12 @@ int pdp_tidget(struct pdp_t **pdp, uint64_t tid) { + return gtp_pdp_tidget(g_gsn, pdp, tid); +} + +int gtp_pdp_tidget(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t tid) +{ + struct pdp_t **hashtid = gsn->hashtid; int hash = pdp_tidhash(tid); struct pdp_t *pdp2; DEBUGP(DLGTP, "Begin pdp_tidget tid = %"PRIx64"\n", tid); @@ -285,7 +322,12 @@ int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi) { - return pdp_tidget(pdp, + return gtp_pdp_getimsi(g_gsn, pdp, imsi, nsapi); +} + +int gtp_pdp_getimsi(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi) +{ + return gtp_pdp_tidget(gsn, pdp, (imsi & 0x0fffffffffffffffull) + ((uint64_t) nsapi << 60)); } diff --git a/gtp/pdp.h b/gtp/pdp.h index a287113..9527464 100644 --- a/gtp/pdp.h +++ b/gtp/pdp.h @@ -15,6 +15,8 @@ #include <stdbool.h> +#include <osmocom/core/defs.h> + struct gsn_t; #define LOGPDPX(ss, level, pdp, fmt, args...) \ @@ -235,33 +237,40 @@ /* to be used by libgtp callers/users (to attach their own private state) */ void *priv; - struct gsn_t *gsn; + struct gsn_t *gsn; /* Back pointer to GSN where this pdp ctx belongs to */ bool tx_gpdu_seq; /* Transmit (true) or suppress G-PDU sequence numbers */ }; /* functions related to pdp_t management */ -int pdp_init(); -int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi, - struct pdp_t *pdp_old); +int gtp_pdp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t imsi, + uint8_t nsapi, struct pdp_t *pdp_old); int pdp_freepdp(struct pdp_t *pdp); -int pdp_getpdp(struct pdp_t **pdp); - -int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl); -int pdp_getgtp1(struct pdp_t **pdp, uint32_t tei); -int pdp_getgtp1_peer_d(struct pdp_t **pdp, const struct sockaddr_in *peer, uint32_t teid_gn); - -int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi); +int gtp_pdp_getgtp0(struct gsn_t *gsn, struct pdp_t **pdp, uint16_t fl); +int gtp_pdp_getgtp1(struct gsn_t *gsn, struct pdp_t **pdp, uint32_t tei); +int gtp_pdp_getgtp1_peer_d(struct gsn_t *gsn, struct pdp_t **pdp, const struct sockaddr_in *peer, uint32_t teid_gn); +int gtp_pdp_getimsi(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi); +int gtp_pdp_tidget(struct gsn_t *gsn, struct pdp_t **pdp, uint64_t tid); int pdp_tidhash(uint64_t tid); int pdp_tidset(struct pdp_t *pdp, uint64_t tid); int pdp_tiddel(struct pdp_t *pdp); -int pdp_tidget(struct pdp_t **pdp, uint64_t tid); +uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi); void pdp_set_imsi_nsapi(struct pdp_t *pdp, uint64_t teid); unsigned int pdp_count_secondary(struct pdp_t *pdp); -uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi); +/* Deprecated APIs (support for only 1 GSN per process). Must be used only after first call to gtp_new() and until it is freed. */ +int pdp_init(struct gsn_t *gsn); /* Use only allowed inside libgtp to keep compatiblity with deprecated APIs defined here. */ +int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi, + struct pdp_t *pdp_old) OSMO_DEPRECATED("Use gtp_pdp_newpdp() instead"); +int pdp_getpdp(struct pdp_t **pdp) OSMO_DEPRECATED("Use gsn_t->pdpa field instead"); +int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl) OSMO_DEPRECATED("Use gtp_pdp_getgtp0() instead"); +int pdp_getgtp1(struct pdp_t **pdp, uint32_t tei) OSMO_DEPRECATED("Use gtp_pdp_getgtp1() instead"); +int pdp_getgtp1_peer_d(struct pdp_t **pdp, const struct sockaddr_in *peer, uint32_t teid_gn) OSMO_DEPRECATED("Use gtp_pdp_getgtp1_peer_d() instead"); +int pdp_getimsi(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi) OSMO_DEPRECATED("Use gtp_pdp_getimsi() instead"); +int pdp_tidget(struct pdp_t **pdp, uint64_t tid) OSMO_DEPRECATED("Use gtp_pdp_tidget() instead"); + #endif /* !_PDP_H */ -- To view, visit https://gerrit.osmocom.org/c/osmo-ggsn/+/14296 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-ggsn Gerrit-Branch: master Gerrit-Change-Id: I653cbdc185165592d985e3efab6e3f1add97877b Gerrit-Change-Number: 14296 Gerrit-PatchSet: 3 Gerrit-Owner: pespin <pes...@sysmocom.de> Gerrit-Reviewer: Harald Welte <lafo...@gnumonks.org> Gerrit-Reviewer: Jenkins Builder Gerrit-MessageType: merged