blob: 73dd39bcb8b3ee5b9036d9bde4cd0cc714df9e3e [file] [log] [blame]
#!/usr/bin/env python
"""
Copyright 2021 Open Networking Foundation (ONF)
Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
"""
FALSE = '0'
TRUE = '1'
DIR_UPLINK = '1'
DIR_DOWNLINK = '2'
IFACE_ACCESS = '1'
IFACE_CORE = '2'
TUNNEL_SPORT = '2152'
TUNNEL_TYPE_GPDU = '3'
class Up4LibCli():
"""
Helper library to attach and detach UEs via UP4 P4Runtime APIs.
"""
@staticmethod
def attachUe(p4rtCli, s1u_address, enb_address, pfcp_session_id, ue_address,
teid=None, up_id=None, down_id=None,
teid_up=None, teid_down=None,
pdr_id_up=None, far_id_up=None, ctr_id_up=None,
pdr_id_down=None, far_id_down=None, ctr_id_down=None,
qfi=None, five_g=False):
Up4LibCli.__programUp4Rules(p4rtCli, s1u_address, enb_address,
pfcp_session_id,
ue_address,
teid, up_id, down_id,
teid_up, teid_down,
pdr_id_up, far_id_up, ctr_id_up,
pdr_id_down, far_id_down, ctr_id_down,
qfi, five_g, action="program")
@staticmethod
def detachUe(p4rtCli, s1u_address, enb_address, pfcp_session_id, ue_address,
teid=None, up_id=None, down_id=None,
teid_up=None, teid_down=None,
pdr_id_up=None, far_id_up=None, ctr_id_up=None,
pdr_id_down=None, far_id_down=None, ctr_id_down=None,
qfi=None, five_g=False):
Up4LibCli.__programUp4Rules(p4rtCli, s1u_address, enb_address,
pfcp_session_id,
ue_address,
teid, up_id, down_id,
teid_up, teid_down,
pdr_id_up, far_id_up, ctr_id_up,
pdr_id_down, far_id_down, ctr_id_down,
qfi, five_g, action="clear")
@staticmethod
def __programUp4Rules(p4rtCli, s1u_address, enb_address, pfcp_session_id,
ue_address,
teid=None, up_id=None, down_id=None,
teid_up=None, teid_down=None,
pdr_id_up=None, far_id_up=None, ctr_id_up=None,
pdr_id_down=None, far_id_down=None, ctr_id_down=None,
qfi=None, five_g=False, action="program"):
if up_id is not None:
pdr_id_up = up_id
far_id_up = up_id
ctr_id_up = up_id
if down_id is not None:
pdr_id_down = down_id
far_id_down = down_id
ctr_id_down = down_id
if teid is not None:
teid_up = teid
teid_down = teid
entries = []
# ========================#
# PDR Entries
# ========================#
# Uplink
tableName = 'PreQosPipe.pdrs'
actionName = ''
matchFields = {}
actionParams = {}
if qfi is None:
actionName = 'PreQosPipe.set_pdr_attributes'
else:
actionName = 'PreQosPipe.set_pdr_attributes_qos'
if five_g:
# TODO: currently QFI_MATCH is unsupported in TNA
matchFields['has_qfi'] = TRUE
matchFields["qfi"] = str(qfi)
actionParams['needs_qfi_push'] = FALSE
actionParams['qfi'] = str(qfi)
# Match fields
matchFields['src_iface'] = IFACE_ACCESS
matchFields['ue_addr'] = str(ue_address)
matchFields['teid'] = str(teid_up)
matchFields['tunnel_ipv4_dst'] = str(s1u_address)
# Action params
actionParams['id'] = str(pdr_id_up)
actionParams['fseid'] = str(pfcp_session_id)
actionParams['ctr_id'] = str(ctr_id_up)
actionParams['far_id'] = str(far_id_up)
actionParams['needs_gtpu_decap'] = TRUE
if not Up4LibCli.__add_entry(p4rtCli, tableName, actionName, matchFields,
actionParams, entries, action):
return False
# Downlink
tableName = 'PreQosPipe.pdrs'
actionName = ''
matchFields = {}
actionParams = {}
if qfi is None:
actionName = 'PreQosPipe.set_pdr_attributes'
else:
actionName = 'PreQosPipe.set_pdr_attributes_qos'
# TODO: currently QFI_PUSH is unsupported in TNA
actionParams['needs_qfi_push'] = TRUE if five_g else FALSE
actionParams['qfi'] = str(qfi)
# Match fields
matchFields['src_iface'] = IFACE_CORE
matchFields['ue_addr'] = str(ue_address)
# Action params
actionParams['id'] = str(pdr_id_down)
actionParams['fseid'] = str(pfcp_session_id)
actionParams['ctr_id'] = str(ctr_id_down)
actionParams['far_id'] = str(far_id_down)
actionParams['needs_gtpu_decap'] = FALSE
if not Up4LibCli.__add_entry(p4rtCli, tableName, actionName, matchFields,
actionParams, entries, action):
return False
# ========================#
# FAR Entries
# ========================#
# Uplink
tableName = 'PreQosPipe.load_far_attributes'
actionName = 'PreQosPipe.load_normal_far_attributes'
matchFields = {}
actionParams = {}
# Match fields
matchFields['far_id'] = str(far_id_up)
matchFields['session_id'] = str(pfcp_session_id)
# Action params
actionParams['needs_dropping'] = FALSE
actionParams['notify_cp'] = FALSE
if not Up4LibCli.__add_entry(p4rtCli, tableName, actionName, matchFields,
actionParams, entries, action):
return False
# Downlink
tableName = 'PreQosPipe.load_far_attributes'
actionName = 'PreQosPipe.load_tunnel_far_attributes'
matchFields = {}
actionParams = {}
# Match fields
matchFields['far_id'] = str(far_id_down)
matchFields['session_id'] = str(pfcp_session_id)
# Action params
actionParams['needs_dropping'] = FALSE
actionParams['notify_cp'] = FALSE
actionParams['needs_buffering'] = FALSE
actionParams['tunnel_type'] = TUNNEL_TYPE_GPDU
actionParams['src_addr'] = str(s1u_address)
actionParams['dst_addr'] = str(enb_address)
actionParams['teid'] = str(teid_down)
actionParams['sport'] = TUNNEL_SPORT
if not Up4LibCli.__add_entry(p4rtCli, tableName, actionName, matchFields,
actionParams, entries, action):
return False
if action == "program":
main.log.info("All entries added successfully.")
elif action == "clear":
Up4LibCli.__clear_entries(p4rtCli, entries)
@staticmethod
def __add_entry(p4rtCli, tableName, actionName, matchFields, actionParams,
entries, action):
if action == "program":
p4rtCli.buildP4RtTableEntry(tableName=tableName,
actionName=actionName,
actionParams=actionParams,
matchFields=matchFields)
if p4rtCli.pushTableEntry(debug=True) == main.TRUE:
main.log.info("*** Entry added.")
else:
main.log.error("Error during table insertion")
Up4LibCli.__clear_entries(p4rtCli, entries)
return False
entries.append({"tableName": tableName, "actionName": actionName,
"matchFields": matchFields,
"actionParams": actionParams})
return True
@staticmethod
def __clear_entries(p4rtCli, entries):
for i, entry in enumerate(entries):
p4rtCli.buildP4RtTableEntry(**entry)
if p4rtCli.deleteTableEntry(debug=True) == main.TRUE:
main.log.info("*** Entry %d of %d deleted." % (i + 1, len(entries)))
else:
main.log.error("Error during table delete")