aboutsummaryrefslogtreecommitdiffstats
path: root/extras/packetforge/ExpressionConverter.py
diff options
context:
space:
mode:
authorTing Xu <ting.xu@intel.com>2022-04-24 06:14:25 +0000
committerDave Wallace <dwallacelf@gmail.com>2022-09-20 20:44:42 +0000
commitce4b6451787389c5b0ebfac413c350ef3a424b8b (patch)
treeaa777368e14fca9b6613f747817331336ca2b11b /extras/packetforge/ExpressionConverter.py
parentf5e0a17c9cca09822296a0ed3196fde36c1ca5f8 (diff)
packetforge: add packetforge for generic flow to extras
Add a new tool packetforge to extras. This tool is to support generic flow. Packetforge is a library to translate naming or json profile format flow pattern to the required input of generic flow, i.e. spec and mask. Using python script flow_create.py, it can add and enable a new flow rule for an interface via flow VAPI, and can delete an existed flow rule as well. Command examples are shown below. Json profile examples can be found in ./parsegraph/samples. Naming format input: 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 python flow_create.py --del -i 1 -I 0 Json profile format input: python flow_create.py -f "./flow_rule_examples/mac_ipv4.json" -i 1 With this command, flow rule can be added or deleted, and the flow entry can be listed with "show flow entry" command in VPP CLI. Packetforge is based on a parsegraph. The parsegraph can be built by users. A Spec can be found in ./parsegraph as guidance. More details about packetforge are in README file. Type: feature Signed-off-by: Ting Xu <ting.xu@intel.com> Change-Id: Ia9f539741c5dca27ff236f2bcc493c5dd48c0df1
Diffstat (limited to 'extras/packetforge/ExpressionConverter.py')
-rw-r--r--extras/packetforge/ExpressionConverter.py162
1 files changed, 162 insertions, 0 deletions
diff --git a/extras/packetforge/ExpressionConverter.py b/extras/packetforge/ExpressionConverter.py
new file mode 100644
index 00000000000..1f9c73fedfa
--- /dev/null
+++ b/extras/packetforge/ExpressionConverter.py
@@ -0,0 +1,162 @@
+# Copyright (c) 2022 Intel and/or its affiliates.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from InputFormat import InputFormat
+
+
+def ByteArrayToString(data):
+ if len(data) == 0:
+ return ""
+
+ sb = []
+
+ for i in range(len(data) - 1):
+ sb.append("%02x" % data[i])
+
+ sb.append("%02x" % data[len(data) - 1])
+
+ return sb
+
+
+def ToNum(exp):
+ if exp == None:
+ return True, None
+
+ exp = exp.strip()
+
+ if exp.startswith("0x"):
+ out = int(exp, 16)
+ else:
+ try:
+ out = int(exp)
+ except:
+ return False, None
+
+ return True, out
+
+
+def ToIPv4Address(exp):
+ ipv4 = [0] * 4
+
+ exp = exp.strip()
+ tokens = exp.split(".")
+
+ if len(tokens) != 4:
+ return False, bytes(4)
+
+ for i in range(4):
+ u8 = int(tokens[i])
+ if u8 == None:
+ return False, bytes(4)
+
+ ipv4[i] = u8
+
+ return True, bytes(ipv4)
+
+
+def ToIPv6Address(exp):
+ ipv6 = [0] * 16
+
+ exp = exp.strip()
+ tokens = exp.split(":")
+
+ if len(tokens) != 8:
+ return False, bytes(16)
+
+ for i in range(8):
+ u16 = int(tokens[i], 16)
+ if u16 == None:
+ return False, bytes(16)
+
+ ipv6[i * 2] = u16 >> 8
+ ipv6[i * 2 + 1] = u16 & 0xFF
+
+ return True, bytes(ipv6)
+
+
+def ToMacAddress(exp):
+ mac = [0] * 6
+
+ exp = exp.strip()
+ tokens = exp.split(":")
+
+ if len(tokens) != 6:
+ return False, bytes(6)
+
+ for i in range(6):
+ u8 = int(tokens[i], 16)
+ if u8 == None:
+ return False, bytes(6)
+
+ mac[i] = u8
+
+ return True, bytes(mac)
+
+
+def ToByteArray(exp):
+ exp = exp.strip()
+ tokens = exp.split(",")
+
+ tmp = [] * len(tokens)
+
+ for i in range(len(tokens)):
+ _, num = ToNum(tokens[i])
+ if num == 0:
+ return False, bytes(len(tokens))
+
+ tmp[i] = ToNum(tokens[i])
+
+ return True, bytes(tmp)
+
+
+def Verify(format, expression):
+ if (
+ format == InputFormat.u8
+ or format == InputFormat.u16
+ or format == InputFormat.u32
+ or format == InputFormat.u64
+ ):
+ return ToNum(expression)
+ elif format == InputFormat.ipv4:
+ return ToIPv4Address(expression)
+ elif format == InputFormat.ipv6:
+ return ToIPv6Address(expression)
+ elif format == InputFormat.mac:
+ return ToMacAddress(expression)
+ elif format == InputFormat.bytearray:
+ return ToByteArray(expression)
+ else:
+ return False, 0
+
+
+def IncreaseValue(expression, size):
+ if expression == None:
+ return str(size)
+
+ _, num = ToNum(expression)
+ return str(num + size)
+
+
+def Equal(exp, val):
+ if exp == None:
+ num_1 = 0
+ else:
+ _, num_1 = ToNum(exp)
+ if not num_1:
+ return False
+
+ _, num_2 = ToNum(val)
+ if not num_2:
+ return False
+
+ return num_1 == num_2