packetforge: add packetforge for generic flow to extras
[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 Main(argv):
33     file_flag = False
34     operation = None
35     try:
36         opts, args = getopt.getopt(
37             argv,
38             "hf:p:a:i:I:",
39             [
40                 "help=",
41                 "add",
42                 "del",
43                 "file=",
44                 "pattern=",
45                 "actions=",
46                 "interface=",
47                 "flow-index=",
48             ],
49         )
50     except getopt.GetoptError:
51         print(
52             "flow_create.py --add|del -f <file> -p <pattern> -a <actions> -i <interface> -I <flow-index>"
53         )
54         sys.exit()
55     for opt, arg in opts:
56         if opt == "-h":
57             print(
58                 "flow_create.py --add|del -f <file> -p <pattern> -a <actions> -i <interface> -I <flow-index>"
59             )
60             sys.exit()
61         elif opt == "--add":
62             operation = "add"
63         elif opt == "--del":
64             operation = "del"
65         elif opt in ("-f", "--file"):
66             actions = ""
67             json_file = arg
68             file_flag = True
69         elif opt in ("-p", "--pattern") and not file_flag:
70             pattern = arg
71         elif opt in ("-a", "--actions"):
72             actions = arg
73         elif opt in ("-i", "--interface"):
74             iface = arg
75         elif opt in ("-I", "--flow-index"):
76             flow_index = arg
77
78     if operation == None:
79         print("Error: Please choose the operation: add or del")
80         sys.exit()
81
82     if operation == "add":
83         if not file_flag:
84             result = packetforge.Forge(pattern, actions, False)
85         else:
86             result = packetforge.Forge(json_file, actions, True)
87         return result, int(iface), operation, None
88     elif operation == "del":
89         return None, int(iface), operation, int(flow_index)
90
91
92 def load_json_api_files(suffix=API_FILE_SUFFIX):
93     jsonfiles = []
94     json_dir = VPP_JSON_DIR
95     for root, dirnames, filenames in os.walk(json_dir):
96         for filename in fnmatch.filter(filenames, suffix):
97             jsonfiles.append(os.path.join(json_dir, filename))
98     json_dir = VPP_JSON_DIR_PLUGIN
99     for root, dirnames, filenames in os.walk(json_dir):
100         for filename in fnmatch.filter(filenames, suffix):
101             jsonfiles.append(os.path.join(json_dir, filename))
102     if not jsonfiles:
103         raise RuntimeError("Error: no json api files found")
104     else:
105         print("load json api file done")
106     return jsonfiles
107
108
109 def connect_vpp(jsonfiles):
110     vpp = VPPApiClient(apifiles=jsonfiles)
111     r = vpp.connect("CLIENT_ID")
112     print("VPP api opened with code: %s" % r)
113     return vpp
114
115
116 if __name__ == "__main__":
117     # Python API need json definitions to interpret messages
118     vpp = connect_vpp(load_json_api_files())
119     print(vpp.api.show_version())
120
121     # Parse the arguments
122     my_flow, iface, operation, del_flow_index = Main(sys.argv[1:])
123
124     # set inteface states
125     vpp.api.sw_interface_set_flags(sw_if_index=iface, flags=1)
126
127     if operation == "add":
128         # add flow
129         rv = vpp.api.flow_add_v2(flow=my_flow)
130         flow_index = rv[3]
131         print(rv)
132
133         # enable added flow
134         rv = vpp.api.flow_enable(flow_index=flow_index, hw_if_index=iface)
135         ena_res = rv[2]
136         # if enable flow fail, delete added flow
137         if ena_res:
138             print("Error: enable flow failed, delete flow")
139             rv = vpp.api.flow_del(flow_index=flow_index)
140         print(rv)
141
142     elif operation == "del":
143         # disable flow
144         rv = vpp.api.flow_disable(flow_index=del_flow_index, hw_if_index=iface)
145         dis_res = rv[2]
146         if dis_res:
147             print("Error: disable flow failed")
148             sys.exit()
149         print(rv)
150
151         # delete flow
152         rv = vpp.api.flow_del(flow_index=del_flow_index)
153         print(rv)
154
155 # command example:
156 # 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
157 # python flow_create.py --del -i 1 -I 0