diff options
author | Ting Xu <ting.xu@intel.com> | 2022-04-24 06:14:25 +0000 |
---|---|---|
committer | Dave Wallace <dwallacelf@gmail.com> | 2022-09-20 20:44:42 +0000 |
commit | ce4b6451787389c5b0ebfac413c350ef3a424b8b (patch) | |
tree | aa777368e14fca9b6613f747817331336ca2b11b /extras/packetforge/ExpressionConverter.py | |
parent | f5e0a17c9cca09822296a0ed3196fde36c1ca5f8 (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.py | 162 |
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 |