forked from acouzens/open5gs
Support SMF Security Indication IE (#1851)
This commit is contained in:
parent
f1c0b6d239
commit
0df2cba257
|
@ -440,7 +440,20 @@ logger:
|
||||||
# mnc: 70
|
# mnc: 70
|
||||||
# tac: 99
|
# tac: 99
|
||||||
#
|
#
|
||||||
|
# <Security Indication - 5G Core only>
|
||||||
|
#
|
||||||
|
# According to 3GPP TS38.413 Section 9.3.1.27,
|
||||||
|
# Security Indication IE may be instructed to 5G gNB.
|
||||||
|
#
|
||||||
|
# If you set the security_indication in smf.yaml,
|
||||||
|
# this information is delivered using PDU Session Resource Request Transfer IE
|
||||||
|
#
|
||||||
|
# security_indication:
|
||||||
|
# integrity_protection_indication: required|preferred|not-needed
|
||||||
|
# confidentiality_protection_indication: required|preferred|not-needed
|
||||||
|
# maximum_integrity_protected_data_rate_uplink: bitrate64kbs|maximum-UE-rate
|
||||||
|
# maximum_integrity_protected_data_rate_downlink: bitrate64kbs|maximum-UE-rate
|
||||||
|
#
|
||||||
smf:
|
smf:
|
||||||
sbi:
|
sbi:
|
||||||
- addr: 127.0.0.4
|
- addr: 127.0.0.4
|
||||||
|
|
|
@ -202,6 +202,83 @@ static int smf_context_validation(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self.security_indication.integrity_protection_indication ||
|
||||||
|
self.security_indication.confidentiality_protection_indication) {
|
||||||
|
if (!self.security_indication.integrity_protection_indication ||
|
||||||
|
!self.security_indication.confidentiality_protection_indication) {
|
||||||
|
ogs_error("Invalid security_indication [%s,%s]",
|
||||||
|
self.security_indication.integrity_protection_indication ?
|
||||||
|
self.security_indication.integrity_protection_indication :
|
||||||
|
"No integrity_protection_indication",
|
||||||
|
self.security_indication.confidentiality_protection_indication ?
|
||||||
|
self.security_indication.confidentiality_protection_indication :
|
||||||
|
"No confidentiality_protection_indication");
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
if (smf_integrity_protection_indication_value2enum(
|
||||||
|
self.security_indication.integrity_protection_indication) < 0) {
|
||||||
|
ogs_error("Invalid integrity_protection_indication [%s]",
|
||||||
|
self.security_indication.integrity_protection_indication);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
if (smf_confidentiality_protection_indication_value2enum(
|
||||||
|
self.security_indication.
|
||||||
|
confidentiality_protection_indication) < 0) {
|
||||||
|
ogs_error("Invalid confidentiality_protection_indication [%s]",
|
||||||
|
self.security_indication.confidentiality_protection_indication);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.security_indication.maximum_integrity_protected_data_rate_uplink) {
|
||||||
|
NGAP_IntegrityProtectionIndication_t integrityProtectionIndication;
|
||||||
|
if (smf_maximum_integrity_protected_data_rate_uplink_value2enum(
|
||||||
|
self.security_indication.
|
||||||
|
maximum_integrity_protected_data_rate_uplink) < 0) {
|
||||||
|
ogs_error("Invalid "
|
||||||
|
"maximum_integrity_protected_data_rate_uplink [%s]",
|
||||||
|
self.security_indication.
|
||||||
|
maximum_integrity_protected_data_rate_uplink);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
integrityProtectionIndication =
|
||||||
|
smf_integrity_protection_indication_value2enum(
|
||||||
|
self.security_indication.integrity_protection_indication);
|
||||||
|
if (integrityProtectionIndication ==
|
||||||
|
NGAP_IntegrityProtectionIndication_required ||
|
||||||
|
integrityProtectionIndication ==
|
||||||
|
NGAP_IntegrityProtectionIndication_preferred) {
|
||||||
|
} else {
|
||||||
|
ogs_error("Invalid security_indication [%s:UL-%s]",
|
||||||
|
self.security_indication.integrity_protection_indication ?
|
||||||
|
self.security_indication.integrity_protection_indication :
|
||||||
|
"No integrity_protection_indication",
|
||||||
|
self.security_indication.
|
||||||
|
maximum_integrity_protected_data_rate_uplink ?
|
||||||
|
self.security_indication.
|
||||||
|
maximum_integrity_protected_data_rate_uplink :
|
||||||
|
"No integrity_protection_indication");
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.security_indication.maximum_integrity_protected_data_rate_downlink) {
|
||||||
|
if (smf_maximum_integrity_protected_data_rate_downlink_value2enum(
|
||||||
|
self.security_indication.
|
||||||
|
maximum_integrity_protected_data_rate_downlink) < 0) {
|
||||||
|
ogs_error("Invalid "
|
||||||
|
"maximum_integrity_protected_data_rate_downlink [%s]",
|
||||||
|
self.security_indication.
|
||||||
|
maximum_integrity_protected_data_rate_downlink);
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
if (!self.security_indication.
|
||||||
|
maximum_integrity_protected_data_rate_uplink) {
|
||||||
|
ogs_error("No maximum_integrity_protected_data_rate_uplink");
|
||||||
|
return OGS_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return OGS_OK;
|
return OGS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,6 +902,40 @@ int smf_context_parse_config(void)
|
||||||
} while (ogs_yaml_iter_type(&info_array) ==
|
} while (ogs_yaml_iter_type(&info_array) ==
|
||||||
YAML_SEQUENCE_NODE);
|
YAML_SEQUENCE_NODE);
|
||||||
|
|
||||||
|
} else if (!strcmp(smf_key, "security_indication")) {
|
||||||
|
ogs_yaml_iter_t security_indication_iter;
|
||||||
|
ogs_yaml_iter_recurse(
|
||||||
|
&smf_iter, &security_indication_iter);
|
||||||
|
while (ogs_yaml_iter_next(&security_indication_iter)) {
|
||||||
|
const char *security_indication_key =
|
||||||
|
ogs_yaml_iter_key(&security_indication_iter);
|
||||||
|
ogs_assert(security_indication_key);
|
||||||
|
if (!strcmp(security_indication_key,
|
||||||
|
"integrity_protection_indication")) {
|
||||||
|
self.security_indication.
|
||||||
|
integrity_protection_indication =
|
||||||
|
ogs_yaml_iter_value(
|
||||||
|
&security_indication_iter);
|
||||||
|
} else if (!strcmp(security_indication_key,
|
||||||
|
"confidentiality_protection_indication")) {
|
||||||
|
self.security_indication.
|
||||||
|
confidentiality_protection_indication =
|
||||||
|
ogs_yaml_iter_value(
|
||||||
|
&security_indication_iter);
|
||||||
|
} else if (!strcmp(security_indication_key,
|
||||||
|
"maximum_integrity_protected_data_rate_uplink")) {
|
||||||
|
self.security_indication.
|
||||||
|
maximum_integrity_protected_data_rate_uplink =
|
||||||
|
ogs_yaml_iter_value(
|
||||||
|
&security_indication_iter);
|
||||||
|
} else if (!strcmp(security_indication_key,
|
||||||
|
"maximum_integrity_protected_data_rate_downlink")) {
|
||||||
|
self.security_indication.
|
||||||
|
maximum_integrity_protected_data_rate_downlink =
|
||||||
|
ogs_yaml_iter_value(
|
||||||
|
&security_indication_iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (!strcmp(smf_key, "pfcp")) {
|
} else if (!strcmp(smf_key, "pfcp")) {
|
||||||
/* handle config in pfcp library */
|
/* handle config in pfcp library */
|
||||||
} else if (!strcmp(smf_key, "subnet")) {
|
} else if (!strcmp(smf_key, "subnet")) {
|
||||||
|
@ -2981,3 +3092,42 @@ static void stats_remove_smf_session(void)
|
||||||
num_of_smf_sess = num_of_smf_sess - 1;
|
num_of_smf_sess = num_of_smf_sess - 1;
|
||||||
ogs_info("[Removed] Number of SMF-Sessions is now %d", num_of_smf_sess);
|
ogs_info("[Removed] Number of SMF-Sessions is now %d", num_of_smf_sess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int smf_integrity_protection_indication_value2enum(const char *value)
|
||||||
|
{
|
||||||
|
ogs_assert(value);
|
||||||
|
if (!strcmp(value, "required"))
|
||||||
|
return NGAP_IntegrityProtectionIndication_required;
|
||||||
|
else if (!strcmp(value, "preferred"))
|
||||||
|
return NGAP_IntegrityProtectionIndication_preferred;
|
||||||
|
else if (!strcmp(value, "not-needed"))
|
||||||
|
return NGAP_IntegrityProtectionIndication_not_needed;
|
||||||
|
else {
|
||||||
|
ogs_error("Invalid value[%s]", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int smf_confidentiality_protection_indication_value2enum(const char *value)
|
||||||
|
{
|
||||||
|
ogs_assert(value);
|
||||||
|
return smf_integrity_protection_indication_value2enum(value);
|
||||||
|
}
|
||||||
|
int smf_maximum_integrity_protected_data_rate_uplink_value2enum(
|
||||||
|
const char *value)
|
||||||
|
{
|
||||||
|
ogs_assert(value);
|
||||||
|
if (!strcmp(value, "bitrate64kbs"))
|
||||||
|
return NGAP_MaximumIntegrityProtectedDataRate_bitrate64kbs;
|
||||||
|
else if (!strcmp(value, "maximum-UE-rate"))
|
||||||
|
return NGAP_MaximumIntegrityProtectedDataRate_maximum_UE_rate;
|
||||||
|
else {
|
||||||
|
ogs_error("Invalid value[%s]", value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int smf_maximum_integrity_protected_data_rate_downlink_value2enum(
|
||||||
|
const char *value)
|
||||||
|
{
|
||||||
|
ogs_assert(value);
|
||||||
|
return smf_maximum_integrity_protected_data_rate_uplink_value2enum(value);
|
||||||
|
}
|
||||||
|
|
|
@ -92,6 +92,13 @@ typedef struct smf_context_s {
|
||||||
|
|
||||||
uint16_t mtu; /* MTU to advertise in PCO */
|
uint16_t mtu; /* MTU to advertise in PCO */
|
||||||
|
|
||||||
|
struct {
|
||||||
|
const char *integrity_protection_indication;
|
||||||
|
const char *confidentiality_protection_indication;
|
||||||
|
const char *maximum_integrity_protected_data_rate_uplink;
|
||||||
|
const char *maximum_integrity_protected_data_rate_downlink;
|
||||||
|
} security_indication;
|
||||||
|
|
||||||
#define SMF_UE_IS_LAST_SESSION(__sMF) \
|
#define SMF_UE_IS_LAST_SESSION(__sMF) \
|
||||||
((__sMF) && (ogs_list_count(&(__sMF)->sess_list)) == 1)
|
((__sMF) && (ogs_list_count(&(__sMF)->sess_list)) == 1)
|
||||||
ogs_list_t smf_ue_list;
|
ogs_list_t smf_ue_list;
|
||||||
|
@ -512,6 +519,13 @@ void smf_pf_identifier_pool_final(smf_bearer_t *bearer);
|
||||||
void smf_pf_precedence_pool_init(smf_sess_t *sess);
|
void smf_pf_precedence_pool_init(smf_sess_t *sess);
|
||||||
void smf_pf_precedence_pool_final(smf_sess_t *sess);
|
void smf_pf_precedence_pool_final(smf_sess_t *sess);
|
||||||
|
|
||||||
|
int smf_integrity_protection_indication_value2enum(const char *value);
|
||||||
|
int smf_confidentiality_protection_indication_value2enum(const char *value);
|
||||||
|
int smf_maximum_integrity_protected_data_rate_uplink_value2enum(
|
||||||
|
const char *value);
|
||||||
|
int smf_maximum_integrity_protected_data_rate_downlink_value2enum(
|
||||||
|
const char *value);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -33,6 +33,7 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer(
|
||||||
NGAP_GTPTunnel_t *gTPTunnel = NULL;
|
NGAP_GTPTunnel_t *gTPTunnel = NULL;
|
||||||
NGAP_DataForwardingNotPossible_t *DataForwardingNotPossible = NULL;
|
NGAP_DataForwardingNotPossible_t *DataForwardingNotPossible = NULL;
|
||||||
NGAP_PDUSessionType_t *PDUSessionType = NULL;
|
NGAP_PDUSessionType_t *PDUSessionType = NULL;
|
||||||
|
NGAP_SecurityIndication_t *SecurityIndication = NULL;
|
||||||
NGAP_QosFlowSetupRequestList_t *QosFlowSetupRequestList = NULL;
|
NGAP_QosFlowSetupRequestList_t *QosFlowSetupRequestList = NULL;
|
||||||
NGAP_QosFlowSetupRequestItem_t *QosFlowSetupRequestItem = NULL;
|
NGAP_QosFlowSetupRequestItem_t *QosFlowSetupRequestItem = NULL;
|
||||||
NGAP_QosFlowIdentifier_t *qosFlowIdentifier = NULL;
|
NGAP_QosFlowIdentifier_t *qosFlowIdentifier = NULL;
|
||||||
|
@ -129,6 +130,89 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer(
|
||||||
ogs_assert_if_reached();
|
ogs_assert_if_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (smf_self()->security_indication.integrity_protection_indication &&
|
||||||
|
smf_self()->security_indication.confidentiality_protection_indication) {
|
||||||
|
|
||||||
|
ie = CALLOC(1,
|
||||||
|
sizeof(NGAP_PDUSessionResourceSetupRequestTransferIEs_t));
|
||||||
|
ogs_assert(ie);
|
||||||
|
ASN_SEQUENCE_ADD(&message.protocolIEs, ie);
|
||||||
|
|
||||||
|
ie->id = NGAP_ProtocolIE_ID_id_SecurityIndication;
|
||||||
|
ie->criticality = NGAP_Criticality_reject;
|
||||||
|
ie->value.present = NGAP_PDUSessionResourceSetupRequestTransferIEs__value_PR_SecurityIndication;
|
||||||
|
|
||||||
|
SecurityIndication = &ie->value.choice.SecurityIndication;
|
||||||
|
|
||||||
|
SecurityIndication->integrityProtectionIndication =
|
||||||
|
smf_integrity_protection_indication_value2enum(
|
||||||
|
smf_self()->security_indication.
|
||||||
|
integrity_protection_indication);
|
||||||
|
ogs_assert(SecurityIndication->integrityProtectionIndication >= 0);
|
||||||
|
|
||||||
|
SecurityIndication->confidentialityProtectionIndication =
|
||||||
|
smf_confidentiality_protection_indication_value2enum(
|
||||||
|
smf_self()->security_indication.
|
||||||
|
confidentiality_protection_indication);
|
||||||
|
ogs_assert(SecurityIndication->
|
||||||
|
confidentialityProtectionIndication >= 0);
|
||||||
|
|
||||||
|
if (smf_self()->security_indication.
|
||||||
|
maximum_integrity_protected_data_rate_uplink) {
|
||||||
|
|
||||||
|
ogs_assert(
|
||||||
|
SecurityIndication->integrityProtectionIndication ==
|
||||||
|
NGAP_IntegrityProtectionIndication_required ||
|
||||||
|
SecurityIndication->integrityProtectionIndication ==
|
||||||
|
NGAP_IntegrityProtectionIndication_preferred);
|
||||||
|
|
||||||
|
SecurityIndication->maximumIntegrityProtectedDataRate_UL =
|
||||||
|
CALLOC(1, sizeof(NGAP_MaximumIntegrityProtectedDataRate_t));
|
||||||
|
ogs_assert(SecurityIndication->
|
||||||
|
maximumIntegrityProtectedDataRate_UL);
|
||||||
|
*(SecurityIndication->maximumIntegrityProtectedDataRate_UL) =
|
||||||
|
smf_maximum_integrity_protected_data_rate_uplink_value2enum(
|
||||||
|
smf_self()->security_indication.
|
||||||
|
maximum_integrity_protected_data_rate_uplink);
|
||||||
|
ogs_assert(
|
||||||
|
*(SecurityIndication->
|
||||||
|
maximumIntegrityProtectedDataRate_UL) >= 0);
|
||||||
|
|
||||||
|
if (smf_self()->security_indication.
|
||||||
|
maximum_integrity_protected_data_rate_downlink) {
|
||||||
|
NGAP_ProtocolExtensionContainer_9625P229_t *extContainer = NULL;
|
||||||
|
NGAP_SecurityIndication_ExtIEs_t *extIe = NULL;
|
||||||
|
NGAP_MaximumIntegrityProtectedDataRate_t
|
||||||
|
*MaximumIntegrityProtectedDataRate = NULL;
|
||||||
|
|
||||||
|
extContainer = CALLOC(1,
|
||||||
|
sizeof(NGAP_ProtocolExtensionContainer_9625P229_t));
|
||||||
|
ogs_assert(extContainer);
|
||||||
|
SecurityIndication->iE_Extensions =
|
||||||
|
(struct NGAP_ProtocolExtensionContainer *)extContainer;
|
||||||
|
|
||||||
|
extIe = CALLOC(1, sizeof(NGAP_SecurityIndication_ExtIEs_t));
|
||||||
|
ogs_assert(extIe);
|
||||||
|
ASN_SEQUENCE_ADD(&extContainer->list, extIe);
|
||||||
|
|
||||||
|
extIe->id =
|
||||||
|
NGAP_ProtocolIE_ID_id_MaximumIntegrityProtectedDataRate_DL;
|
||||||
|
extIe->criticality = NGAP_Criticality_ignore;
|
||||||
|
extIe->extensionValue.present = NGAP_SecurityIndication_ExtIEs__extensionValue_PR_MaximumIntegrityProtectedDataRate;
|
||||||
|
|
||||||
|
MaximumIntegrityProtectedDataRate =
|
||||||
|
&extIe->extensionValue.choice.
|
||||||
|
MaximumIntegrityProtectedDataRate;
|
||||||
|
|
||||||
|
*MaximumIntegrityProtectedDataRate =
|
||||||
|
smf_maximum_integrity_protected_data_rate_downlink_value2enum(
|
||||||
|
smf_self()->security_indication.
|
||||||
|
maximum_integrity_protected_data_rate_downlink);
|
||||||
|
ogs_assert(*MaximumIntegrityProtectedDataRate >= 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestTransferIEs_t));
|
ie = CALLOC(1, sizeof(NGAP_PDUSessionResourceSetupRequestTransferIEs_t));
|
||||||
ogs_assert(ie);
|
ogs_assert(ie);
|
||||||
ASN_SEQUENCE_ADD(&message.protocolIEs, ie);
|
ASN_SEQUENCE_ADD(&message.protocolIEs, ie);
|
||||||
|
|
Loading…
Reference in New Issue