From 56a866c46e19233cebda59342d0cbf06f2fb22c0 Mon Sep 17 00:00:00 2001 From: Kenny Barlee Date: Wed, 9 Sep 2020 13:28:19 +0100 Subject: [PATCH] Fix for SGWC and SMF round robin selection - select only PFCP associated SGWU/UPF nodes (#556) --- src/sgwc/context.c | 40 +++++++++++++++++++++++++++++----------- src/smf/context.c | 40 +++++++++++++++++++++++++++++----------- 2 files changed, 58 insertions(+), 22 deletions(-) diff --git a/src/sgwc/context.c b/src/sgwc/context.c index f442e9283..54436051b 100644 --- a/src/sgwc/context.c +++ b/src/sgwc/context.c @@ -451,19 +451,37 @@ static ogs_pfcp_node_t *selected_sgwu_node( ogs_assert(current); ogs_assert(sess); - next = ogs_list_next(current); - for (node = next; node; node = ogs_list_next(node)) { - if (OGS_FSM_CHECK(&node->sm, sgwc_pfcp_state_associated) && - compare_ue_info(node, sess) == true) return node; + int RR=0, selected=0; + + while(!selected){ + // continue search from current position + next = ogs_list_next(current); + for (node = next; node; node = ogs_list_next(node)) { + if (!RR){ + if (OGS_FSM_CHECK(&node->sm, sgwc_pfcp_state_associated) && + compare_ue_info(node, sess) == true) return node; + }else{ + if (OGS_FSM_CHECK(&node->sm, sgwc_pfcp_state_associated)) return node; + } + } + // cyclic search from top to current position + for (node = ogs_list_first(&ogs_pfcp_self()->peer_list); + node != next; node = ogs_list_next(node)) { + if (!RR){ + if (OGS_FSM_CHECK(&node->sm, sgwc_pfcp_state_associated) && + compare_ue_info(node, sess) == true) return node; + }else{ + if (OGS_FSM_CHECK(&node->sm, sgwc_pfcp_state_associated)) return node; + } + } + // if a round robin search has already been carried out + if(RR) break; + // re-run search in round robin mode, find and use next PFCP associated node + RR = 1; } - for (node = ogs_list_first(&ogs_pfcp_self()->peer_list); - node != next; node = ogs_list_next(node)) { - if (OGS_FSM_CHECK(&node->sm, sgwc_pfcp_state_associated) && - compare_ue_info(node, sess) == true) return node; - } - - return next ? next : ogs_list_first(&ogs_pfcp_self()->peer_list); + ogs_error("No SGWUs are PFCP associated"); + return ogs_list_first(&ogs_pfcp_self()->peer_list); } void sgwc_sess_select_sgwu(sgwc_sess_t *sess) diff --git a/src/smf/context.c b/src/smf/context.c index fdddfe9c0..31bc2d357 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -635,19 +635,37 @@ static ogs_pfcp_node_t *selected_upf_node( ogs_assert(current); ogs_assert(sess); - next = ogs_list_next(current); - for (node = next; node; node = ogs_list_next(node)) { - if (OGS_FSM_CHECK(&node->sm, smf_pfcp_state_associated) && - compare_ue_info(node, sess) == true) return node; + int RR=0, selected=0; + + while(!selected){ + // continue search from current position + next = ogs_list_next(current); + for (node = next; node; node = ogs_list_next(node)) { + if (!RR){ + if (OGS_FSM_CHECK(&node->sm, smf_pfcp_state_associated) && + compare_ue_info(node, sess) == true) return node; + }else{ + if (OGS_FSM_CHECK(&node->sm, smf_pfcp_state_associated)) return node; + } + } + // cyclic search from top to current position + for (node = ogs_list_first(&ogs_pfcp_self()->peer_list); + node != next; node = ogs_list_next(node)) { + if (!RR){ + if (OGS_FSM_CHECK(&node->sm, smf_pfcp_state_associated) && + compare_ue_info(node, sess) == true) return node; + }else{ + if (OGS_FSM_CHECK(&node->sm, smf_pfcp_state_associated)) return node; + } + } + // if a round robin search has already been carried out + if(RR) break; + // re-run search in round robin mode, find and use next PFCP associated node + RR = 1; } - for (node = ogs_list_first(&ogs_pfcp_self()->peer_list); - node != next; node = ogs_list_next(node)) { - if (OGS_FSM_CHECK(&node->sm, smf_pfcp_state_associated) && - compare_ue_info(node, sess) == true) return node; - } - - return next ? next : ogs_list_first(&ogs_pfcp_self()->peer_list); + ogs_error("No UPFs are PFCP associated"); + return ogs_list_first(&ogs_pfcp_self()->peer_list); } void smf_sess_select_upf(smf_sess_t *sess)