pespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-hnbgw/+/41483?usp=email )
Change subject: SPlit UPF into its own object ......................................................................
SPlit UPF into its own object
This allows easily extending per-peer (UPF) functionalities, eg. adding Heartbeat procedure, as well as a step towards supporting a UPF pool in the future.
Change-Id: I624bafe2fa150f7480b6fb44433c34e83154e06c --- M include/osmocom/hnbgw/hnbgw.h M include/osmocom/hnbgw/hnbgw_pfcp.h M src/osmo-hnbgw/hnbgw_pfcp.c M src/osmo-hnbgw/hnbgw_ranap.c M src/osmo-hnbgw/ps_rab_ass_fsm.c M src/osmo-hnbgw/ps_rab_fsm.c 6 files changed, 82 insertions(+), 35 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-hnbgw refs/changes/83/41483/1
diff --git a/include/osmocom/hnbgw/hnbgw.h b/include/osmocom/hnbgw/hnbgw.h index 981b809..36e8943 100644 --- a/include/osmocom/hnbgw/hnbgw.h +++ b/include/osmocom/hnbgw/hnbgw.h @@ -147,9 +147,7 @@
struct { struct osmo_pfcp_endpoint *ep; - struct osmo_pfcp_cp_peer *cp_peer; - /* Running counters for the PFCP conn */ - struct osmo_stat_item_group *statg; + struct hnbgw_upf *upf; } pfcp;
struct osmo_timer_list hnb_store_rab_durations_timer; diff --git a/include/osmocom/hnbgw/hnbgw_pfcp.h b/include/osmocom/hnbgw/hnbgw_pfcp.h index 376d144..96ab990 100644 --- a/include/osmocom/hnbgw/hnbgw_pfcp.h +++ b/include/osmocom/hnbgw/hnbgw_pfcp.h @@ -1,9 +1,24 @@ #pragma once
+#include <osmocom/core/fsm.h> +#include <osmocom/core/socket.h> +#include <osmocom/core/stat_item.h> +#include <osmocom/pfcp/pfcp_endpoint.h> +#include <osmocom/pfcp/pfcp_cp_peer.h> + enum hnbgw_upf_stats { HNBGW_UPF_STAT_ASSOCIATED, }; -#define HNBGW_UPF_STAT_SET(stat, val) osmo_stat_item_set(osmo_stat_item_group_get_item(g_hnbgw->pfcp.statg, (stat)), (val)) +#define HNBGW_UPF_STAT_SET(stat, val) osmo_stat_item_set(osmo_stat_item_group_get_item(g_hnbgw->pfcp.upf->statg, (stat)), (val)) + +struct hnbgw_upf { + struct osmo_pfcp_cp_peer *cp_peer; + /* Running counters for the PFCP conn */ + struct osmo_stat_item_group *statg; +}; + +struct hnbgw_upf *hnbgw_upf_alloc(struct osmo_pfcp_endpoint *ep, const struct osmo_sockaddr *rem_addr); +void hnbgw_upf_free(struct hnbgw_upf *upf);
int hnbgw_pfcp_init(void); void hnbgw_pfcp_release(void); diff --git a/src/osmo-hnbgw/hnbgw_pfcp.c b/src/osmo-hnbgw/hnbgw_pfcp.c index dc82f04..8fb7786 100644 --- a/src/osmo-hnbgw/hnbgw_pfcp.c +++ b/src/osmo-hnbgw/hnbgw_pfcp.c @@ -45,7 +45,7 @@ static void pfcp_set_msg_ctx(struct osmo_pfcp_endpoint *ep, struct osmo_pfcp_msg *m, struct osmo_pfcp_msg *req) { if (!m->ctx.peer_fi) - osmo_pfcp_cp_peer_set_msg_ctx(g_hnbgw->pfcp.cp_peer, m); + osmo_pfcp_cp_peer_set_msg_ctx(g_hnbgw->pfcp.upf->cp_peer, m);
/* If this is a response to an earlier request, just take the msg context from the request message. * In osmo-hnbgw, a session_fi always points at a ps_rab FSM. */ @@ -83,6 +83,51 @@ HNBGW_UPF_STAT_SET(HNBGW_UPF_STAT_ASSOCIATED, associated ? 1 : 0); }
+struct hnbgw_upf *hnbgw_upf_alloc(struct osmo_pfcp_endpoint *ep, const struct osmo_sockaddr *upf_addr) +{ + struct hnbgw_upf *upf = talloc_zero(g_hnbgw, struct hnbgw_upf); + OSMO_ASSERT(upf); + + upf->statg = osmo_stat_item_group_alloc(g_hnbgw, &hnbgw_upf_statg_desc, 0); + if (!upf->statg) { + LOGP(DLPFCP, LOGL_ERROR, "Failed creating UPF stats item group\n"); + goto free_ret; + } + + upf->cp_peer = osmo_pfcp_cp_peer_alloc(g_hnbgw, ep, upf_addr); + if (!upf->cp_peer) { + LOGP(DLPFCP, LOGL_ERROR, "Cannot allocate PFCP CP Peer FSM\n"); + goto free_ret; + } + osmo_pfcp_cp_peer_set_priv(upf->cp_peer, upf); + + if (osmo_pfcp_cp_peer_set_associated_cb(upf->cp_peer, pfcp_cp_peer_assoc_cb)) { + LOGP(DLPFCP, LOGL_ERROR, "Cannot Set PFCP CP Peer associated callback\n"); + goto free_ret; + } + + if (osmo_pfcp_cp_peer_associate(upf->cp_peer)) { + LOGP(DLPFCP, LOGL_ERROR, "Cannot start PFCP CP Peer FSM\n"); + goto free_ret; + } + + return upf; +free_ret: + osmo_pfcp_cp_peer_free(upf->cp_peer); + osmo_stat_item_group_free(upf->statg); + talloc_free(upf); + return NULL; +} + +void hnbgw_upf_free(struct hnbgw_upf *upf) +{ + if (!upf) + return; + + osmo_pfcp_cp_peer_free(upf->cp_peer); + osmo_stat_item_group_free(upf->statg); +} + int hnbgw_pfcp_init(void) { struct osmo_pfcp_endpoint_cfg cfg; @@ -102,12 +147,6 @@ return -1; }
- g_hnbgw->pfcp.statg = osmo_stat_item_group_alloc(g_hnbgw, &hnbgw_upf_statg_desc, 0); - if (!g_hnbgw->pfcp.statg) { - LOGP(DLPFCP, LOGL_ERROR, "Failed creating UPF stats item group\n"); - return -1; - } - cfg = (struct osmo_pfcp_endpoint_cfg){ .set_msg_ctx_cb = pfcp_set_msg_ctx, .rx_msg_cb = pfcp_rx_msg, @@ -132,12 +171,6 @@ return -1; }
- g_hnbgw->pfcp.ep = ep = osmo_pfcp_endpoint_create(g_hnbgw, &cfg); - if (!ep) { - LOGP(DLPFCP, LOGL_ERROR, "Failed to allocate PFCP endpoint\n"); - return -1; - } - /* Set up remote PFCP address to reach UPF at. First parse the string into upf_addr_str. */ if (osmo_sockaddr_str_from_str(&upf_addr_str, g_hnbgw->config.pfcp.remote_addr, g_hnbgw->config.pfcp.remote_port)) { LOGP(DLPFCP, LOGL_ERROR, "Error in PFCP remote IP: %s\n", @@ -151,6 +184,12 @@ return -1; }
+ g_hnbgw->pfcp.ep = ep = osmo_pfcp_endpoint_create(g_hnbgw, &cfg); + if (!ep) { + LOGP(DLPFCP, LOGL_ERROR, "Failed to allocate PFCP endpoint\n"); + return -1; + } + /* Start the socket */ if (osmo_pfcp_endpoint_bind(ep)) { LOGP(DLPFCP, LOGL_ERROR, "Cannot bind PFCP endpoint\n"); @@ -158,18 +197,9 @@ }
/* Associate with UPF */ - g_hnbgw->pfcp.cp_peer = osmo_pfcp_cp_peer_alloc(g_hnbgw, ep, &upf_addr); - if (!g_hnbgw->pfcp.cp_peer) { - LOGP(DLPFCP, LOGL_ERROR, "Cannot allocate PFCP CP Peer FSM\n"); - return -1; - } - if (osmo_pfcp_cp_peer_set_associated_cb(g_hnbgw->pfcp.cp_peer, pfcp_cp_peer_assoc_cb)) { - LOGP(DLPFCP, LOGL_ERROR, "Cannot Set PFCP CP Peer associated callback\n"); - return -1; - } - - if (osmo_pfcp_cp_peer_associate(g_hnbgw->pfcp.cp_peer)) { - LOGP(DLPFCP, LOGL_ERROR, "Cannot start PFCP CP Peer FSM\n"); + g_hnbgw->pfcp.upf = hnbgw_upf_alloc(ep, &upf_addr); + if (!g_hnbgw->pfcp.upf) { + LOGP(DLPFCP, LOGL_ERROR, "Failed creating UPF\n"); return -1; }
@@ -180,5 +210,6 @@ { if (!hnb_gw_is_gtp_mapping_enabled()) return; - osmo_stat_item_group_free(g_hnbgw->pfcp.statg); + hnbgw_upf_free(g_hnbgw->pfcp.upf); + g_hnbgw->pfcp.upf = NULL; } diff --git a/src/osmo-hnbgw/hnbgw_ranap.c b/src/osmo-hnbgw/hnbgw_ranap.c index efa46d4..e89e932 100644 --- a/src/osmo-hnbgw/hnbgw_ranap.c +++ b/src/osmo-hnbgw/hnbgw_ranap.c @@ -44,6 +44,7 @@ #include <osmocom/hnbgw/hnbgw.h> #include <osmocom/hnbgw/hnbgw_rua.h> #include <osmocom/hnbgw/hnbgw_cn.h> +#include <osmocom/hnbgw/hnbgw_pfcp.h> #include <osmocom/hnbgw/context_map.h> #include <osmocom/hnbgw/mgw_fsm.h> #include <osmocom/hnbgw/ps_rab_ass_fsm.h> @@ -655,7 +656,7 @@ if (hnb_gw_is_gtp_mapping_enabled()) { LOG_MAP(map, DCN, LOGL_DEBUG, "RAB Assignment: setting up GTP tunnel mapping via UPF %s\n", - osmo_sockaddr_to_str_c(OTC_SELECT, osmo_pfcp_cp_peer_get_remote_addr(g_hnbgw->pfcp.cp_peer))); + osmo_sockaddr_to_str_c(OTC_SELECT, osmo_pfcp_cp_peer_get_remote_addr(g_hnbgw->pfcp.upf->cp_peer))); return hnbgw_gtpmap_rx_rab_ass_req(map, ranap_msg, message); } /* If no UPF is configured, directly forward the message as-is (no GTP mapping). */ diff --git a/src/osmo-hnbgw/ps_rab_ass_fsm.c b/src/osmo-hnbgw/ps_rab_ass_fsm.c index c6e8495..9f6441a 100644 --- a/src/osmo-hnbgw/ps_rab_ass_fsm.c +++ b/src/osmo-hnbgw/ps_rab_ass_fsm.c @@ -43,6 +43,7 @@ #include <osmocom/pfcp/pfcp_cp_peer.h>
#include <osmocom/hnbgw/hnbgw.h> +#include <osmocom/hnbgw/hnbgw_pfcp.h> #include <osmocom/hnbgw/context_map.h> #include <osmocom/hnbgw/ranap_rab_ass.h> #include <osmocom/hnbgw/ps_rab_ass_fsm.h> @@ -230,7 +231,7 @@ rab_ass->ranap_rab_ass_req_message = message; /* Now rab_ass owns message and will clean it up */
- if (!osmo_pfcp_cp_peer_is_associated(g_hnbgw->pfcp.cp_peer)) { + if (!osmo_pfcp_cp_peer_is_associated(g_hnbgw->pfcp.upf->cp_peer)) { LOG_MAP(map, DLPFCP, LOGL_ERROR, "PFCP is not associated, cannot set up GTP mapping\n"); goto no_rab; } @@ -432,7 +433,7 @@ rab_ass->ranap_rab_ass_resp_msgb = ranap_msg; /* Now rab_ass owns message and will clean it up */
- if (!osmo_pfcp_cp_peer_is_associated(g_hnbgw->pfcp.cp_peer)) { + if (!osmo_pfcp_cp_peer_is_associated(g_hnbgw->pfcp.upf->cp_peer)) { LOG_PS_RAB_ASS(rab_ass, LOGL_ERROR, "PFCP is not associated, cannot set up GTP mapping\n"); goto no_rab; } diff --git a/src/osmo-hnbgw/ps_rab_fsm.c b/src/osmo-hnbgw/ps_rab_fsm.c index caaed84..eb12792 100644 --- a/src/osmo-hnbgw/ps_rab_fsm.c +++ b/src/osmo-hnbgw/ps_rab_fsm.c @@ -23,6 +23,7 @@ #include <osmocom/pfcp/pfcp_cp_peer.h>
#include <osmocom/hnbgw/hnbgw.h> +#include <osmocom/hnbgw/hnbgw_pfcp.h> #include <osmocom/hnbgw/context_map.h> #include <osmocom/hnbgw/tdefs.h> #include <osmocom/hnbgw/ps_rab_fsm.h> @@ -143,7 +144,7 @@
static struct osmo_pfcp_msg *ps_rab_new_pfcp_msg_req(struct ps_rab *rab, enum osmo_pfcp_message_type msg_type) { - struct osmo_pfcp_msg *m = osmo_pfcp_cp_peer_new_req(g_hnbgw->pfcp.cp_peer, msg_type); + struct osmo_pfcp_msg *m = osmo_pfcp_cp_peer_new_req(g_hnbgw->pfcp.upf->cp_peer, msg_type);
m->h.seid_present = true; m->h.seid = rab->up_f_seid.seid; @@ -320,7 +321,7 @@ m->h.seid = 0;
/* Make a new CP-SEID, our local reference for the PFCP session. */ - rab->cp_seid = osmo_pfcp_cp_peer_next_seid(g_hnbgw->pfcp.cp_peer); + rab->cp_seid = osmo_pfcp_cp_peer_next_seid(g_hnbgw->pfcp.upf->cp_peer); cp_f_seid = (struct osmo_pfcp_ie_f_seid){ .seid = rab->cp_seid, };