packetforge: add option to show spec and mask only
[vpp.git] / extras / packetforge / flow_create.py
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
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
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
117     # Python API need json definitions to interpret messages
118     vpp = connect_vpp(load_json_api_files())
119
120     # set inteface states
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()
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
173 # python flow_create.py --show -p "mac()/ipv4(src=1.1.1.1,dst=2.2.2.2)/udp()"