[PFCP] Support associating multiple URRs to a PDR (#1456)

* [PFCP] Fix trailing whitespace in message generation files

* [PFCP] message gen: Support multiple URR ID IEs in Create PDR group

* [PFCP] Support associating multiple URRs to a PDR

According to 3GPP TS 29.244:
"""
A PDR shall contain:
- zero, one or more URRs, which contains instructions related to traffic measurement and reporting.
"""
This commit is contained in:
Pau Espin 2022-03-28 14:56:58 +02:00 committed by GitHub
parent 825b06b6e0
commit 4b8d3a845a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 59 additions and 38 deletions

View File

@ -339,9 +339,10 @@ void ogs_pfcp_build_create_pdr(
message->far_id.u32 = pdr->far->id;
}
if (pdr->urr) {
message->urr_id.presence = 1;
message->urr_id.u32 = pdr->urr->id;
ogs_assert(pdr->num_of_urr <= OGS_ARRAY_SIZE(message->urr_id));
for (i = 0; i < pdr->num_of_urr; i++) {
message->urr_id[i].presence = 1;
message->urr_id[i].u32 = pdr->urr[i]->id;
}
if (pdr->qer) {

View File

@ -969,8 +969,16 @@ void ogs_pfcp_pdr_associate_urr(ogs_pfcp_pdr_t *pdr, ogs_pfcp_urr_t *urr)
{
ogs_assert(pdr);
ogs_assert(urr);
ogs_assert(pdr->num_of_urr < OGS_ARRAY_SIZE(pdr->urr));
int i;
pdr->urr = urr;
/* Avoid storing duplicate pointers */
for (i = 0; i < pdr->num_of_urr; i++) {
if (pdr->urr[i]->id == urr->id)
return;
}
pdr->urr[pdr->num_of_urr++] = urr;
}
void ogs_pfcp_pdr_associate_qer(ogs_pfcp_pdr_t *pdr, ogs_pfcp_qer_t *qer)
{

View File

@ -169,7 +169,10 @@ typedef struct ogs_pfcp_pdr_s {
uint8_t qfi;
ogs_pfcp_far_t *far;
ogs_pfcp_urr_t *urr;
int num_of_urr;
ogs_pfcp_urr_t *urr[OGS_MAX_NUM_OF_URR];
ogs_pfcp_qer_t *qer;
int num_of_flow;

View File

@ -471,12 +471,15 @@ ogs_pfcp_pdr_t *ogs_pfcp_handle_create_pdr(ogs_pfcp_sess_t *sess,
ogs_pfcp_pdr_associate_far(pdr, far);
}
pdr->urr = NULL;
if (message->urr_id.presence) {
urr = ogs_pfcp_urr_find_or_add(sess, message->urr_id.u32);
ogs_assert(urr);
ogs_pfcp_pdr_associate_urr(pdr,urr);
for (i = 0; i < OGS_ARRAY_SIZE(pdr->urr); i++)
pdr->urr[i] = NULL;
pdr->num_of_urr = 0;
for (i = 0; i < OGS_ARRAY_SIZE(message->urr_id); i++) {
if (message->urr_id[i].presence) {
urr = ogs_pfcp_urr_find_or_add(sess, message->urr_id[i].u32);
ogs_assert(urr);
ogs_pfcp_pdr_associate_urr(pdr,urr);
}
}
pdr->qer = NULL;

View File

@ -20,7 +20,7 @@
/*******************************************************************************
* This file had been created by pfcp-tlv.py script v0.1.0
* Please do not modify this file but regenerate it via script.
* Created on: 2021-10-04 22:09:12.905975 by acetcom
* Created on: 2022-03-28 12:29:26.113044 by pespin
* from 29244-g10.docx
******************************************************************************/
@ -1575,6 +1575,7 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_create_pdr =
&ogs_pfcp_tlv_desc_outer_header_removal,
&ogs_pfcp_tlv_desc_far_id,
&ogs_pfcp_tlv_desc_urr_id,
&ogs_tlv_desc_more8,
&ogs_pfcp_tlv_desc_qer_id,
&ogs_pfcp_tlv_desc_activate_predefined_rules,
&ogs_pfcp_tlv_desc_activation_time,
@ -1758,6 +1759,7 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_access_forwarding_action_information_1 =
&ogs_pfcp_tlv_desc_weight,
&ogs_pfcp_tlv_desc_priority,
&ogs_pfcp_tlv_desc_urr_id,
&ogs_tlv_desc_more8,
NULL,
}
};
@ -1775,6 +1777,7 @@ ogs_tlv_desc_t ogs_pfcp_tlv_desc_access_forwarding_action_information_2 =
&ogs_pfcp_tlv_desc_weight,
&ogs_pfcp_tlv_desc_priority,
&ogs_pfcp_tlv_desc_urr_id,
&ogs_tlv_desc_more8,
NULL,
}
};
@ -2753,7 +2756,7 @@ int ogs_pfcp_parse_msg(ogs_pfcp_message_t *pfcp_message, ogs_pkbuf_t *pkbuf)
h = (ogs_pfcp_header_t *)pkbuf->data;
ogs_assert(h);
memset(pfcp_message, 0, sizeof(ogs_pfcp_message_t));
if (h->seid_presence)

View File

@ -20,7 +20,7 @@
/*******************************************************************************
* This file had been created by pfcp-tlv.py script v0.1.0
* Please do not modify this file but regenerate it via script.
* Created on: 2021-10-04 22:09:12.899719 by acetcom
* Created on: 2022-03-28 12:29:26.101574 by pespin
* from 29244-g10.docx
******************************************************************************/
@ -654,7 +654,7 @@ typedef struct ogs_pfcp_tlv_create_pdr_s {
ogs_pfcp_tlv_pdi_t pdi;
ogs_pfcp_tlv_outer_header_removal_t outer_header_removal;
ogs_pfcp_tlv_far_id_t far_id;
ogs_pfcp_tlv_urr_id_t urr_id;
ogs_pfcp_tlv_urr_id_t urr_id[8];
ogs_pfcp_tlv_qer_id_t qer_id;
ogs_pfcp_tlv_activate_predefined_rules_t activate_predefined_rules;
ogs_pfcp_tlv_activation_time_t activation_time;
@ -747,7 +747,7 @@ typedef struct ogs_pfcp_tlv_access_forwarding_action_information_1_s {
ogs_pfcp_tlv_far_id_t far_id;
ogs_pfcp_tlv_weight_t weight;
ogs_pfcp_tlv_priority_t priority;
ogs_pfcp_tlv_urr_id_t urr_id;
ogs_pfcp_tlv_urr_id_t urr_id[8];
} ogs_pfcp_tlv_access_forwarding_action_information_1_t;
typedef struct ogs_pfcp_tlv_access_forwarding_action_information_2_s {
@ -755,7 +755,7 @@ typedef struct ogs_pfcp_tlv_access_forwarding_action_information_2_s {
ogs_pfcp_tlv_far_id_t far_id;
ogs_pfcp_tlv_weight_t weight;
ogs_pfcp_tlv_priority_t priority;
ogs_pfcp_tlv_urr_id_t urr_id;
ogs_pfcp_tlv_urr_id_t urr_id[8];
} ogs_pfcp_tlv_access_forwarding_action_information_2_t;
typedef struct ogs_pfcp_tlv_update_access_forwarding_action_information_1_s {

View File

@ -14,7 +14,8 @@ ies.append({ "ie_type" : "Precedence", "ie_value" : "Precedence", "presence" : "
ies.append({ "ie_type" : "PDI", "ie_value" : "PDI", "presence" : "M", "tlv_more" : "0", "comment" : "This IE shall contain the PDI against which incoming packets will be matched.See Table 7.5.2.2-2."})
ies.append({ "ie_type" : "Outer Header Removal", "ie_value" : "Outer Header Removal", "presence" : "C", "tlv_more" : "0", "comment" : "This IE shall be present if the UP function is required to remove one or more outer header(s) from the packets matching this PDR."})
ies.append({ "ie_type" : "FAR ID", "ie_value" : "FAR ID", "presence" : "C", "tlv_more" : "0", "comment" : "This IE shall be present if the Activate Predefined Rules IE is not included or if it is included but it does not result in activating a predefined FAR, and if the MAR ID is not included.When present this IE shall contain the FAR ID to be associated to the PDR."})
ies.append({ "ie_type" : "URR ID", "ie_value" : "URR ID", "presence" : "C", "tlv_more" : "0", "comment" : "This IE shall be present if a measurement action shall be applied to packets matching this PDR.When present, this IE shall contain the URR IDs to be associated to the PDR.Several IEs within the same IE type may be present to represent a list of URRs to be associated to the PDR."})
type_list["URR ID"]["max_tlv_more"] = "7"
ies.append({ "ie_type" : "URR ID", "ie_value" : "URR ID", "presence" : "C", "tlv_more" : "7", "comment" : "This IE shall be present if a measurement action shall be applied to packets matching this PDR.When present, this IE shall contain the URR IDs to be associated to the PDR.Several IEs within the same IE type may be present to represent a list of URRs to be associated to the PDR."})
ies.append({ "ie_type" : "QER ID", "ie_value" : "QER ID", "presence" : "C", "tlv_more" : "0", "comment" : "This IE shall be present if a QoS enforcement or QoS marking action shall be applied to packets matching this PDR.When present, this IE shall contain the QER IDs to be associated to the PDR. Several IEs within the same IE type may be present to represent a list of QERs to be associated to the PDR."})
ies.append({ "ie_type" : "Activate Predefined Rules", "ie_value" : "Activate Predefined Rules", "presence" : "C", "tlv_more" : "0", "comment" : "This IE shall be present if Predefined Rule(s) shall be activated for this PDR. When present this IE shall contain one Predefined Rules name.Several IEs with the same IE type may be present to represent multiple Activate Predefined Rules names."})
ies.append({ "ie_type" : "Activation Time", "ie_value" : "Activation Time", "presence" : "O", "tlv_more" : "0", "comment" : "This IE may be present if the PDR activation shall be deferred. (NOTE 1)"})
@ -143,7 +144,7 @@ ies = []
ies.append({ "ie_type" : "FAR ID", "ie_value" : "FAR ID", "presence" : "M", "tlv_more" : "0", "comment" : "This IE shall uniquely identify the FAR among all the FARs configured for this PFCP session. "})
ies.append({ "ie_type" : "Weight", "ie_value" : "Weight", "presence" : "C", "tlv_more" : "0", "comment" : "This IE shall be present if steering mode is set to Load Balancing to identify the weight of the FAR.(NOTE 1) "})
ies.append({ "ie_type" : "Priority", "ie_value" : "Priority", "presence" : "C", "tlv_more" : "0", "comment" : "This IE shall be present if the steering mode is set to Active-Standby or Priority-based. (NOTE 2)"})
ies.append({ "ie_type" : "URR ID", "ie_value" : "URR ID", "presence" : "C", "tlv_more" : "0", "comment" : "This IE shall uniquely identify the URR among all the URRs configured for the PFCP session. This enables the SMF to request separate usage reports for different FARs (i.e. different accesses) (NOTE 3)Several IEs within the same IE type may be present to represent a list of URRs to be associated to the FAR."})
ies.append({ "ie_type" : "URR ID", "ie_value" : "URR ID", "presence" : "C", "tlv_more" : "7", "comment" : "This IE shall uniquely identify the URR among all the URRs configured for the PFCP session. This enables the SMF to request separate usage reports for different FARs (i.e. different accesses) (NOTE 3)Several IEs within the same IE type may be present to represent a list of URRs to be associated to the FAR."})
group_list["Access Forwarding Action Information 1"] = { "index" : "266", "type" : "166", "ies" : ies }
group_list["Access Forwarding Action Information 2"] = { "index" : "267", "type" : "167", "ies" : ies }
ies = []

View File

@ -103,7 +103,7 @@ def get_cells(cells):
comment = re.sub('\n|\"|\'|\\\\', '', comment);
#print comment
ie_type = re.sub('\s*$', '', re.sub('\'\s*\n*\s*\(NOTE.*\)*', '', cells[-1].text))
#if ie_type.find('Usage Report') != -1:
if ie_type == 'Usage Report':
if comment.find('Report Type') != -1:
@ -114,7 +114,7 @@ def get_cells(cells):
ie_type = "Usage Report Session Deletion Response"
else:
assert False, "Unknown IE type : [Usage Report]"
if ie_type == 'Update BAR':
if comment.find('7.5.4.11-1') != -1:
ie_type = "Update BAR Session Modification Request"
@ -122,7 +122,7 @@ def get_cells(cells):
ie_type = "Update BAR PFCP Session Report Response"
else:
assert False, "Unknown IE type : [Update BAR]"
if ie_type.find('PFD Contents') != -1:
ie_type = 'PFD contents'
elif ie_type.find('UE IP address') != -1:
@ -154,6 +154,8 @@ def get_cells(cells):
tlv_more = "3"
if ie_type == 'SDF Filter':
tlv_more = "7"
if ie_type == 'URR ID' and comment.find('Several IEs within the same IE type may be present') != -1:
tlv_more = "7"
if int(tlv_more) > int(type_list[ie_type]["max_tlv_more"]):
type_list[ie_type]["max_tlv_more"] = tlv_more
@ -193,7 +195,7 @@ for o, a in opts:
sys.exit(2)
if os.path.isfile(filename) and os.access(filename, os.R_OK):
file = open(filename, 'r')
file = open(filename, 'r')
else:
d_error("Cannot find file : " + filename)
@ -204,7 +206,7 @@ if os.path.isfile(cachefile) and os.access(cachefile, os.R_OK):
print("Read from " + cachefile)
else:
document = Document(filename)
f = open(cachefile, 'w')
f = open(cachefile, 'w')
msg_table = ""
for i, table in enumerate(document.tables):
@ -236,7 +238,7 @@ if os.path.isfile(cachefile) and os.access(cachefile, os.R_OK):
print("Read from " + cachefile)
else:
document = Document(filename)
f = open(cachefile, 'w')
f = open(cachefile, 'w')
ie_table = ""
for i, table in enumerate(document.tables):
@ -270,7 +272,7 @@ if os.path.isfile(cachefile) and os.access(cachefile, os.R_OK):
print("Read from " + cachefile)
else:
document = Document(filename)
f = open(cachefile, 'w')
f = open(cachefile, 'w')
for i, table in enumerate(document.tables):
try:
@ -309,18 +311,18 @@ else:
elif (int(ie_type) == 79):
ie_name = "Usage Report Session Deletion Response"
elif (int(ie_type) == 80):
ie_name = "Usage Report Session Report Request"
ie_name = "Usage Report Session Report Request"
elif (int(ie_type) == 86):
ie_name = "Update BAR Session Modification Request"
ie_name = "Update BAR Session Modification Request"
elif (int(ie_type) == 12):
ie_name = "Update BAR PFCP Session Report Response"
ie_name = "Update BAR PFCP Session Report Response"
if ie_name.find('Access Forwarding Action Information 2') != -1:
ie_idx = str(int(ie_type)+100)
group_list[ie_name] = { "index" : ie_idx, "type" : ie_type, "ies" : ies }
write_file(f, "group_list[\"" + ie_name + "\"] = { \"index\" : \"" + ie_idx + "\", \"type\" : \"" + ie_type + "\", \"ies\" : ies }\n")
continue
if ie_name not in group_list.keys():
ies = []
write_file(f, "ies = []\n")
@ -338,7 +340,7 @@ else:
f.close()
msg_list["PFCP Heartbeat Request"]["table"] = 7
msg_list["PFCP Heartbeat Response"]["table"] = 8
msg_list["PFCP Heartbeat Response"]["table"] = 8
msg_list["PFCP PFD Management Request"]["table"] = 9
msg_list["PFCP PFD Management Response"]["table"] = 12
msg_list["PFCP Association Setup Request"]["table"] = 13
@ -370,7 +372,7 @@ for key in msg_list.keys():
print("Read from " + cachefile)
else:
document = Document(filename)
f = open(cachefile, 'w')
f = open(cachefile, 'w')
table = document.tables[msg_list[key]["table"]]
if key.find('Association') != -1:
@ -379,7 +381,7 @@ for key in msg_list.keys():
start_i = 1
else:
start_i = 2
ies = []
write_file(f, "ies = []\n")
if key != "PFCP Session Deletion Request" and key != "PFCP Version Not Supported Response":
@ -579,7 +581,7 @@ for (k, v) in sorted_group_list:
f.write("typedef struct ogs_pfcp_tlv_" + v_lower(k) + "_s {\n")
f.write(" ogs_tlv_presence_t presence;\n")
for ies in group_list[k]["ies"]:
if type_list[ies["ie_type"]]["max_tlv_more"] != "0":
if type_list[ies["ie_type"]]["max_tlv_more"] != "0" and ies["tlv_more"] != "0":
f.write(" ogs_pfcp_tlv_" + v_lower(ies["ie_type"]) + "_t " + v_lower(ies["ie_value"]) + "[" + str(int(ies["tlv_more"])+1) + "];\n")
else:
f.write(" ogs_pfcp_tlv_" + v_lower(ies["ie_type"]) + "_t " + \
@ -592,7 +594,7 @@ for (k, v) in sorted_msg_list:
if "ies" in msg_list[k]:
f.write("typedef struct ogs_" + v_lower(k) + "_s {\n")
for ies in msg_list[k]["ies"]:
if type_list[ies["ie_type"]]["max_tlv_more"] != "0":
if type_list[ies["ie_type"]]["max_tlv_more"] != "0" and ies["tlv_more"] != "0":
f.write(" ogs_pfcp_tlv_" + v_lower(ies["ie_type"]) + "_t " + v_lower(ies["ie_value"]) + "[" + str(int(ies["tlv_more"])+1) + "];\n")
else:
f.write(" ogs_pfcp_tlv_" + v_lower(ies["ie_type"]) + "_t " + v_lower(ies["ie_value"]) + ";\n")
@ -667,7 +669,7 @@ for (k, v) in sorted_group_list:
f.write(" {\n")
for ies in group_list[k]["ies"]:
f.write(" &ogs_pfcp_tlv_desc_%s,\n" % v_lower(ies["ie_type"]))
if type_list[ies["ie_type"]]["max_tlv_more"] != "0":
if type_list[ies["ie_type"]]["max_tlv_more"] != "0" and ies["tlv_more"] != "0":
f.write(" &ogs_tlv_desc_more" + str(int(ies["tlv_more"])+1) + ",\n")
f.write(" NULL,\n")
f.write(" }\n")
@ -682,7 +684,7 @@ for (k, v) in sorted_msg_list:
f.write(" 0, 0, 0, 0, {\n")
for ies in msg_list[k]["ies"]:
f.write(" &ogs_pfcp_tlv_desc_%s,\n" % v_lower(ies["ie_type"]))
if type_list[ies["ie_type"]]["max_tlv_more"] != "0":
if type_list[ies["ie_type"]]["max_tlv_more"] != "0" and ies["tlv_more"] != "0":
f.write(" &ogs_tlv_desc_more" + str(int(ies["tlv_more"])+1) + ",\n")
f.write(" NULL,\n")
f.write("}};\n\n")
@ -700,7 +702,7 @@ f.write("""int ogs_pfcp_parse_msg(ogs_pfcp_message_t *pfcp_message, ogs_pkbuf_t
h = (ogs_pfcp_header_t *)pkbuf->data;
ogs_assert(h);
memset(pfcp_message, 0, sizeof(ogs_pfcp_message_t));
if (h->seid_presence)