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
|
||||
# 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:
|
||||
sbi:
|
||||
- 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;
|
||||
}
|
||||
|
||||
|
@ -825,6 +902,40 @@ int smf_context_parse_config(void)
|
|||
} while (ogs_yaml_iter_type(&info_array) ==
|
||||
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")) {
|
||||
/* handle config in pfcp library */
|
||||
} 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;
|
||||
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 */
|
||||
|
||||
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) \
|
||||
((__sMF) && (ogs_list_count(&(__sMF)->sess_list)) == 1)
|
||||
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_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
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -33,6 +33,7 @@ ogs_pkbuf_t *ngap_build_pdu_session_resource_setup_request_transfer(
|
|||
NGAP_GTPTunnel_t *gTPTunnel = NULL;
|
||||
NGAP_DataForwardingNotPossible_t *DataForwardingNotPossible = NULL;
|
||||
NGAP_PDUSessionType_t *PDUSessionType = NULL;
|
||||
NGAP_SecurityIndication_t *SecurityIndication = NULL;
|
||||
NGAP_QosFlowSetupRequestList_t *QosFlowSetupRequestList = NULL;
|
||||
NGAP_QosFlowSetupRequestItem_t *QosFlowSetupRequestItem = 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();
|
||||
}
|
||||
|
||||
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));
|
||||
ogs_assert(ie);
|
||||
ASN_SEQUENCE_ADD(&message.protocolIEs, ie);
|
||||
|
|
Loading…
Reference in New Issue