Ting Xu | ce4b645 | 2022-04-24 06:14:25 +0000 | [diff] [blame] | 1 | # Copyright (c) 2022 Intel and/or its affiliates. |
| 2 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 3 | # you may not use this file except in compliance with the License. |
| 4 | # You may obtain a copy of the License at: |
| 5 | # |
| 6 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 7 | # |
| 8 | # Unless required by applicable law or agreed to in writing, software |
| 9 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 11 | # See the License for the specific language governing permissions and |
| 12 | # limitations under the License. |
| 13 | |
| 14 | from vpp_papi.vpp_papi import VPPApiClient |
| 15 | import sys, getopt |
| 16 | import packetforge |
| 17 | import fnmatch |
| 18 | import os |
| 19 | |
| 20 | # Get VPP json API file directory |
| 21 | CLIENT_ID = "Vppclient" |
| 22 | VPP_JSON_DIR = ( |
| 23 | os.path.abspath("../..") + "/build-root/install-vpp-native/vpp/share/vpp/api/core" |
| 24 | ) |
| 25 | VPP_JSON_DIR_PLUGIN = ( |
| 26 | os.path.abspath("../..") |
| 27 | + "/build-root/install-vpp-native/vpp/share/vpp/api/plugins" |
| 28 | ) |
| 29 | API_FILE_SUFFIX = "*.api.json" |
| 30 | |
| 31 | |
Ting Xu | ce4b645 | 2022-04-24 06:14:25 +0000 | [diff] [blame] | 32 | def load_json_api_files(suffix=API_FILE_SUFFIX): |
| 33 | jsonfiles = [] |
| 34 | json_dir = VPP_JSON_DIR |
| 35 | for root, dirnames, filenames in os.walk(json_dir): |
| 36 | for filename in fnmatch.filter(filenames, suffix): |
| 37 | jsonfiles.append(os.path.join(json_dir, filename)) |
| 38 | json_dir = VPP_JSON_DIR_PLUGIN |
| 39 | for root, dirnames, filenames in os.walk(json_dir): |
| 40 | for filename in fnmatch.filter(filenames, suffix): |
| 41 | jsonfiles.append(os.path.join(json_dir, filename)) |
| 42 | if not jsonfiles: |
| 43 | raise RuntimeError("Error: no json api files found") |
| 44 | else: |
| 45 | print("load json api file done") |
| 46 | return jsonfiles |
| 47 | |
| 48 | |
| 49 | def connect_vpp(jsonfiles): |
| 50 | vpp = VPPApiClient(apifiles=jsonfiles) |
| 51 | r = vpp.connect("CLIENT_ID") |
| 52 | print("VPP api opened with code: %s" % r) |
| 53 | return vpp |
| 54 | |
| 55 | |
Ting Xu | f34420f | 2023-03-16 01:22:33 +0000 | [diff] [blame^] | 56 | def Main(argv): |
| 57 | file_flag = False |
| 58 | operation = None |
| 59 | actions = "" |
| 60 | iface = "" |
| 61 | try: |
| 62 | opts, args = getopt.getopt( |
| 63 | argv, |
| 64 | "hf:p:a:i:I:", |
| 65 | [ |
| 66 | "help", |
| 67 | "add", |
| 68 | "del", |
| 69 | "show", |
| 70 | "file=", |
| 71 | "pattern=", |
| 72 | "actions=", |
| 73 | "interface=", |
| 74 | "flow-index=", |
| 75 | ], |
| 76 | ) |
| 77 | except getopt.GetoptError: |
| 78 | print( |
| 79 | "flow_create.py --add|del|show -f <file> -p <pattern> -a <actions> -i <interface> -I <flow-index>" |
| 80 | ) |
| 81 | sys.exit() |
| 82 | for opt, arg in opts: |
| 83 | if opt == "-h": |
| 84 | print( |
| 85 | "flow_create.py --add|del|show -f <file> -p <pattern> -a <actions> -i <interface> -I <flow-index>" |
| 86 | ) |
| 87 | sys.exit() |
| 88 | elif opt == "--add": |
| 89 | operation = "add" |
| 90 | elif opt == "--del": |
| 91 | operation = "del" |
| 92 | elif opt == "--show": |
| 93 | operation = "show" |
| 94 | elif opt in ("-f", "--file"): |
| 95 | json_file = arg |
| 96 | file_flag = True |
| 97 | elif opt in ("-p", "--pattern") and not file_flag: |
| 98 | pattern = arg |
| 99 | elif opt in ("-a", "--actions"): |
| 100 | actions = arg |
| 101 | elif opt in ("-i", "--interface"): |
| 102 | iface = arg |
| 103 | elif opt in ("-I", "--flow-index"): |
| 104 | flow_index = arg |
| 105 | |
| 106 | if operation == None: |
| 107 | print("Error: Please choose the operation: add or del") |
| 108 | sys.exit() |
| 109 | |
| 110 | if operation == "show": |
| 111 | if not file_flag: |
| 112 | result = packetforge.Forge(pattern, actions, False, True) |
| 113 | else: |
| 114 | result = packetforge.Forge(json_file, actions, True, True) |
| 115 | return result, None, operation, None, None |
| 116 | |
Ting Xu | ce4b645 | 2022-04-24 06:14:25 +0000 | [diff] [blame] | 117 | # Python API need json definitions to interpret messages |
| 118 | vpp = connect_vpp(load_json_api_files()) |
Ting Xu | ce4b645 | 2022-04-24 06:14:25 +0000 | [diff] [blame] | 119 | |
| 120 | # set inteface states |
Ting Xu | f34420f | 2023-03-16 01:22:33 +0000 | [diff] [blame^] | 121 | vpp.api.sw_interface_set_flags(sw_if_index=int(iface), flags=1) |
| 122 | |
| 123 | if operation == "add": |
| 124 | if not file_flag: |
| 125 | result = packetforge.Forge(pattern, actions, False, False) |
| 126 | else: |
| 127 | result = packetforge.Forge(json_file, actions, True, False) |
| 128 | return result, int(iface), operation, None, vpp |
| 129 | elif operation == "del": |
| 130 | return None, int(iface), operation, int(flow_index), vpp |
| 131 | |
| 132 | |
| 133 | if __name__ == "__main__": |
| 134 | # Parse the arguments |
| 135 | my_flow, iface, operation, del_flow_index, vpp = Main(sys.argv[1:]) |
| 136 | |
| 137 | # if operation is show, just show spec and mask, then exit |
| 138 | if operation == "show": |
| 139 | print(my_flow) |
| 140 | sys.exit() |
Ting Xu | ce4b645 | 2022-04-24 06:14:25 +0000 | [diff] [blame] | 141 | |
| 142 | if operation == "add": |
| 143 | # add flow |
| 144 | rv = vpp.api.flow_add_v2(flow=my_flow) |
| 145 | flow_index = rv[3] |
| 146 | print(rv) |
| 147 | |
| 148 | # enable added flow |
| 149 | rv = vpp.api.flow_enable(flow_index=flow_index, hw_if_index=iface) |
| 150 | ena_res = rv[2] |
| 151 | # if enable flow fail, delete added flow |
| 152 | if ena_res: |
| 153 | print("Error: enable flow failed, delete flow") |
| 154 | rv = vpp.api.flow_del(flow_index=flow_index) |
| 155 | print(rv) |
| 156 | |
| 157 | elif operation == "del": |
| 158 | # disable flow |
| 159 | rv = vpp.api.flow_disable(flow_index=del_flow_index, hw_if_index=iface) |
| 160 | dis_res = rv[2] |
| 161 | if dis_res: |
| 162 | print("Error: disable flow failed") |
| 163 | sys.exit() |
| 164 | print(rv) |
| 165 | |
| 166 | # delete flow |
| 167 | rv = vpp.api.flow_del(flow_index=del_flow_index) |
| 168 | print(rv) |
| 169 | |
| 170 | # command example: |
| 171 | # python flow_create.py --add -p "mac()/ipv4(src=1.1.1.1,dst=2.2.2.2)/udp()" -a "redirect-to-queue 3" -i 1 |
| 172 | # python flow_create.py --del -i 1 -I 0 |
Ting Xu | f34420f | 2023-03-16 01:22:33 +0000 | [diff] [blame^] | 173 | # python flow_create.py --show -p "mac()/ipv4(src=1.1.1.1,dst=2.2.2.2)/udp()" |