Daniele Moro | c9b4afe | 2021-08-26 18:07:01 +0200 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
| 3 | """ |
| 4 | Copyright 2021 Open Networking Foundation (ONF) |
| 5 | |
| 6 | Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>, |
| 7 | the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>, |
| 8 | or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg> |
| 9 | |
| 10 | """ |
| 11 | |
| 12 | FALSE = '0' |
| 13 | TRUE = '1' |
| 14 | DIR_UPLINK = '1' |
| 15 | DIR_DOWNLINK = '2' |
| 16 | IFACE_ACCESS = '1' |
| 17 | IFACE_CORE = '2' |
| 18 | TUNNEL_SPORT = '2152' |
| 19 | TUNNEL_TYPE_GPDU = '3' |
| 20 | |
| 21 | |
| 22 | class Up4LibCli(): |
| 23 | """ |
| 24 | Helper library to attach and detach UEs via UP4 P4Runtime APIs. |
| 25 | """ |
| 26 | |
| 27 | @staticmethod |
| 28 | def attachUe(p4rtCli, s1u_address, enb_address, pfcp_session_id, ue_address, |
| 29 | teid=None, up_id=None, down_id=None, |
| 30 | teid_up=None, teid_down=None, |
| 31 | pdr_id_up=None, far_id_up=None, ctr_id_up=None, |
| 32 | pdr_id_down=None, far_id_down=None, ctr_id_down=None, |
| 33 | qfi=None, five_g=False): |
| 34 | Up4LibCli.__programUp4Rules(p4rtCli, s1u_address, enb_address, |
| 35 | pfcp_session_id, |
| 36 | ue_address, |
| 37 | teid, up_id, down_id, |
| 38 | teid_up, teid_down, |
| 39 | pdr_id_up, far_id_up, ctr_id_up, |
| 40 | pdr_id_down, far_id_down, ctr_id_down, |
| 41 | qfi, five_g, action="program") |
| 42 | |
| 43 | @staticmethod |
| 44 | def detachUe(p4rtCli, s1u_address, enb_address, pfcp_session_id, ue_address, |
| 45 | teid=None, up_id=None, down_id=None, |
| 46 | teid_up=None, teid_down=None, |
| 47 | pdr_id_up=None, far_id_up=None, ctr_id_up=None, |
| 48 | pdr_id_down=None, far_id_down=None, ctr_id_down=None, |
| 49 | qfi=None, five_g=False): |
| 50 | Up4LibCli.__programUp4Rules(p4rtCli, s1u_address, enb_address, |
| 51 | pfcp_session_id, |
| 52 | ue_address, |
| 53 | teid, up_id, down_id, |
| 54 | teid_up, teid_down, |
| 55 | pdr_id_up, far_id_up, ctr_id_up, |
| 56 | pdr_id_down, far_id_down, ctr_id_down, |
| 57 | qfi, five_g, action="clear") |
| 58 | |
| 59 | @staticmethod |
| 60 | def __programUp4Rules(p4rtCli, s1u_address, enb_address, pfcp_session_id, |
| 61 | ue_address, |
| 62 | teid=None, up_id=None, down_id=None, |
| 63 | teid_up=None, teid_down=None, |
| 64 | pdr_id_up=None, far_id_up=None, ctr_id_up=None, |
| 65 | pdr_id_down=None, far_id_down=None, ctr_id_down=None, |
| 66 | qfi=None, five_g=False, action="program"): |
| 67 | if up_id is not None: |
| 68 | pdr_id_up = up_id |
| 69 | far_id_up = up_id |
| 70 | ctr_id_up = up_id |
| 71 | if down_id is not None: |
| 72 | pdr_id_down = down_id |
| 73 | far_id_down = down_id |
| 74 | ctr_id_down = down_id |
| 75 | if teid is not None: |
| 76 | teid_up = teid |
| 77 | teid_down = teid |
| 78 | |
| 79 | entries = [] |
| 80 | |
| 81 | # ========================# |
| 82 | # PDR Entries |
| 83 | # ========================# |
| 84 | |
| 85 | # Uplink |
| 86 | tableName = 'PreQosPipe.pdrs' |
| 87 | actionName = '' |
| 88 | matchFields = {} |
| 89 | actionParams = {} |
| 90 | if qfi is None: |
| 91 | actionName = 'PreQosPipe.set_pdr_attributes' |
| 92 | else: |
| 93 | actionName = 'PreQosPipe.set_pdr_attributes_qos' |
| 94 | if five_g: |
| 95 | # TODO: currently QFI_MATCH is unsupported in TNA |
| 96 | matchFields['has_qfi'] = TRUE |
| 97 | matchFields["qfi"] = str(qfi) |
| 98 | actionParams['needs_qfi_push'] = FALSE |
| 99 | actionParams['qfi'] = str(qfi) |
| 100 | # Match fields |
| 101 | matchFields['src_iface'] = IFACE_ACCESS |
| 102 | matchFields['ue_addr'] = str(ue_address) |
| 103 | matchFields['teid'] = str(teid_up) |
| 104 | matchFields['tunnel_ipv4_dst'] = str(s1u_address) |
| 105 | # Action params |
| 106 | actionParams['id'] = str(pdr_id_up) |
| 107 | actionParams['fseid'] = str(pfcp_session_id) |
| 108 | actionParams['ctr_id'] = str(ctr_id_up) |
| 109 | actionParams['far_id'] = str(far_id_up) |
| 110 | actionParams['needs_gtpu_decap'] = TRUE |
| 111 | if not Up4LibCli.__add_entry(p4rtCli, tableName, actionName, matchFields, |
| 112 | actionParams, entries, action): |
| 113 | return False |
| 114 | |
| 115 | # Downlink |
| 116 | tableName = 'PreQosPipe.pdrs' |
| 117 | actionName = '' |
| 118 | matchFields = {} |
| 119 | actionParams = {} |
| 120 | if qfi is None: |
| 121 | actionName = 'PreQosPipe.set_pdr_attributes' |
| 122 | else: |
| 123 | actionName = 'PreQosPipe.set_pdr_attributes_qos' |
| 124 | # TODO: currently QFI_PUSH is unsupported in TNA |
| 125 | actionParams['needs_qfi_push'] = TRUE if five_g else FALSE |
| 126 | actionParams['qfi'] = str(qfi) |
| 127 | # Match fields |
| 128 | matchFields['src_iface'] = IFACE_CORE |
| 129 | matchFields['ue_addr'] = str(ue_address) |
| 130 | # Action params |
| 131 | actionParams['id'] = str(pdr_id_down) |
| 132 | actionParams['fseid'] = str(pfcp_session_id) |
| 133 | actionParams['ctr_id'] = str(ctr_id_down) |
| 134 | actionParams['far_id'] = str(far_id_down) |
| 135 | actionParams['needs_gtpu_decap'] = FALSE |
| 136 | if not Up4LibCli.__add_entry(p4rtCli, tableName, actionName, matchFields, |
| 137 | actionParams, entries, action): |
| 138 | return False |
| 139 | |
| 140 | # ========================# |
| 141 | # FAR Entries |
| 142 | # ========================# |
| 143 | |
| 144 | # Uplink |
| 145 | tableName = 'PreQosPipe.load_far_attributes' |
| 146 | actionName = 'PreQosPipe.load_normal_far_attributes' |
| 147 | matchFields = {} |
| 148 | actionParams = {} |
| 149 | |
| 150 | # Match fields |
| 151 | matchFields['far_id'] = str(far_id_up) |
| 152 | matchFields['session_id'] = str(pfcp_session_id) |
| 153 | # Action params |
| 154 | actionParams['needs_dropping'] = FALSE |
| 155 | actionParams['notify_cp'] = FALSE |
| 156 | if not Up4LibCli.__add_entry(p4rtCli, tableName, actionName, matchFields, |
| 157 | actionParams, entries, action): |
| 158 | return False |
| 159 | |
| 160 | # Downlink |
| 161 | tableName = 'PreQosPipe.load_far_attributes' |
| 162 | actionName = 'PreQosPipe.load_tunnel_far_attributes' |
| 163 | matchFields = {} |
| 164 | actionParams = {} |
| 165 | |
| 166 | # Match fields |
| 167 | matchFields['far_id'] = str(far_id_down) |
| 168 | matchFields['session_id'] = str(pfcp_session_id) |
| 169 | # Action params |
| 170 | actionParams['needs_dropping'] = FALSE |
| 171 | actionParams['notify_cp'] = FALSE |
| 172 | actionParams['needs_buffering'] = FALSE |
| 173 | actionParams['tunnel_type'] = TUNNEL_TYPE_GPDU |
| 174 | actionParams['src_addr'] = str(s1u_address) |
| 175 | actionParams['dst_addr'] = str(enb_address) |
| 176 | actionParams['teid'] = str(teid_down) |
| 177 | actionParams['sport'] = TUNNEL_SPORT |
| 178 | if not Up4LibCli.__add_entry(p4rtCli, tableName, actionName, matchFields, |
| 179 | actionParams, entries, action): |
| 180 | return False |
| 181 | |
| 182 | if action == "program": |
| 183 | main.log.info("All entries added successfully.") |
| 184 | elif action == "clear": |
| 185 | Up4LibCli.__clear_entries(p4rtCli, entries) |
| 186 | |
| 187 | @staticmethod |
| 188 | def __add_entry(p4rtCli, tableName, actionName, matchFields, actionParams, |
| 189 | entries, action): |
| 190 | if action == "program": |
| 191 | p4rtCli.buildP4RtTableEntry(tableName=tableName, |
| 192 | actionName=actionName, |
| 193 | actionParams=actionParams, |
| 194 | matchFields=matchFields) |
| 195 | if p4rtCli.pushTableEntry(debug=True) == main.TRUE: |
| 196 | main.log.info("*** Entry added.") |
| 197 | else: |
| 198 | main.log.error("Error during table insertion") |
| 199 | Up4LibCli.__clear_entries(p4rtCli, entries) |
| 200 | return False |
| 201 | entries.append({"tableName": tableName, "actionName": actionName, |
| 202 | "matchFields": matchFields, |
| 203 | "actionParams": actionParams}) |
| 204 | return True |
| 205 | |
| 206 | @staticmethod |
| 207 | def __clear_entries(p4rtCli, entries): |
| 208 | for i, entry in enumerate(entries): |
| 209 | p4rtCli.buildP4RtTableEntry(**entry) |
| 210 | if p4rtCli.deleteTableEntry(debug=True) == main.TRUE: |
| 211 | main.log.info("*** Entry %d of %d deleted." % (i + 1, len(entries))) |
| 212 | else: |
| 213 | main.log.error("Error during table delete") |