diff --git a/configs/open5gs/sgwc.yaml.in b/configs/open5gs/sgwc.yaml.in index fd7ff63a2..24d3673b0 100644 --- a/configs/open5gs/sgwc.yaml.in +++ b/configs/open5gs/sgwc.yaml.in @@ -61,15 +61,20 @@ sgwc: # pfcp: # addr: 127.0.0.6 # -# +# # # o Round-Robin +# (note that round robin can be disabled for a particular node +# by setting flag 'rr' to 0) +# # sgwu: # pfcp: # - addr: 127.0.0.6 # - addr: 127.0.0.12 +# rr: 0 +# - addr: 127.0.0.18 # -# o UPF selection by eNodeB TAC +# o SGWU selection by eNodeB TAC # (either single TAC or multiple TACs, DECIMAL representation) # # sgwu: @@ -79,24 +84,24 @@ sgwc: # - addr: 127.0.0.12 # tac: [3,5,8] # -# o UPF selection by UE's DNN/APN (either single DNN/APN or multiple DNNs/APNs) +# o SGWU selection by UE's APN (either single APN or multiple APNs) # # sgwu: # pfcp: # - addr: 127.0.0.6 -# dnn: ims +# apn: ims # - addr: 127.0.0.12 # apn: [internet, web] # -# o UPF selection by CellID(e_cell_id: 28bit, nr_cell_id: 36bit) -# (either single enb_id or multiple enb_ids, HEX representation) +# o SGWU selection by CellID(e_cell_id: 28bit) +# (either single e_cell_id or multiple e_cell_id, HEX representation) # # sgwu: # pfcp: # - addr: 127.0.0.6 # e_cell_id: 463 # - addr: 127.0.0.12 -# nr_cell_id: [123456789, 9413] +# e_cell_id: [123456789, 9413] # sgwu: pfcp: diff --git a/configs/open5gs/smf.yaml.in b/configs/open5gs/smf.yaml.in index d3630a233..8048bdf47 100644 --- a/configs/open5gs/smf.yaml.in +++ b/configs/open5gs/smf.yaml.in @@ -246,10 +246,15 @@ nrf: # # # o Round-Robin +# (note that round robin can be disabled for a particular node +# by setting flag 'rr' to 0) +# # upf: # pfcp: # - addr: 127.0.0.7 # - addr: 127.0.0.12 +# rr: 0 +# - addr: 127.0.0.19 # # o UPF selection by eNodeB TAC # (either single TAC or multiple TACs, DECIMAL representation) diff --git a/lib/pfcp/context.c b/lib/pfcp/context.c index e80c6127b..9e1d0999a 100644 --- a/lib/pfcp/context.c +++ b/lib/pfcp/context.c @@ -408,6 +408,7 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote) uint8_t num_of_e_cell_id = 0; uint32_t nr_cell_id[OGS_MAX_NUM_OF_CELL_ID] = {0,}; uint8_t num_of_nr_cell_id = 0; + uint8_t rr_enable = 1; /* full list RR enabled by default */ if (ogs_yaml_iter_type(&pfcp_array) == YAML_MAPPING_NODE) { @@ -570,6 +571,9 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote) } while ( ogs_yaml_iter_type(&nr_cell_id_iter) == YAML_SEQUENCE_NODE); + } else if (!strcmp(pfcp_key, "rr")) { + const char *v = ogs_yaml_iter_value(&pfcp_iter); + if (v) rr_enable = atoi(v); } else ogs_warn("unknown key `%s`", pfcp_key); } @@ -609,6 +613,8 @@ int ogs_pfcp_context_parse_config(const char *local, const char *remote) if (num_of_nr_cell_id != 0) memcpy(node->nr_cell_id, nr_cell_id, sizeof(node->nr_cell_id)); + + node->rr_enable = rr_enable; } while (ogs_yaml_iter_type(&pfcp_array) == YAML_SEQUENCE_NODE); } diff --git a/lib/pfcp/context.h b/lib/pfcp/context.h index 3666c3f97..59a468b59 100644 --- a/lib/pfcp/context.h +++ b/lib/pfcp/context.h @@ -93,6 +93,7 @@ typedef struct ogs_pfcp_node_s { uint8_t num_of_e_cell_id; uint32_t nr_cell_id[OGS_MAX_NUM_OF_CELL_ID]; uint8_t num_of_nr_cell_id; + uint8_t rr_enable; /* flag to enable/ disable full list RR for this node */ ogs_list_t gtpu_resource_list; /* User Plane IP Resource Information */ } ogs_pfcp_node_t; diff --git a/src/sgwc/context.c b/src/sgwc/context.c index 44a54d203..754dfde7f 100644 --- a/src/sgwc/context.c +++ b/src/sgwc/context.c @@ -431,14 +431,14 @@ static bool compare_ue_info(ogs_pfcp_node_t *node, sgwc_sess_t *sess) sgwc_ue = sess->sgwc_ue; ogs_assert(sgwc_ue); - for (i = 0; i < node->num_of_tac; i++) - if (node->tac[i] == sgwc_ue->e_tai.tac) return true; + for (i = 0; i < node->num_of_apn; i++) + if (strcmp(node->apn[i], sess->pdn.apn) == 0) return true; for (i = 0; i < node->num_of_e_cell_id; i++) if (node->e_cell_id[i] == sgwc_ue->e_cgi.cell_id) return true; - for (i = 0; i < node->num_of_apn; i++) - if (strcmp(node->apn[i], sess->pdn.apn) == 0) return true; + for (i = 0; i < node->num_of_tac; i++) + if (node->tac[i] == sgwc_ue->e_tai.tac) return true; return false; } @@ -461,8 +461,12 @@ static ogs_pfcp_node_t *selected_sgwu_node( 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; + /* + * we are in RR mode - use next PFCP associated + * node that is suited for full list RR + */ + if (OGS_FSM_CHECK(&node->sm, sgwc_pfcp_state_associated) && + node->rr_enable == 1) return node; } } /* cyclic search from top to current position */ @@ -472,8 +476,12 @@ static ogs_pfcp_node_t *selected_sgwu_node( 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; + /* + * we are in RR mode - use next PFCP associated + * node that is suited for full list RR + */ + if (OGS_FSM_CHECK(&node->sm, sgwc_pfcp_state_associated) && + node->rr_enable == 1) return node; } } @@ -487,7 +495,7 @@ static ogs_pfcp_node_t *selected_sgwu_node( RR = 1; } - ogs_error("No SGWUs are PFCP associated"); + ogs_error("No SGWUs are PFCP associated that are suited to RR"); return ogs_list_first(&ogs_pfcp_self()->peer_list); } diff --git a/src/smf/context.c b/src/smf/context.c index 3577eec18..f925dd41e 100644 --- a/src/smf/context.c +++ b/src/smf/context.c @@ -611,9 +611,8 @@ static bool compare_ue_info(ogs_pfcp_node_t *node, smf_sess_t *sess) ogs_assert(node); ogs_assert(sess); - for (i = 0; i < node->num_of_tac; i++) - if (node->tac[i] == sess->e_tai.tac || - node->tac[i] == sess->nr_tai.tac.v) return true; + for (i = 0; i < node->num_of_apn; i++) + if (strcmp(node->apn[i], sess->pdn.apn) == 0) return true; for (i = 0; i < node->num_of_e_cell_id; i++) if (node->e_cell_id[i] == sess->e_cgi.cell_id) return true; @@ -621,8 +620,9 @@ static bool compare_ue_info(ogs_pfcp_node_t *node, smf_sess_t *sess) for (i = 0; i < node->num_of_nr_cell_id; i++) if (node->nr_cell_id[i] == sess->nr_cgi.cell_id) return true; - for (i = 0; i < node->num_of_apn; i++) - if (strcmp(node->apn[i], sess->pdn.apn) == 0) return true; + for (i = 0; i < node->num_of_tac; i++) + if ((node->tac[i] == sess->e_tai.tac) || + (node->tac[i] == sess->nr_tai.tac.v)) return true; return false; } @@ -645,8 +645,12 @@ static ogs_pfcp_node_t *selected_upf_node( 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; + /* + * we are in RR mode - use next PFCP associated + * node that is suited for full list RR + */ + if (OGS_FSM_CHECK(&node->sm, smf_pfcp_state_associated) && + node->rr_enable == 1) return node; } } /* cyclic search from top to current position */ @@ -656,8 +660,12 @@ static ogs_pfcp_node_t *selected_upf_node( 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; + /* + * we are in RR mode - use next PFCP associated + * node that is suited for full list RR + */ + if (OGS_FSM_CHECK(&node->sm, smf_pfcp_state_associated) && + node->rr_enable == 1) return node; } } @@ -671,7 +679,7 @@ static ogs_pfcp_node_t *selected_upf_node( RR = 1; } - ogs_error("No UPFs are PFCP associated"); + ogs_error("No UPFs are PFCP associated that are suited to RR"); return ogs_list_first(&ogs_pfcp_self()->peer_list); }