--- /dev/null
+This directory (and its subdirectories)
+contain files that have to be distributed under GPL license,
+mostly because of linking with scapy.
+
+When migrating more files here, make sure to migrate
+also everything linking with them.
+
+Currently the license listed is still Apache 2.0,
+we are waiting for sign-offs as described in
+https://wiki.fd.io/view/TSC/Relicensing_Procedure
+before we switch the licenses.
#!/usr/bin/python3
-# Copyright (c) 2019 Cisco and/or its affiliates.
+# Copyright (c) 2020 Cisco 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:
-# Copyright (c) 2019 Cisco and/or its affiliates.
+# Copyright (c) 2020 Cisco 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:
-# Copyright (c) 2019 Cisco and/or its affiliates.
+# Copyright (c) 2020 Cisco 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:
--- /dev/null
+# Copyright (c) 2020 Cisco 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.
+
+"""
+__init__ file for directory traffic_scripts
+"""
from scapy.layers.l2 import Ether
from scapy.packet import Raw
-from resources.libraries.python.PacketVerifier import RxQueue, TxQueue
-from resources.libraries.python.TrafficScriptArg import TrafficScriptArg
+from .PacketVerifier import RxQueue, TxQueue
+from .TrafficScriptArg import TrafficScriptArg
def check_ipsec(
from scapy.layers.l2 import Ether
from scapy.packet import Raw
-from resources.libraries.python.PacketVerifier import RxQueue, TxQueue
-from resources.libraries.python.TrafficScriptArg import TrafficScriptArg
+from .PacketVerifier import RxQueue, TxQueue
+from .TrafficScriptArg import TrafficScriptArg
def check_ipsec(pkt_recv, ip_layer, dst_tun, src_ip, dst_ip, sa_in):
--- /dev/null
+# Copyright (c) 2020 Cisco 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.
+
+"""
+__init__ file for directory lisp
+"""
#!/usr/bin/env python3
-# Copyright (c) 2019 Cisco and/or its affiliates.
+# Copyright (c) 2020 Cisco 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:
from scapy.layers.l2 import Ether
from scapy.packet import Raw
-from resources.libraries.python.PacketVerifier import RxQueue, TxQueue
-from resources.libraries.python.TrafficScriptArg import TrafficScriptArg
+from ..PacketVerifier import RxQueue, TxQueue
+from ..TrafficScriptArg import TrafficScriptArg
class LispHeader(Packet):
#!/usr/bin/env python3
-# Copyright (c) 2019 Cisco and/or its affiliates.
+# Copyright (c) 2020 Cisco 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:
from scapy.layers.l2 import Ether
from scapy.packet import Raw
-from resources.libraries.python.PacketVerifier import RxQueue, TxQueue
-from resources.libraries.python.TrafficScriptArg import TrafficScriptArg
+from ..PacketVerifier import RxQueue, TxQueue
+from ..TrafficScriptArg import TrafficScriptArg
class LispGPEHeader(Packet):
#!/usr/bin/env python3
-# Copyright (c) 2019 Cisco and/or its affiliates.
+# Copyright (c) 2020 Cisco 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:
from scapy.layers.inet6 import IPv6, ICMPv6ND_NS
from scapy.packet import Raw
-from resources.libraries.python.TrafficScriptArg import TrafficScriptArg
-from resources.libraries.python.PacketVerifier import RxQueue, TxQueue
+from .TrafficScriptArg import TrafficScriptArg
+from .PacketVerifier import RxQueue, TxQueue
def check_ipv4(pkt_recv, dscp):
#!/usr/bin/env python3
-# Copyright (c) 2016 Cisco and/or its affiliates.
+# Copyright (c) 2020 Cisco 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:
from scapy.layers.l2 import Ether
from scapy.packet import Raw
-from resources.libraries.python.PacketVerifier import RxQueue, TxQueue
-from resources.libraries.python.TrafficScriptArg import TrafficScriptArg
+from .PacketVerifier import RxQueue, TxQueue
+from .TrafficScriptArg import TrafficScriptArg
def valid_ipv4(ip):
#!/usr/bin/env python3
-# Copyright (c) 2019 Cisco and/or its affiliates.
+# Copyright (c) 2020 Cisco 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:
from scapy.layers.l2 import Ether, Dot1Q
from scapy.packet import Raw
-from resources.libraries.python.PacketVerifier import RxQueue, TxQueue
-from resources.libraries.python.TrafficScriptArg import TrafficScriptArg
+from .PacketVerifier import RxQueue, TxQueue
+from .TrafficScriptArg import TrafficScriptArg
def valid_ipv4(ip):
#!/usr/bin/env python3
-# Copyright (c) 2019 Cisco and/or its affiliates.
+# Copyright (c) 2020 Cisco 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:
from scapy.layers.l2 import Ether
from scapy.packet import Raw
-from resources.libraries.python.PacketVerifier import RxQueue, TxQueue
-from resources.libraries.python.TrafficScriptArg import TrafficScriptArg
-from resources.traffic_scripts import vxlan
+from .PacketVerifier import RxQueue, TxQueue
+from .TrafficScriptArg import TrafficScriptArg
+from . import vxlan
def main():
from scapy.layers.l2 import Ether
from scapy.packet import Raw
-from resources.libraries.python.PacketVerifier import RxQueue, TxQueue
-from resources.libraries.python.TrafficScriptArg import TrafficScriptArg
+from .PacketVerifier import RxQueue, TxQueue
+from .TrafficScriptArg import TrafficScriptArg
def check_srv6(
--- /dev/null
+# Copyright (c) 2020 Cisco 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 scapy.fields import BitField, XByteField, X3BytesField
+from scapy.layers.inet import UDP
+from scapy.layers.l2 import Ether
+from scapy.packet import Packet, bind_layers
+
+
+class VXLAN(Packet):
+ name = u"VXLAN"
+ fields_desc = [
+ BitField(u"flags", 0x08000000, 32),
+ X3BytesField(u"vni", 0),
+ XByteField(u"reserved", 0x00)
+ ]
+
+ def mysummary(self):
+ return self.sprintf(f"VXLAN (vni={VXLAN.vni})")
+
+bind_layers(UDP, VXLAN, dport=4789)
+bind_layers(VXLAN, Ether)
:param loss_acceptance: Permitted drop ratio or frames count.
:param loss_acceptance_type: Type of permitted loss.
:param traffic_profile: Module name as a traffic profile identifier.
- See resources/traffic_profiles/trex for implemented modules.
+ See GPL/traffic_profiles/trex for implemented modules.
:param skip_warmup: Start TRex without warmup traffic if true.
:type rate: float
:type frame_size: str
)
raise RuntimeError(u"Start TRex failed!")
- # Test if TRex starts successfully.
- cmd = f"sh -c \"{Constants.REMOTE_FW_DIR}/resources/tools/" \
- f"trex/trex_server_info.py\""
+ # Test if TRex starts successfuly.
+ command_line = OptionString().add(u"python3")
+ dirname = f"{Constants.REMOTE_FW_DIR}/GPL/tools/trex"
+ command_line.add(f"'{dirname}/trex_server_info.py'")
try:
exec_cmd_no_error(
- tg_node, cmd, sudo=True,
+ tg_node, command_line, sudo=True,
message=u"Test TRex failed!", retries=20
)
except RuntimeError:
:raises RuntimeError: If stop traffic script fails.
"""
# No need to check subtype, we know it is TREX.
- x_args = u""
+ command_line = OptionString().add(u"python3")
+ dirname = f"{Constants.REMOTE_FW_DIR}/GPL/tools/trex"
+ command_line.add(f"'{dirname}/trex_stateless_stop.py'")
+ command_line.change_prefix(u"--")
for index, value in enumerate(self._xstats):
if value is not None:
- # Nested quoting is fun.
value = value.replace(u"'", u"\"")
- x_args += f" --xstat{index}='\"'\"'{value}'\"'\"'"
+ command_line.add_equals(f"xstat{index}", f"'{value}'")
stdout, _ = exec_cmd_no_error(
- node, f"sh -c '{Constants.REMOTE_FW_DIR}/resources/tools/trex/"
- f"trex_stateless_stop.py{x_args}'",
- message=u"TRex stateless runtime error"
+ node, command_line, message=u"TRex stateless runtime error"
)
self._parse_traffic_results(stdout)
:param rate: Traffic rate expressed with units (pps, %)
:param frame_size: L2 frame size to send (without padding and IPG).
:param traffic_profile: Module name as a traffic profile identifier.
- See resources/traffic_profiles/trex for implemented modules.
+ See GPL/traffic_profiles/trex for implemented modules.
:param async_call: If enabled then don't wait for all incomming trafic.
:param latency: With latency measurement.
:param warmup_time: Warmup time period.
# No need to check subtype, we know it is TREX.
reorder = self._ifaces_reordered # Just to make the next line fit.
p_0, p_1 = (rx_port, tx_port) if reorder else (tx_port, rx_port)
-
if not isinstance(duration, (float, int)):
duration = float(duration)
if not isinstance(warmup_time, (float, int)):
warmup_time = float(warmup_time)
- command = f"sh -c \"" \
- f"{Constants.REMOTE_FW_DIR}/resources/tools/trex/" \
- f"trex_stateless_profile.py " \
- f"--profile {Constants.REMOTE_FW_DIR}/resources/" \
- f"traffic_profiles/trex/{traffic_profile}.py " \
- f"--duration {duration!r} --frame_size {frame_size} " \
- f"--rate {rate!r} --warmup_time {warmup_time!r} " \
- f"--port_0 {p_0} --port_1 {p_1} " \
- f"--traffic_directions {traffic_directions}"
- if async_call:
- command += u" --async_start"
- if latency:
- command += u" --latency"
- if Constants.TREX_SEND_FORCE:
- command += u" --force"
- command += u"\""
+
+ command_line = OptionString().add(u"python3")
+ dirname = f"{Constants.REMOTE_FW_DIR}/GPL/tools/trex"
+ command_line.add(f"'{dirname}/trex_stateless_profile.py'")
+ command_line.change_prefix(u"--")
+ dirname = f"{Constants.REMOTE_FW_DIR}/GPL/traffic_profiles/trex"
+ quoted_path = f"'{dirname}/{traffic_profile}.py'"
+ command_line.add_with_value(u"profile", quoted_path)
+ command_line.add_with_value(u"duration", f"{duration!r}")
+ command_line.add_with_value(u"frame_size", frame_size)
+ command_line.add_with_value(u"rate", f"{rate!r}")
+ command_line.add_with_value(u"warmup_time", f"{warmup_time!r}")
+ command_line.add_with_value(u"port_0", p_0)
+ command_line.add_with_value(u"port_1", p_1)
+ command_line.add_with_value(u"traffic_directions", traffic_directions)
+ command_line.add_if(u"async_start", async_call)
+ command_line.add_if(u"latency", latency)
+ command_line.add_if(u"force", Constants.TREX_SEND_FORCE)
stdout, _ = exec_cmd_no_error(
- self._node, command, timeout=float(duration) + 60,
+ self._node, command_line, timeout=float(duration) + 60,
message=u"TRex stateless runtime error"
)
:param rate: Offered load per interface (e.g. 1%, 3gbps, 4mpps, ...).
:param frame_size: Frame size (L2) in Bytes.
:param traffic_profile: Module name as a traffic profile identifier.
- See resources/traffic_profiles/trex for implemented modules.
+ See GPL/traffic_profiles/trex for implemented modules.
:param warmup_time: Warmup phase in seconds.
:param async_call: Async mode.
:param latency: With latency measurement.
:param frame_size: Frame size identifier or value [B].
:param traffic_profile: Module name as a traffic profile identifier.
- See resources/traffic_profiles/trex for implemented modules.
+ See GPL/traffic_profiles/trex for implemented modules.
:param warmup_time: Traffic duration before measurement starts [s].
:param traffic_directions: Traffic is bi- (2) or uni- (1) directional.
Default: 2
:param frame_size: Frame size identifier or value [B].
:param traffic_profile: Module name as a traffic profile identifier.
- See resources/traffic_profiles/trex for implemented modules.
+ See GPL/traffic_profiles/trex for implemented modules.
:param minimum_transmit_rate: Minimal uni-directional
target transmit rate [pps].
:param maximum_transmit_rate: Maximal uni-directional
:param frame_size: Frame size identifier or value [B].
:param traffic_profile: Module name as a traffic profile identifier.
- See resources/traffic_profiles/trex for implemented modules.
+ See GPL/traffic_profiles/trex for implemented modules.
:param minimum_transmit_rate: Minimal uni-directional
target transmit rate [pps].
:param maximum_transmit_rate: Maximal uni-directional
-# Copyright (c) 2019 Cisco and/or its affiliates.
+# Copyright (c) 2020 Cisco 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:
"""
ssh = SSH()
ssh.connect(node)
+ module_name = script_file_name[:-3].replace('/', '.')
cmd = f"cd {Constants.REMOTE_FW_DIR}; virtualenv -p $(which python3) " \
f"--system-site-packages --never-download env && " \
f"export PYTHONPATH=${{PWD}}; . ${{PWD}}/env/bin/activate; " \
- f"resources/traffic_scripts/{script_file_name} {script_args}"
-
+ f"cd GPL; python -m traffic_scripts.{module_name} {script_args}"
ret_code, stdout, stderr = ssh.exec_command_sudo(
f'sh -c "{TrafficScriptExecutor._escape(cmd)}"', timeout=timeout
)
--- /dev/null
+#!/usr/bin/env bash
+
+# Copyright (c) 2020 Cisco 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.
+
+set -exuo pipefail
+
+if [[ "${#}" != "1" ]]; then
+ echo 'An utility to switch license comment blocks.'
+ echo 'Requires files "gpl_block.txt" and "apache_block.txt" in the working'
+ echo 'directory, and a single argument pointing to root directory.'
+ echo 'Affects only .sh and .py files.'
+ exit 1
+fi
+
+find "${1}" \( -name "*.py" -o -name "*.sh" \) -print0 | xargs -0 \
+python3 replace.py "apache_block.txt" "gpl_block.txt"
--- /dev/null
+# 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.
--- /dev/null
+#!/usr/bin/env bash
+
+# Copyright (c) 2020 Cisco 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.
+
+set -exuo pipefail
+
+if [[ "${#}" != "1" ]]; then
+ echo 'An utility to switch license comment blocks.'
+ echo 'Requires files "gpl_block.txt" and "apache_block.txt" in the working'
+ echo 'directory, and a single argument pointing to root directory.'
+ echo 'Affects only .sh and .py files.'
+ exit 1
+fi
+
+find "${1}" \( -name "*.py" -o -name "*.sh" \) -print0 | xargs -0 \
+python3 replace.py "gpl_block.txt" "apache_block.txt"
--- /dev/null
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This file is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this file. If not, see <https://www.gnu.org/licenses/>.
--- /dev/null
+#!/usr/bin/env python3
+
+# Copyright (c) 2020 Cisco 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.
+
+"""A script simplifying replacement of blocks of lines.
+
+A bash solution created by combining these two:
+ https://unix.stackexchange.com/a/181215
+ https://stackoverflow.com/a/23849180
+does not seem to work if the blocks contain complicated characters.
+"""
+
+import argparse
+import os
+import tempfile
+
+def main():
+ """Main function for the block replacing script."""
+
+ description = '''Replace a block of lines with another block.
+
+ Both block-to-replace and replacing-block are read from a file.
+ The replacement is performed on a file, in-place.
+ Only first block occurence is replaced.
+ If the block-to-replace is preceded by a partial match,
+ it may not be recognized.
+
+ The current implementation uses temporary files,
+ created in the working directory.
+ if something fails, thise temporary files need to be deleted manually.
+
+ TODO: Preserve target attributes. Maybe https://pypi.org/project/in-place/
+'''
+ parser = argparse.ArgumentParser(description)
+ parser.add_argument(
+ u"before", type=str,
+ help=u"Path to file containing the old content to replace."
+ )
+ parser.add_argument(
+ u"after", type=str,
+ help=u"Path to file containing the new content to replace with."
+ )
+ parser.add_argument(
+ u"targets", metavar=u"target", nargs=u"+", type=str,
+ help=u"Paths to file where the replacement should be made."
+ )
+ args = parser.parse_args()
+
+ do_it(args)
+
+
+def do_it(args):
+ """Read contents, create edited target, replace the original target with it.
+
+ :param args: Parsed command line arguments.
+ :type args: Object (typically argparse.Namespace) which contains
+ "before", "after" and "target" fields.
+ """
+ with open(args.before, u"r") as file_in:
+ content_before = file_in.readlines()
+ before_len = len(content_before)
+ with open(args.after, u"r") as file_in:
+ content_after = file_in.readlines()
+
+ for target in args.targets:
+ with tempfile.NamedTemporaryFile(
+ dir=u".", mode=u"w", delete=False
+ ) as file_out:
+ with open(target, u"r") as file_in:
+ # Phase one, searching for content, copying what does not match.
+ buffer_lines = list()
+ line_index_to_check = 0
+ content_found = False
+ while 1:
+ line_in = file_in.readline()
+ if not line_in:
+ print(f"{target}: Content not found.")
+ for line_out in buffer_lines:
+ file_out.write(line_out)
+ buffer_lines = list()
+ break
+ if line_in != content_before[line_index_to_check]:
+ line_index_to_check = 0
+ if buffer_lines:
+ for line_out in buffer_lines:
+ file_out.write(line_out)
+ buffer_lines = list()
+ file_out.write(line_in)
+ continue
+ buffer_lines.append(line_in)
+ line_index_to_check += 1
+ if line_index_to_check < before_len:
+ continue
+ # Buffer has the match! Do not write it.
+ content_found = True
+ break
+ if not content_found:
+ file_out.close()
+ os.remove(file_out.name)
+ continue
+ # Phase two, write the replacement instead.
+ for line_out in content_after:
+ file_out.write(line_out)
+ # Phase three, copy the rest of the file.
+ while 1:
+ line_in = file_in.readline()
+ if not line_in:
+ print(f"{target}: Replacement done.")
+ break
+ file_out.write(line_in)
+ os.replace(file_out.name, target)
+
+
+if __name__ == u"__main__":
+ main()
+++ /dev/null
-from scapy.fields import BitField, XByteField, X3BytesField
-from scapy.layers.inet import UDP
-from scapy.layers.l2 import Ether
-from scapy.packet import Packet, bind_layers
-
-
-class VXLAN(Packet):
- name = u"VXLAN"
- fields_desc = [
- BitField(u"flags", 0x08000000, 32),
- X3BytesField(u"vni", 0),
- XByteField(u"reserved", 0x00)
- ]
-
- def mysummary(self):
- return self.sprintf(f"VXLAN (vni={VXLAN.vni})")
-
-bind_layers(UDP, VXLAN, dport=4789)
-bind_layers(VXLAN, Ether)