neels has submitted this change. ( https://gerrit.osmocom.org/c/osmo-upf/+/31480 )
Change subject: move next_teid from up_endpoint to g_upf ......................................................................
move next_teid from up_endpoint to g_upf
up_endpoint is about the PFCP endpoint, handing out local TEID is about local GTP endpoints. Move the TEID allocation to g_upf / upf.c.
An upcoming patch will use a hash table in g_upf to speed up lookup whether a local TEID is already in use; cosmetically prepare for that.
Change-Id: I8eae5b53c563400ddfded264678d9cfb28b6f737 --- M include/osmocom/upf/up_endpoint.h M include/osmocom/upf/upf.h M src/osmo-upf/up_endpoint.c M src/osmo-upf/up_session.c M src/osmo-upf/upf.c 5 files changed, 55 insertions(+), 35 deletions(-)
Approvals: Jenkins Builder: Verified msuraev: Looks good to me, but someone else must approve laforge: Looks good to me, approved
diff --git a/include/osmocom/upf/up_endpoint.h b/include/osmocom/upf/up_endpoint.h index 60b3927..12ab548 100644 --- a/include/osmocom/upf/up_endpoint.h +++ b/include/osmocom/upf/up_endpoint.h @@ -39,11 +39,9 @@ struct llist_head peers;
uint64_t next_seid_state; - uint32_t next_teid_state; };
struct up_endpoint *up_endpoint_init(void *ctx, const struct osmo_sockaddr *local_addr); void up_endpoint_free(struct up_endpoint **ep);
uint64_t up_endpoint_next_seid(struct up_endpoint *ep); -uint32_t up_endpoint_next_teid(struct up_endpoint *ep); diff --git a/include/osmocom/upf/upf.h b/include/osmocom/upf/upf.h index 71364d4..041edea 100644 --- a/include/osmocom/upf/upf.h +++ b/include/osmocom/upf/upf.h @@ -115,6 +115,10 @@ uint32_t next_chain_id_state; } tunmap;
+ struct { + uint32_t next_local_teid_state; + } gtp; + struct llist_head netinst; };
@@ -134,3 +138,5 @@
int upf_gtp_devs_open(); void upf_gtp_devs_close(); + +uint32_t upf_next_local_teid(void); diff --git a/src/osmo-upf/up_endpoint.c b/src/osmo-upf/up_endpoint.c index 70900c4..4500a43 100644 --- a/src/osmo-upf/up_endpoint.c +++ b/src/osmo-upf/up_endpoint.c @@ -271,17 +271,6 @@ return NULL; }
-static struct up_session *up_endpoint_find_session_by_local_teid(struct up_endpoint *ep, uint32_t teid) -{ - struct up_peer *peer; - llist_for_each_entry(peer, &ep->peers, entry) { - struct up_session *session = up_session_find_by_local_teid(peer, teid); - if (session) - return session; - } - return NULL; -} - uint64_t up_endpoint_next_seid(struct up_endpoint *ep) { uint64_t sanity; @@ -294,26 +283,6 @@ return 0; }
-static uint32_t up_endpoint_inc_teid(struct up_endpoint *ep) -{ - ep->next_teid_state++; - if (!ep->next_teid_state) - ep->next_teid_state++; - return ep->next_teid_state; -} - -uint32_t up_endpoint_next_teid(struct up_endpoint *ep) -{ - uint32_t sanity; - for (sanity = 2342; sanity; sanity--) { - uint32_t next_teid = up_endpoint_inc_teid(ep); - if (up_endpoint_find_session_by_local_teid(ep, next_teid)) - continue; - return next_teid; - } - return 0; -} - void up_endpoint_free(struct up_endpoint **_ep) { struct up_peer *peer; diff --git a/src/osmo-upf/up_session.c b/src/osmo-upf/up_session.c index 38f4d2b..bbf994e 100644 --- a/src/osmo-upf/up_session.c +++ b/src/osmo-upf/up_session.c @@ -185,7 +185,6 @@ bool choose_id_present, uint8_t choose_id, const char *netinst_name) { - struct up_endpoint *up_ep = session->up_peer->up_endpoint; struct chosen_f_teid *chosen = NULL;
if (choose_id_present) @@ -206,7 +205,7 @@ return rc;
/* Choose a new TEID */ - dst->fixed.teid = up_endpoint_next_teid(up_ep); + dst->fixed.teid = upf_next_local_teid(); if (dst->fixed.teid == 0) { LOGPFSML(session->fi, LOGL_ERROR, "Failed to allocate an unused TEID\n"); return OSMO_PFCP_CAUSE_PFCP_ENTITY_IN_CONGESTION; diff --git a/src/osmo-upf/upf.c b/src/osmo-upf/upf.c index b28e55d..047a6ff 100644 --- a/src/osmo-upf/upf.c +++ b/src/osmo-upf/upf.c @@ -29,6 +29,8 @@
#include <osmocom/upf/upf.h> #include <osmocom/upf/up_endpoint.h> +#include <osmocom/upf/up_peer.h> +#include <osmocom/upf/up_session.h> #include <osmocom/upf/upf_gtp.h>
struct g_upf *g_upf = NULL; @@ -98,3 +100,34 @@ } return 0; } + +static bool upf_is_local_teid_in_use(uint32_t teid) +{ + struct up_peer *peer; + llist_for_each_entry(peer, &g_upf->pfcp.ep->peers, entry) { + struct up_session *session = up_session_find_by_local_teid(peer, teid); + if (session) + return true; + } + return false; +} + +static uint32_t upf_next_local_teid_inc(void) +{ + g_upf->gtp.next_local_teid_state++; + if (!g_upf->gtp.next_local_teid_state) + g_upf->gtp.next_local_teid_state++; + return g_upf->gtp.next_local_teid_state; +} + +uint32_t upf_next_local_teid(void) +{ + uint32_t sanity; + for (sanity = 2342; sanity; sanity--) { + uint32_t next_teid = upf_next_local_teid_inc(); + if (upf_is_local_teid_in_use(next_teid)) + continue; + return next_teid; + } + return 0; +}