diff options
70 files changed, 14908 insertions, 36 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..42388658 --- /dev/null +++ b/.gitignore @@ -0,0 +1,57 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*.confc + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +eggs/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.cache +nosetests.xml +coverage.xml + +# Translations +*.mo +*.pot + +# Log files: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# SublimeText +*.sublime-project +*.sublime-workspace diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..91dc6d25 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,65 @@ +# General Coding Style + +## Code + +Abide by [PEP-8] for general code. Some particular points to note: + +* Wrap code at 79 characters. +* Use only spaces - no tabs. +* Use implicit string concatenation where possible. Don't use the escape + character unless absolutely necessary. +* Be liberal in your use of whitespace to group related statements together. + However, don't leave a space after the docstring and the first statement. +* Use single quotes for all string literals. + +## Documentation + +Follow [PEP-257] and the [Sphinx guidelines] for documentation. In particular: + +* Wrap docstrings at 72 characters. +* Use double-quotes for all docstrings. +* Write all inline comments in lower-case, except where using a name/initialism. +* Document **all** library functions/classes completely. Tests, however, only need a test case docstring. + +To summarise the docstring conventions: + +```python +def my_function(athing, stuff=5): + """ + Summary line here in imperative tense. + + Longer description here... + + :param athing: Details about this paramter here + :param stuff: Ditto + + :returns: None + """ + pass # code here... +``` + +### Validation + +All code should be checked with the PyLint linter and PEP8 style guide checker. +Pylint can be run like so: + +```bash +pylint <file or directory> +``` + +Most PyLint errors should be resolved. You will need to do this manually. +However, there are cases where they may not make sense (e.g. you **need** to +pass `N` parameters to a function). In this case, disable the relevant +case using an inline `disable` like so: + +```python +# pylint: disable=[code] +``` + +On the other hand, all PEP8 errors should be resolved. + +--- + +[PEP-8]: http://legacy.python.org/dev/peps/pep-0008/ +[PEP-257]: http://legacy.python.org/dev/peps/pep-0257/ +[Sphinx guidelines]: https://pythonhosted.org/an_example_pypi_project/sphinx.html diff --git a/LICENSE.toit b/LICENSE.toit new file mode 100644 index 00000000..67db8588 --- /dev/null +++ b/LICENSE.toit @@ -0,0 +1,175 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. @@ -0,0 +1,8 @@ +========================================================================= +== OpenStack Neutron Notice == +========================================================================= + +Portions of this software were based on software developed by VMWare, Inc. + +Copyright 2011 VMWare Inc. +All rights reserved. diff --git a/README b/README deleted file mode 100644 index 2b6705cd..00000000 --- a/README +++ /dev/null @@ -1,36 +0,0 @@ -# vswitchperf project directory layout: ---------------------------------------- - -\- vswitchperf - \- src - directory to manage upstream packages - |- package-list.mk - list of all related package url and tags - \- mk - contains common makefiles - \- dpdk - sub folder for dpdk package - \- ovs - sub folder for ovs package - \- systems - contains linux distributions - |- build_base_machine.sh - Input for generating Makefiles - \- Fedora - Fedora specific setup - \- Ubuntu - Ubuntu specific setup - \- vswitches - API to setup vswitches DUT - |- add_switch - script to add switch - |- add_port - script to add ports on switch - |- add_flow - script to add flow on switch - \- ovs-dpdk - contains implementation on ovs-dpdk - \- ovs-kernel - contains implementation on ovs-kernel - \- tools - collections of tool sets - \- pktgen - contains various packet generator - |- dpkt-pktgen - dpdk pkt generator - |- pktgen - netmap pkt generator - |- pktcounter - a kernel based packet generator - |- spirent - script to control spirent - |- ixia - script to control ixia - \- collectors - contains various data collectors - \- testcases - collections of test cases - |- p2p - test PHY to PHY - |- pvp - test PHY to VNF to PHY - |- pvvp - test PHY to VNF to VNF to PHY - |- p2v - test PHY to VNF - |- v2p - test VNF to PHY - \- jobs - collections of job configurations - |- dpdk.conf - dpdk configuration - \- test_spec - contains test specifications diff --git a/README.md b/README.md new file mode 100644 index 00000000..c9cdd6dc --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +# VSPERF - vSwitch Performance Tests + +Documentation for this project including the [quickstart guide] is contained +under the ./docs directory. + +--- + +[quickstart guide]: docs/quickstart.md diff --git a/conf/00_common.conf b/conf/00_common.conf new file mode 100644 index 00000000..ef1c6280 --- /dev/null +++ b/conf/00_common.conf @@ -0,0 +1,61 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +# ########################### +# Common setting potentially accessed by all components. +# ########################### + +import os + +# ############################ +# Directories +# ############################ + +ROOT_DIR = os.path.normpath(os.path.join( + os.path.dirname(os.path.realpath(__file__)), '../')) +TRAFFICGEN_DIR = os.path.join(ROOT_DIR, 'tools/pkt_gen') +SYSMETRICS_DIR = os.path.join(ROOT_DIR, 'tools/collectors') + +# ############################ +# Process configuration +# ############################ + +# shell command to use when running commands through Pexpect +SHELL_CMD = ['/bin/bash', '-c'] + +# ############################ +# Logging configuration +# ############################ + +# default log output directory for all logs +LOG_DIR = '/tmp' + +# default log for all "small" executables +LOG_FILE_DEFAULT = 'overall.log' + +# log file for all commands executed on host +LOG_FILE_HOST_CMDS = 'host-cmds.log' + +# ############################ +# Test configuration +# ############################ + +# verbosity of output to 'stdout' +# NOTE: output to log files is always 'debug' level +VERBOSITY = 'debug' + +# dictionary of test-specific parameters. These values are accessible +# from anywhere in the test framework so be careful with naming +# conventions +TEST_PARAMS = {} diff --git a/conf/01_testcases.conf b/conf/01_testcases.conf new file mode 100755 index 00000000..42090df4 --- /dev/null +++ b/conf/01_testcases.conf @@ -0,0 +1,40 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +# This file describes a list of testcases. Each testcase is described as a +# dictionary in a list of dictionaries. +# +# The dictionary keys, their meanings and available values are: +# +# "Name": "phy2phy_burst", # A human-readable string identifying the +# # test. +# "Traffic Type": "rfc2544", # One of the supported traffic types. +# "Collector": "cpu, memory", # Comma-separated list of Collectors to +# # be activated during this test. +# "Deployment": "p2p", # One of the supported deployment scenarios. +# "Description": "Lorem ipsum..." # Optional. A human-readable string +# # describing the test. +# "MultiStream": [true|false], +# "Test Modifier": [FrameMod|Other], +# "Dependency": [Test_Case_Name |None], + +PERFORMANCE_TESTS = [ + { + "Name": "phy2phy_tput", + "Traffic Type": "rfc2544", + "Collector": "cpu", + "Deployment": "p2p", + "Description": "RFC2544 Throughput Phy2Phy Loopback", + }, +] diff --git a/conf/02_vswitch.conf b/conf/02_vswitch.conf new file mode 100644 index 00000000..8b6a80a0 --- /dev/null +++ b/conf/02_vswitch.conf @@ -0,0 +1,78 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +# ############################ +# vswitch configuration +# ############################ +RTE_SDK = '~/dpdk' +OVS_DIR = '~/openvswitch' + +# ############################ +# DPDK configuration +# ############################ + +# DPDK target used when builing DPDK +RTE_TARGET = 'x86_64-ivshmem-linuxapp-gcc' + +# list of NIC HWIDs which will be bound to the 'igb_uio' driver on +# system init +WHITELIST_NICS = ['05:00.0', '05:00.1'] + +# list of NIC HWIDs which will be ignored by the 'igb_uio' driver on +# system init +BLACKLIST_NICS = ['0000:09:00.0', '0000:09:00.1', '0000:09:00.2', + '0000:09:00.3'] + +# These are DPDK EAL parameters and they may need to be changed depending on +# hardware configuration, like cpu numbering and NUMA. +VSWITCHD_DPDK_ARGS = ['-c', '0x4', '-n', '4', '--socket-mem 1024,0'] + +# directory where hugepages will be mounted on system init +HUGEPAGE_DIR = '/dev/hugepages' + +# list of tuples of format (path, module_name), which will be inserted +# using 'insmod' on system init + +# for OVS modules the path is in reference to the OVS directory. +OVS_MODULES = [] + +# for DPDK_MODULES the path is in reference to the build directory +DPDK_MODULES = [ + ('kmod', 'igb_uio'), +] + +VHOST_MODULE = [ + ('eventfd_link', 'eventfd_link') +] + +# list of modules that will be inserted using 'modprobe' on system init +SYS_MODULES = ['uio', 'cuse'] + +# vhost character device file used by dpdkvhostport QemuWrap cases +VHOST_DEV_FILE = 'ovs-vhost-net' + +# location of vhost-user sockets +VHOST_USER_SOCKS = ['/tmp/dpdkvhostuser0', '/tmp/dpdkvhostuser1', + '/tmp/dpdkvhostuser2', '/tmp/dpdkvhostuser3', + '/tmp/myport0', '/tmp/helloworld123', '/tmp/abcstuff0'] + +# log file for ovs-vswitchd +LOG_FILE_VSWITCHD = 'vswitchd.log' + +# log file for ovs-dpdk +LOG_FILE_OVS = 'ovs.log' + +VSWITCH_DIR = os.path.join(ROOT_DIR, 'vswitches') +VSWITCH = "OvsDpdkVhost" + diff --git a/conf/03_traffic.conf b/conf/03_traffic.conf new file mode 100644 index 00000000..efc1b2f6 --- /dev/null +++ b/conf/03_traffic.conf @@ -0,0 +1,57 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +# ############################ +# Traffic gen configuration +# ############################ + +# log file for all traffic generator related commands +LOG_FILE_TRAFFIC_GEN = 'traffic-gen.log' + +#path to traffic generators directory. +TRAFFICGEN_DIR = os.path.join(ROOT_DIR, 'tools/pkt_gen') + +# traffic generator to use in tests +TRAFFICGEN = 'IxNet' + +# List of packet sizes to send. +# Expand like this: (64, 128, 256, 512, 1024) +TRAFFICGEN_PKT_SIZES = (64,) + +# path to 'ixos' install path +TRAFFICGEN_IXIA_ROOT_DIR = '/opt/ixos' + +# network address of IXIA chassis +TRAFFICGEN_IXIA_HOST = '' + +TRAFFICGEN_IXIA_CARD = '' + +TRAFFICGEN_IXIA_PORT1 = '' + +TRAFFICGEN_IXIA_PORT2 = '' + +TRAFFICGEN_IXNET_LIB_PATH = '/opt/ixnetwork/lib/IxTclNetwork' + +# IxNetwork host IP address +TRAFFICGEN_IXNET_MACHINE = '' +TRAFFICGEN_IXNET_PORT = '' +TRAFFICGEN_IXNET_USER = '' +TRAFFICGEN_IXNET_CHASSIS = '' + +# The result directory on $TRAFFICGEN_IXNET_MACHINE +TRAFFICGEN_IXNET_TESTER_RESULT_DIR = '' + +# The result directory on DUT. This needs to map to the same directory +# as the previous one +TRAFFICGEN_IXNET_DUT_RESULT_DIR = '' diff --git a/conf/04_vnf.conf b/conf/04_vnf.conf new file mode 100644 index 00000000..2603d589 --- /dev/null +++ b/conf/04_vnf.conf @@ -0,0 +1,58 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +# ############################ +# VNF configuration +# ############################ +QEMU_DIR = '' + +# ############################ +# Executables +# ############################ + +QEMU_BIN = 'qemu-system-x86_64' + +# ############################ +# Guest configuration +# ############################ + +# directory which is shared to QEMU guests. Useful for exchanging files +# between host and guest +GUEST_SHARE_DIR = '/tmp/qemu_share' + +# location of guest disk image +GUEST_IMAGE = '' + +# username for guest image +GUEST_USERNAME = '' + +# password for guest image +GUEST_PASSWORD = '' + +# login username prompt for guest image +GUEST_PROMPT_LOGIN = '' + +# login password prompt for guest image +GUEST_PROMPT_PASSWORD = '' + +# standard prompt for guest image +GUEST_PROMPT = '' + +# log file for qemu +LOG_FILE_QEMU = 'qemu.log' + +# log file for all commands executed on guest(s) +# multiple guests will result in log files with the guest number appended +LOG_FILE_GUEST_CMDS = 'guest-cmds.log' + diff --git a/conf/05_collector.conf b/conf/05_collector.conf new file mode 100644 index 00000000..4dcd8162 --- /dev/null +++ b/conf/05_collector.conf @@ -0,0 +1,31 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +# ############################ +# Collector configuration +# ############################ + +# ############################ +# Sysmetrics configuration +# ############################ + +COLLECTOR = 'LinuxMetrics' +COLLECTOR_DIR = os.path.join(ROOT_DIR, 'tools/collectors') + +# the number of seconds between samples when calculating CPU percentage +SYSMETRICS_LINUX_METRICS_CPU_SAMPLES_INTERVAL = 5 + +# log file for sysmetrics +LOG_FILE_SYS_METRICS = 'system-metrics.log' + diff --git a/conf/10_custom.conf b/conf/10_custom.conf new file mode 100644 index 00000000..95118753 --- /dev/null +++ b/conf/10_custom.conf @@ -0,0 +1,44 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +# traffic generator to use in tests +RTE_SDK = '' # full path to DPDK src dir +OVS_DIR = '' # full path to Open vSwitch src dir +RTE_TARGET = '' # the relevant DPDK build target + +# traffic generator to use in tests +TRAFFICGEN = 'Dummy' +#TRAFFICGEN = 'IxNet' +#TRAFFICGEN = 'Ixia' + +# Ixia/IxNet configuration +TRAFFICGEN_IXIA_CARD = '' +TRAFFICGEN_IXIA_PORT1 = '' +TRAFFICGEN_IXIA_PORT2 = '' +TRAFFICGEN_IXIA_LIB_PATH = '/opt/ixos/lib/ixTcl1.0' +TRAFFICGEN_IXNET_LIB_PATH = '/opt/ixnet/IxTclNetwork' + +# Ixia traffic generator +TRAFFICGEN_IXIA_HOST = '' # quad dotted ip address + +# host where IxNetwork GUI/daemon runs +TRAFFICGEN_IXNET_MACHINE = '' # quad dotted ip address +TRAFFICGEN_IXNET_PORT = '' +TRAFFICGEN_IXNET_USER = '' + +# paths to shared directory for IXIA_HOST and DUT (localhost) +TRAFFICGEN_IXNET_TESTER_RESULT_DIR = '' +TRAFFICGEN_IXNET_DUT_RESULT_DIR = '' + +TEST_PARAMS = {'packet_sizes':'64'} diff --git a/conf/__init__.py b/conf/__init__.py new file mode 100644 index 00000000..0af47adb --- /dev/null +++ b/conf/__init__.py @@ -0,0 +1,141 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Settings and configuration handlers. + +Settings will be loaded from several .conf files +and any user provided settings file. +""" + +# pylint: disable=invalid-name + +import os +import re +import pprint + +class Settings(object): + """Holding class for settings. + """ + def __init__(self): + pass + + def getValue(self, attr): + """Return a settings item value + """ + if attr in self.__dict__: + return getattr(self, attr) + else: + raise AttributeError("%r object has no attribute %r" % + (self.__class__, attr)) + + def __setattr__(self, name, value): + """Set a value + """ + # skip non-settings. this should exclude built-ins amongst others + if not name.isupper(): + return + + # we can assume all uppercase keys are valid settings + super(Settings, self).__setattr__(name, value) + + def load_from_file(self, path): + """Update ``settings`` with values found in module at ``path``. + """ + import imp + + custom_settings = imp.load_source('custom_settings', path) + + for key in dir(custom_settings): + if getattr(custom_settings, key) is not None: + setattr(self, key, getattr(custom_settings, key)) + + def load_from_dir(self, dir_path): + """Update ``settings`` with contents of the .conf files at ``path``. + + Each file must be named Nfilename.conf, where N is a single or + multi-digit decimal number. The files are loaded in ascending order of + N - so if a configuration item exists in more that one file the setting + in the file with the largest value of N takes precedence. + + :param dir_path: The full path to the dir from which to load the .conf + files. + + :returns: None + """ + regex = re.compile("^(?P<digit_part>[0-9]+).*.conf$") + + def get_prefix(filename): + """ + Provide a suitable function for sort's key arg + """ + match_object = regex.search(os.path.basename(filename)) + return int(match_object.group('digit_part')) + + # get full file path to all files & dirs in dir_path + file_paths = os.listdir(dir_path) + file_paths = [os.path.join(dir_path, x) for x in file_paths] + + # filter to get only those that are a files, with a leading + # digit and end in '.conf' + file_paths = [x for x in file_paths if os.path.isfile(x) and + regex.search(os.path.basename(x))] + + # sort ascending on the leading digits + file_paths.sort(key=get_prefix) + + # load settings from each file in turn + for filepath in file_paths: + self.load_from_file(filepath) + + def load_from_dict(self, conf): + """ + Update ``settings`` with values found in ``conf``. + + Unlike the other loaders, this is case insensitive. + """ + for key in conf: + if conf[key] is not None: + setattr(self, key.upper(), conf[key]) + + def load_from_env(self): + """ + Update ``settings`` with values found in the environment. + """ + for key in os.environ: + setattr(self, key, os.environ[key]) + + def __str__(self): + """Provide settings as a human-readable string. + + This can be useful for debug. + + Returns: + A human-readable string. + """ + return pprint.pformat(self.__dict__) + + +settings = Settings() + + +def get_test_param(key, default=None): + """Retrieve value for test param ``key`` if available. + + :param key: Key to retrieve from test params. + :param default: Default to return if key not found. + + :returns: Value for ``key`` if found, else ``default``. + """ + test_params = settings.getValue('TEST_PARAMS') + return test_params.get(key, default) if test_params else default diff --git a/core/__init__.py b/core/__init__.py new file mode 100644 index 00000000..0b41aaca --- /dev/null +++ b/core/__init__.py @@ -0,0 +1,20 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Core structural interfaces and their implementations +""" +import core.component_factory +from core.traffic_controller import (ITrafficController) +from core.vnf_controller import (IVnfController) +from core.vswitch_controller import (IVswitchController) diff --git a/core/collector_controller.py b/core/collector_controller.py new file mode 100644 index 00000000..10c9bce7 --- /dev/null +++ b/core/collector_controller.py @@ -0,0 +1,55 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""CollectorController class +""" +from core.results.results import IResults + +class CollectorController(IResults): + """Class which defines a collector controller object. + + Used to set-up and control a collector provider. + """ + + def __init__(self, collector_class): + """Sets up the prerequisites for the Collector. + + :param collector_class: the Collector class to be used. + """ + self._collector = collector_class() + self._results = [] + + def log_mem_stats(self): + """Log memory stats. + """ + self._results.append(self._collector.log_mem_stats()) + + def log_cpu_stats(self): + """Log CPU stats. + """ + self._results.append(self._collector.log_cpu_stats()) + + def get_results(self): + """Return collected CPU and memory stats. + + Implements IResults i/f, see IResults for details. + """ + return self._results + + def print_results(self): + """Prints collected CPU and memory stats. + + Implements IResults i/f, see IResults for details. + """ + print(self._results) diff --git a/core/component_factory.py b/core/component_factory.py new file mode 100644 index 00000000..eb963d6f --- /dev/null +++ b/core/component_factory.py @@ -0,0 +1,101 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Functions for creating controller objects based on deployment or traffic +""" + +from core.traffic_controller_rfc2544 import TrafficControllerRFC2544 +from core.vswitch_controller_p2p import VswitchControllerP2P +from core.vswitch_controller_pvp import VswitchControllerPVP +from core.vnf_controller_p2p import VnfControllerP2P +from core.vnf_controller_pvp import VnfControllerPVP +from core.collector_controller import CollectorController + + +def __init__(): + """Finds and loads all the modules required. + + Very similar code to load_trafficgens(). + """ + pass + +def create_traffic(traffic_type, trafficgen_class): + """Return a new IVSwitchController for the traffic type. + + The returned traffic controller has the given traffic type and traffic + generator class. + + traffic_types: 'rfc2544_throughput' + + :param traffic_type: Name of traffic type + :param trafficgen_class: Reference to traffic generator class to be used. + :return: A new ITrafficController + """ + #TODO - full mapping from all traffic_types to + #correct controller class + return TrafficControllerRFC2544(trafficgen_class) + +def create_vswitch(deployment_scenario, vswitch_class): + """Return a new IVSwitchController for the deployment_scenario. + + The returned controller is configured with the given vSwitch class. + + Deployment scenarios: 'p2p', 'pvp' + + :param deployment_scenario: The deployment scenario name + :param vswitch_class: Reference to vSwitch class to be used. + :return: IVSwitchController for the deployment_scenario + """ + #TODO - full mapping from all deployment_scenarios to + #correct controller class + deployment_scenario = deployment_scenario.lower() + if deployment_scenario.find("p2p") >= 0: + return VswitchControllerP2P(vswitch_class) + elif deployment_scenario.find("pvp") >= 0: + return VswitchControllerPVP(vswitch_class) + +def create_vnf(deployment_scenario, vnf_class): + """Return a new IVnfController for the deployment_scenario. + + The returned controller is configured with the given VNF class. + + Deployment scenarios: 'p2p', 'pvp' + + :param deployment_scenario: The deployment scenario name + :param vswitch_class: Reference to vSwitch class to be used. + :return: IVnfController for the deployment_scenario + """ + #TODO - full mapping from all deployment_scenarios to + #correct controller class + deployment_scenario = deployment_scenario.lower() + if deployment_scenario.find("p2p") >= 0: + return VnfControllerP2P(vnf_class) + elif deployment_scenario.find("pvp") >= 0: + return VnfControllerPVP(vnf_class) + +def create_collector(collector, collector_class): + """Return a new CollectorController of the given class + + Supported collector type strings: + 'cpu' + 'memory': + + :param collector: Collector type string + :param collector_class: The collector class to be used. + :return: A new CollectorController. + """ + collector = collector.lower() + if "cpu" in collector or "memory" in collector: + return CollectorController(collector_class) + diff --git a/core/loader/__init__.py b/core/loader/__init__.py new file mode 100644 index 00000000..023f30a6 --- /dev/null +++ b/core/loader/__init__.py @@ -0,0 +1,20 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Loader package + +This packet is responsible for loading classes & creating instances +of requested objects. This component directly depends upon conf. +""" +from .loader import Loader diff --git a/core/loader/loader.py b/core/loader/loader.py new file mode 100755 index 00000000..57787751 --- /dev/null +++ b/core/loader/loader.py @@ -0,0 +1,153 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Loader module definition. +""" + +from conf import settings +from core.loader.loader_servant import LoaderServant +from tools.pkt_gen.trafficgen import ITrafficGenerator +from tools.collectors.collector import ICollector +from vswitches.vswitch import IVSwitch + +class Loader(object): + """Loader class - main object context holder. + """ + _trafficgen_loader = None + _metrics_loader = None + _vswitch_loader = None + + def __init__(self): + """Loader ctor - initialization method. + + All data is read from configuration each time Loader instance is + created. It is up to creator to maintain object life cycle if this + behavior is unwanted. + """ + self._trafficgen_loader = LoaderServant( + settings.getValue('TRAFFICGEN_DIR'), + settings.getValue('TRAFFICGEN'), + ITrafficGenerator) + + self._metrics_loader = LoaderServant( + settings.getValue('COLLECTOR_DIR'), + settings.getValue('COLLECTOR'), + ICollector) + + self._vswitch_loader = LoaderServant( + settings.getValue('VSWITCH_DIR'), + settings.getValue('VSWITCH'), + IVSwitch) + + def get_trafficgen(self): + """Returns a new instance configured traffic generator. + + :return: ITrafficGenerator implementation if available, None otherwise. + """ + return self._trafficgen_loader.get_class()() + + def get_trafficgen_class(self): + """Returns type of currently configured traffic generator. + + :return: Type of ITrafficGenerator implementation if available. + None otherwise. + """ + return self._trafficgen_loader.get_class() + + def get_trafficgens(self): + """Returns dictionary of all available traffic generators. + + :return: Dictionary of traffic generators. + - key: name of the class which implements ITrafficGenerator, + - value: Type of traffic generator which implements + ITrafficGenerator. + """ + return self._trafficgen_loader.get_classes() + + def get_trafficgens_printable(self): + """Returns all available traffic generators in printable format. + + :return: String containing printable list of traffic generators. + """ + return self._trafficgen_loader.get_classes_printable() + + def get_collector(self): + """Returns instance of currently configured collector implementation. + + :return: ICollector implementation if available, None otherwise. + """ + return self._metrics_loader.get_class()() + + def get_collector_class(self): + """Returns type of currently configured collector implementation. + + :return: Type of ICollector implementation if available. + None otherwise. + """ + return self._metrics_loader.get_class() + + def get_collectors(self): + """Returns dictionary of all available collectors. + + :return: Dictionary of collectors. + - key: name of the class which implements ICollector, + - value: Type of traffic generator which implements ICollector. + """ + return self._metrics_loader.get_classes() + + def get_collectors_printable(self): + """Returns all available collectors in printable format. + + :return: String containing printable list of collectors. + """ + return self._metrics_loader.get_classes_printable() + + def get_vswitch(self): + """Returns instance of currently configured vswitch implementation. + + :return: IVSwitch implementation if available, None otherwise. + """ + return self._vswitch_loader.get_class()() + + def get_vswitch_class(self): + """Returns type of currently configured vswitch implementation. + + :return: Type of IVSwitch implementation if available. + None otherwise. + """ + return self._vswitch_loader.get_class() + + def get_vswitches(self): + """Returns dictionary of all available vswitches. + + :return: Dictionary of vswitches. + - key: name of the class which implements IVSwitch, + - value: Type of traffic generator which implements IVSwitch. + """ + return self._vswitch_loader.get_classes() + + def get_vswitches_printable(self): + """Returns all available vswitches in printable format. + + :return: String containing printable list of vswitches. + """ + return self._vswitch_loader.get_classes_printable() + + def get_vnf_class(self): + """Returns a new instance of the configured VNF + + Currently always returns None + """ + #TODO: Load the VNF class + return None diff --git a/core/loader/loader_servant.py b/core/loader/loader_servant.py new file mode 100644 index 00000000..7966532c --- /dev/null +++ b/core/loader/loader_servant.py @@ -0,0 +1,180 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Loader servant module used by Loader. + +Module is inteded to be private to serve only Loader itself, nevertheless +some methods are exposed outside and can be used by any other clients: +- load_modules(self, path, interface) +- load_module(self, path, interface, class_name) +Those method are stateless static members. + +""" +import os +from os import sys +import imp +import fnmatch +import logging + + +class LoaderServant(object): + """Class implements basic dynamic import operations. + """ + _class_name = None + _path = None + _interface = None + + def __init__(self, path, class_name, interface): + """LoaderServant constructor + + Intializes all data needed for import operations. + + Attributes: + path: path to directory which contains implementations derived from + interface. + class_name: Class name which will be returned in get_class + method, if such definition exists in directory + represented by path, + interface: interface type. Every object which doesn't + implement this particular interface will be + filtered out. + """ + self._class_name = class_name + self._path = path + self._interface = interface + + def get_class(self): + """Returns class type based on parameters passed in __init__. + + :return: Type of the found class. + None if class hasn't been found + """ + + return self.load_module(path=self._path, + interface=self._interface, + class_name=self._class_name) + + def get_classes(self): + """Returns all classes in path derived from interface + + :return: Dictionary with following data: + - key: String representing class name, + - value: Class type. + """ + return self.load_modules(path=self._path, + interface=self._interface) + + def get_classes_printable(self): + """Returns all classes derived from _interface found in path + + :return: String - list of classes in printable format. + """ + + out = self.load_modules(path=self._path, + interface=self._interface) + results = [] + + for (name, mod) in list(out.items()): + desc = (mod.__doc__ or 'No description').strip().split('\n')[0] + results.append((name, desc)) + + output = [ + 'Classes derived from: ' + self._interface.__name__ + '\n======\n'] + + for (name, desc) in results: + output.append('* %-18s%s' % ('%s:' % name, desc)) + + output.append('') + + output.append('') + + return '\n'.join(output) + + @staticmethod + def load_module(path, interface, class_name): + """Imports everything from given path and returns class type + + This is based on following conditions: + - Class is derived from interface, + - Class type name matches class_name. + + :return: Type of the found class. + None if class hasn't been found + """ + + results = LoaderServant.load_modules( + path=path, interface=interface) + + if class_name in results: + logging.info( + "Class found: " + class_name + ".") + return results.get(class_name) + + return None + + @staticmethod + def load_modules(path, interface): + """Returns dictionary of class name/class type found in path + + This is based on following conditions: + - classes found under path are derived from interface. + - class is not interface itself. + + :return: Dictionary with following data: + - key: String representing class name, + - value: Class type. + """ + result = {} + + for _, mod in LoaderServant._load_all_modules(path): + # find all system metric loggers defined in the module + gens = dict((k, v) for (k, v) in list(mod.__dict__.items()) + if type(v) == type and + issubclass(v, interface) and k != interface.__name__) + if gens: + for (genname, gen) in list(gens.items()): + result[genname] = gen + return result + + @staticmethod + def _load_all_modules(path): + """Load all modules from ``path`` directory. + + This is based on the design used by OFTest: + https://github.com/floodlight/oftest/blob/master/oft + + :param path: Path to a folder of modules. + + :return: List of modules in a folder. + """ + mods = [] + + for root, _, filenames in os.walk(path): + # Iterate over each python file + for filename in fnmatch.filter(filenames, '[!.]*.py'): + modname = os.path.splitext(os.path.basename(filename))[0] + + try: + if modname in sys.modules: + mod = sys.modules[modname] + else: + mod = imp.load_module( + modname, *imp.find_module(modname, [root])) + except ImportError: + logging.error('Could not import file ' + filename) + raise + + mods.append((modname, mod)) + + return mods diff --git a/core/results/__init__.py b/core/results/__init__.py new file mode 100644 index 00000000..38521211 --- /dev/null +++ b/core/results/__init__.py @@ -0,0 +1,17 @@ +# Copyright 2015 Intel Corporation. +# +# 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. +"""Results package contains the core IResults interface +""" + +from core.results import results diff --git a/core/results/results.py b/core/results/results.py new file mode 100644 index 00000000..f73f6af5 --- /dev/null +++ b/core/results/results.py @@ -0,0 +1,36 @@ +# Copyright 2015 Intel Corporation. +# +# 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. +"""IResult interface definition. +""" + +class IResults(object): + """Abstract class defining an interface for gathering results + """ + def print_results(self): + """Prints gathered results to screen. + """ + raise NotImplementedError("This class does not implement the" \ + " \"print_results\" function.") + + def get_results(self): + """Returns gathered results as a list of dictionaries. + + Each list element represents one record of data. + + :return: Results dictionary + - key: Column name + - value: Column value. + """ + raise NotImplementedError("This class does not implement the" \ + " \"get_results\" function.") diff --git a/core/results/results_constants.py b/core/results/results_constants.py new file mode 100644 index 00000000..2af3f8d8 --- /dev/null +++ b/core/results/results_constants.py @@ -0,0 +1,77 @@ +# Copyright 2015 Intel Corporation. +# +# 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. +"""ResultsConstants class +""" + +class ResultsConstants(object): + """Constant fields holder used by various IResult implementations. + """ + TYPE = 'type' + ID = 'id' + PACKET_SIZE = 'packet_size' + DEPLOYMENT = 'deployment' + + UNKNOWN_VALUE = "Unknown" + + #Traffic Constants + #RFC2544 Throughput & Continuous + THROUGHPUT_TX_FPS = 'throughput_tx_fps' + THROUGHPUT_RX_FPS = 'throughput_rx_fps' + THROUGHPUT_TX_MBPS = 'throughput_tx_mbps' + THROUGHPUT_RX_MBPS = 'throughput_rx_mbps' + THROUGHPUT_TX_PERCENT = 'throughput_tx_percent' + THROUGHPUT_RX_PERCENT = 'throughput_rx_percent' + MIN_LATENCY_NS = 'min_latency_ns' + MAX_LATENCY_NS = 'max_latency_ns' + AVG_LATENCY_NS = 'avg_latency_ns' + #Burst traffic + TX_FRAMES = 'tx_frames' + RX_FRAMES = 'rx_frames' + TX_BYTES = 'tx_bytes' + RX_BYTES = 'rx_bytes' + PAYLOAD_ERR = 'payload_err' + SEQ_ERR = 'seq_err' + #Back2Back + B2B_RX_FPS = 'b2b_rx_fps' + B2B_TX_FPS = 'b2b_tx_fps' + B2B_RX_PERCENT = 'b2b_rx_percent' + B2B_TX_PERCENT = 'b2b_tx_percent' + B2B_TX_COUNT = 'b2b_tx_count' + B2B_FRAMES = 'b2b_frames' + B2B_FRAME_LOSS_FRAMES = 'b2b_frame_loss_frames' + B2B_FRAME_LOSS_PERCENT = 'b2b_frame_loss_percent' + + @staticmethod + def get_traffic_constants(): + """Method returns all Constants used to store results. + + These data can be used to generate final output. + + :return: List of Strings which contains column names used as a result + This applies to any traffic(RFC2544 throughput or continuous flow) + operation. + """ + return [ResultsConstants.TYPE, + ResultsConstants.ID, + ResultsConstants.PACKET_SIZE, + ResultsConstants.DEPLOYMENT, + ResultsConstants.THROUGHPUT_TX_FPS, + ResultsConstants.THROUGHPUT_RX_FPS, + ResultsConstants.THROUGHPUT_TX_MBPS, + ResultsConstants.THROUGHPUT_RX_MBPS, + ResultsConstants.THROUGHPUT_TX_PERCENT, + ResultsConstants.THROUGHPUT_RX_PERCENT, + ResultsConstants.MIN_LATENCY_NS, + ResultsConstants.MAX_LATENCY_NS, + ResultsConstants.AVG_LATENCY_NS] diff --git a/core/traffic_controller.py b/core/traffic_controller.py new file mode 100644 index 00000000..428e91f8 --- /dev/null +++ b/core/traffic_controller.py @@ -0,0 +1,60 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Interface to traffic controllers +""" + +class ITrafficController(object): + """Abstract class which defines a traffic controller object + + Used to setup and control a traffic generator for a particular deployment + scenario. + """ + + def send_traffic(self, traffic): + """Triggers traffic to be sent from the traffic generator. + + This is a blocking function. + + :param traffic: A dictionary describing the traffic to send. + """ + raise NotImplementedError( + "The TrafficController does not implement", + "the \"send_traffic\" function.") + + def send_traffic_async(self, traffic, function): + """Triggers traffic to be sent asynchronously. + + This is not a blocking function. + + :param traffic: A dictionary describing the traffic to send. + :param function: A dictionary describing the function to call between + send and wait in the form: + function = { + 'function' : package.module.function, + 'args' : args + } + If this function requires more than one argument, all should be + should be passed using the args list and appropriately handled. + """ + raise NotImplementedError( + "The TrafficController does not implement", + "the \"send_traffic_async\" function.") + + def stop_traffic(self): + """Kills traffic being sent from the traffic generator. + """ + raise NotImplementedError( + "The TrafficController does not implement", + "the \"stop_traffic\" function.") diff --git a/core/traffic_controller_rfc2544.py b/core/traffic_controller_rfc2544.py new file mode 100644 index 00000000..003307bf --- /dev/null +++ b/core/traffic_controller_rfc2544.py @@ -0,0 +1,135 @@ +# Copyright 2015 Intel Corporation. +# +# 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. +"""RFC2544 Traffic Controller implementation. +""" +import logging + +from core.traffic_controller import ITrafficController +from core.results.results_constants import ResultsConstants +from core.results.results import IResults +from conf import settings +from conf import get_test_param + + +class TrafficControllerRFC2544(ITrafficController, IResults): + """Traffic controller for RFC2544 traffic + + Used to setup and control a traffic generator for an RFC2544 deployment + traffic scenario. + """ + + def __init__(self, traffic_gen_class): + """Initialise the trafficgen and store. + + :param traffic_gen_class: The traffic generator class to be used. + """ + self._logger = logging.getLogger(__name__) + self._logger.debug("__init__") + self._traffic_gen_class = traffic_gen_class() + self._traffic_started = False + self._traffic_started_call_count = 0 + self._packet_sizes = settings.getValue('TRAFFICGEN_PKT_SIZES') + self._trials = get_test_param('rfc2544_trials', 1) + self._results = [] + + def __enter__(self): + """Call initialisation function. + """ + self._traffic_gen_class.connect() + + def __exit__(self, type_, value, traceback): + """Stop traffic, clean up. + """ + if self._traffic_started: + self.stop_traffic() + + @staticmethod + def _append_results(result_dict, packet_size): + """Adds common values to traffic generator results. + + :param result_dict: Dictionary containing results from trafficgen + :param packet_size: Packet size value. + + :returns: dictionary of results with addictional entries. + """ + + ret_value = result_dict + + #TODO Old TOIT controller had knowledge about scenario beeing + #executed, should new controller also fill Configuration & ID, + # or this should be passed to TestCase? + ret_value[ResultsConstants.TYPE] = 'rfc2544' + ret_value[ResultsConstants.PACKET_SIZE] = str(packet_size) + + return ret_value + + def send_traffic(self, traffic): + """See ITrafficController for description + """ + self._logger.debug('send_traffic with ' + + str(self._traffic_gen_class)) + + for packet_size in self._packet_sizes: + traffic['l2'] = {'framesize': packet_size} + result = self._traffic_gen_class.send_rfc2544_throughput( + traffic, + trials=int(self._trials), + duration=int(get_test_param('rfc2544_duration', 20))) + result = TrafficControllerRFC2544._append_results(result, + packet_size) + self._results.append(result) + + def send_traffic_async(self, traffic, function): + """See ITrafficController for description + """ + self._logger.debug('send_traffic_async with ' + + str(self._traffic_gen_class)) + + for packet_size in self._packet_sizes: + traffic['l2'] = {'framesize': packet_size} + self._traffic_gen_class.start_rfc2544_throughput( + traffic, + trials=int(self._trials), + duration=int(get_test_param('rfc2544_duration', 20))) + self._traffic_started = True + if len(function['args']) > 0: + function['function'](function['args']) + else: + function['function']() + result = self._traffic_gen_class.wait_rfc2544_throughput() + result = TrafficControllerRFC2544._append_results(result, + packet_size) + self._results.append(result) + + def stop_traffic(self): + """Kills traffic being sent from the traffic generator. + """ + self._logger.debug("stop_traffic()") + + def print_results(self): + """IResult interface implementation. + """ + counter = 0 + for item in self._results: + logging.info("Record: " + str(counter)) + counter += 1 + for(key, value) in list(item.items()): + logging.info(" Key: " + str(key) + + ", Value: " + str(value)) + + + def get_results(self): + """IResult interface implementation. + """ + return self._results diff --git a/core/vnf_controller.py b/core/vnf_controller.py new file mode 100644 index 00000000..be1c7c4a --- /dev/null +++ b/core/vnf_controller.py @@ -0,0 +1,48 @@ +# Copyright 2015 Intel Corporation. +# +# 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. +""" VNF Controller interface +""" + +class IVnfController(object): + """Abstract class which defines a VNF controller + + Used to set-up and control a VNF provider for a particular + deployment scenario. + """ + + def get_vnfs(self): + """Returns a list of vnfs controlled by this controller. + """ + raise NotImplementedError( + "The VnfController does not implement", + "the \"get_vnfs\" function.") + + #TODO: Decide on contextmanager or __enter/exit__ strategy <MH 2015-05-01> + def start(self): + """Boots all VNFs set-up by __init__. + + This is a blocking function. + """ + raise NotImplementedError( + "The VnfController does not implement", + "the \"start\" function.") + + def stop(self): + """Stops all VNFs set-up by __init__. + + This is a blocking function. + """ + raise NotImplementedError( + "The VnfController does not implement", + "the \"stop\" function.") diff --git a/core/vnf_controller_p2p.py b/core/vnf_controller_p2p.py new file mode 100644 index 00000000..60161480 --- /dev/null +++ b/core/vnf_controller_p2p.py @@ -0,0 +1,58 @@ +# Copyright 2015 Intel Corporation. +# +# 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. +"""VNF Controller for the P2P scenario +""" + +import logging + +from core.vnf_controller import IVnfController + +class VnfControllerP2P(IVnfController): + """VNF controller for the P2P scenario. + + Does nothing as there is no VNF in P2P + + Attributes: + _vnf_class: A class object representing the VNF to be used. + _deployment_scenario: A string describing the scenario to set-up in the + constructor. + _vnfs: A list of vnfs controlled by the controller. + """ + + #TODO: Decide on contextmanager or __enter/exit__ strategy <MH 2015-05-01> + def __init__(self, vnf_class): + """Sets up the VNF infrastructure for the P2P deployment scenario. + + :param vnf_class: The VNF class to be used, this is mostly ignored. + """ + self._logger = logging.getLogger(__name__) + self._vnf_class = vnf_class + self._deployment_scenario = "P2P" + self._logger.debug('__init__ with ' + str(self._vnf_class)) + + def get_vnfs(self): + """Returns an empty list of vnfs. + """ + self._logger.debug('get_vnfs with ' + str(self._vnf_class)) + return [] + + def start(self): + """Starts nothing. + """ + self._logger.debug('start with ' + str(self._vnf_class)) + + def stop(self): + """Stops nothing. + """ + self._logger.debug('stop with ' + str(self._vnf_class)) diff --git a/core/vnf_controller_pvp.py b/core/vnf_controller_pvp.py new file mode 100644 index 00000000..16c21869 --- /dev/null +++ b/core/vnf_controller_pvp.py @@ -0,0 +1,60 @@ +# Copyright 2015 Intel Corporation. +# +# 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. +"""VNF Controller for the PVP scenario +""" + +import logging + +from core.vnf_controller import IVnfController + +class VnfControllerPVP(IVnfController): + """VNF controller for the PVP scenario. + + Used to set-up and control a VNF provider for the PVP scenario. + + Attributes: + _vnf_class: A class object representing the VNF to be used. + _deployment_scenario: A string describing the scenario to set-up in the + constructor. + _vnfs: A list of vnfs controlled by the controller. + """ + + #TODO: Decide on contextmanager or __enter/exit__ strategy <MH 2015-05-01> + def __init__(self, vnf_class): + """Sets up the VNF infrastructure for the PVP deployment scenario. + + :param vnf_class: The VNF class to be used. + """ + self._logger = logging.getLogger(__name__) + self._vnf_class = vnf_class + self._deployment_scenario = "PVP" + self._vnfs = [] + self._logger.debug('__init__ with ' + str(self._vnf_class)) + #TODO call vnf.xxx to carry out the required setup + + def get_vnfs(self): + """See IVnfController for description + """ + self._logger.debug('get_vnfs with ' + str(self._vnf_class)) + return self._vnfs + + def start(self): + """See IVnfController for description + """ + self._logger.debug('start with ' + str(self._vnf_class)) + + def stop(self): + """See IVnfController for description + """ + self._logger.debug('stop with ' + str(self._vnf_class)) diff --git a/core/vswitch_controller.py b/core/vswitch_controller.py new file mode 100644 index 00000000..1caf94fb --- /dev/null +++ b/core/vswitch_controller.py @@ -0,0 +1,50 @@ +# Copyright 2015 Intel Corporation. +# +# 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. +"""Interface for deployment specific vSwitch controllers +""" + +class IVswitchController(object): + """Abstract class which defines a vSwitch controller object + + This interface is used to setup and control a vSwitch provider for a + particular deployment scenario. + """ + def setup(self): + """Sets up the switch for the particular deployment scenario + """ + raise NotImplementedError( + "The VswitchController does not implement the \"setup\" function.") + def stop(self): + """Tears down the switch created in setup() + """ + raise NotImplementedError( + "The VswitchController does not implement the \"stop\" function.") + + def get_vswitch(self): + """Get the controlled vSwitch + + :return: The controlled IVswitch + """ + raise NotImplementedError( + "The VswitchController does not implement the \"get_vswitch\" " + "function.") + + def get_ports_info(self): + """Returns a dictionary describing all ports on the vSwitch. + + See IVswitch for dictionary structure details + """ + raise NotImplementedError( + "The VswitchController does not implement the \"get_ports_info\" " + "function.") diff --git a/core/vswitch_controller_p2p.py b/core/vswitch_controller_p2p.py new file mode 100644 index 00000000..ceb29aa9 --- /dev/null +++ b/core/vswitch_controller_p2p.py @@ -0,0 +1,90 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""VSwitch controller for Physical to Physical deployment +""" + +import logging + +from core.vswitch_controller import IVswitchController +from vswitches.utils import add_ports_to_flow + +_FLOW_TEMPLATE = { + 'idle_timeout': '0' +} +BRIDGE_NAME = 'br0' + +class VswitchControllerP2P(IVswitchController): + """VSwitch controller for P2P deployment scenario. + + Attributes: + _vswitch_class: The vSwitch class to be used. + _vswitch: The vSwitch object controlled by this controller + _deployment_scenario: A string describing the scenario to set-up in the + constructor. + """ + def __init__(self, vswitch_class): + """Initializes up the prerequisites for the P2P deployment scenario. + + :vswitch_class: the vSwitch class to be used. + """ + self._logger = logging.getLogger(__name__) + self._vswitch_class = vswitch_class + self._vswitch = vswitch_class() + self._deployment_scenario = "P2P" + self._logger.debug('Creation using ' + str(self._vswitch_class)) + + def setup(self): + """Sets up the switch for p2p. + """ + self._logger.debug('Setup using ' + str(self._vswitch_class)) + + try: + self._vswitch.start() + + self._vswitch.add_switch(BRIDGE_NAME) + + (_, phy1_number) = self._vswitch.add_phy_port(BRIDGE_NAME) + (_, phy2_number) = self._vswitch.add_phy_port(BRIDGE_NAME) + + self._vswitch.del_flow(BRIDGE_NAME) + flow = add_ports_to_flow(_FLOW_TEMPLATE, phy1_number, phy2_number) + self._vswitch.add_flow(BRIDGE_NAME, flow) + + except: + self._vswitch.stop() + raise + + def stop(self): + """Tears down the switch created in setup(). + """ + self._logger.debug('Stop using ' + str(self._vswitch_class)) + self._vswitch.stop() + + def __enter__(self): + self.setup() + + def __exit__(self, type_, value, traceback): + self.stop() + + def get_vswitch(self): + """See IVswitchController for description + """ + return self._vswitch + + def get_ports_info(self): + """See IVswitchController for description + """ + self._logger.debug('get_ports_info using ' + str(self._vswitch_class)) + return self._vswitch.get_ports(BRIDGE_NAME) diff --git a/core/vswitch_controller_pvp.py b/core/vswitch_controller_pvp.py new file mode 100644 index 00000000..c0286323 --- /dev/null +++ b/core/vswitch_controller_pvp.py @@ -0,0 +1,69 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""VSwitch controller for Physical to VM to Physical deployment +""" + +import logging + +from core.vswitch_controller import IVswitchController + +class VswitchControllerPVP(IVswitchController): + """VSwitch controller for PVP deployment scenario. + + Attributes: + _vswitch_class: The vSwitch class to be used. + _vswitch: The vSwitch object controlled by this controller + _deployment_scenario: A string describing the scenario to set-up in the + constructor. + """ + def __init__(self, vswitch_class): + """Initializes up the prerequisites for the PVP deployment scenario. + + :vswitch_class: the vSwitch class to be used. + """ + self._logger = logging.getLogger(__name__) + self._vswitch_class = vswitch_class + self._vswitch = vswitch_class() + self._deployment_scenario = "PVP" + self._logger.debug('Creation using ' + str(self._vswitch_class)) + + def setup(self): + """ + Sets up the switch for the particular deployment scenario passed in to + the constructor. + """ + # TODO call IVSwitch methods to configure VSwitch for PVP scenario. + self._logger.debug('Setup using ' + str(self._vswitch_class)) + + def stop(self): + """ + Tears down the switch created in setup(). + """ + # TODO call IVSwitch methods to stop VSwitch for PVP scenario. + self._logger.debug('Stop using ' + str(self._vswitch_class)) + + def get_vswitch(self): + """See IVswitchController for description + """ + return self._vswitch + + def get_ports_info(self): + """See IVswitchController for description + """ + self._logger.debug('get_ports_info using ' + str(self._vswitch_class)) + return [] + + + diff --git a/docs/NEWS.md b/docs/NEWS.md new file mode 100644 index 00000000..3ca47d6a --- /dev/null +++ b/docs/NEWS.md @@ -0,0 +1,27 @@ +#May 2015 + +This is the initial release of a re-designed version of the software based on +community feedback. This initial release supports only the Phy2Phy deployment +scenario and the LTD.Throughput.RFC2544.PacketLossRatio test - both described +in the OPNFV vswitchperf 'CHARACTERIZE VSWITCH PERFORMANCE FOR TELCO NFV USE +CASES LEVEL TEST DESIGN'. The intention is that more test cases will follow +once the community has digested the initial release. + +## New + +* CentOS7 support + * Verified on CentOS7 + * Install & Quickstart documentation + +* Better support for mixing tests types with Deployment Scenarios +* Re-work based on community feedback of TOIT + * Framework support for other vSwitches + * Framework support for non-Ixia traffic generators + * Framework support for different VNFs +* Python3 + +## Missing + +* Report generation is currently disabled +* xmlunit output is currently disabled +* VNF support. diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 00000000..e19d0371 --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,62 @@ +# Installing toit + +The test suite requires Python 3.3 and relies on a number of other packages. These need to be installed for the test suite to function. +To install Python 3.3 in CentOS 7, an additional repository, Software Collections (see https://www.softwarecollections.org/en/scls/rhscl/python33) +should be enabled. + +Install the requirements as specified below. + +--- +## Enable Software Collections (SCL) + +```bash +yum -y install scl-utils +yum -y install https://www.softwarecollections.org/en/scls/rhscl/python33/epel-7-x86_64/download/rhscl-python33-epel-7-x86_64.noarch.rpm +``` + +## System packages + +There are a number of packages that must be installed using `yum`. These can be installed like so: + +```bash +yum -y --exclude=python33-mod_wsgi* install python33-* pciutils +``` + +--- + +## Python 3 Packages + +To avoid file permission errors and Python version issues, use virtualenv to create an isolated environment with Python3. +The required Python 3 packages can be found in the `requirements.txt` file in the root of the test suite. +They can be installed in your virtual environment like so: + +```bash +scl enable python33 bash +# Create virtual environment +virtualenv vsperfenv +cd vsperfenv +source bin/activate +pip install -r requirements.txt +``` + +You need to activate the virtual environment everytime you start a new shell session. +To activate, simple run: + +```bash +scl enable python33 bash +cd vsperfenv +source bin/activate +``` + +--- + +# Working Behind a Proxy + +If you're behind a proxy, you'll likely want to configure this before running any of the above. For example: + +```bash +export http_proxy=proxy.mycompany.com:123 +export https_proxy=proxy.mycompany.com:123 +``` + +--- diff --git a/docs/quickstart.md b/docs/quickstart.md new file mode 100644 index 00000000..5d71c77a --- /dev/null +++ b/docs/quickstart.md @@ -0,0 +1,79 @@ +# Getting Started with 'vsperf' + +## Installation + +Follow the [installation instructions] to install. + +--- + +## Configure the `./conf/10_custom.conf` file + +The supplied `10_custom.conf` file must be modified, as it contains +configuration items for which there are no reasonable default values. + +The configuration items that can be added is not limited to the initial +contents. Any configuration item mentioned in any .conf file in `./conf` +directory can be added and that item will be overridden by the custom +configuration value. + + +## Using a custom settings file + +Alternatively a custom settings file can be passed to `vsperf` via the +`--conf-file` argument. + +```bash +./vsperf --conf-file <path_to_settings_py> ... +``` + +Note that configuration passed in via the environment (`--load-env`) or via +another command line argument will override both the default and your custom +configuration files. This "priority hierarchy" can be described like so (1 = +max priority): + +1. Command line arguments +2. Environment variables +3. Configuration file(s) + +--- + +## Executing tests + +To list the available tests: + +```bash +./vsperf --list-tests +``` + +To run a group of tests, for example all tests with a name containing +'RFC2544': + +```bash +./vsperf --conf-file=user_settings.py --tests="RFC2544" +``` + +To run all tests: + +```bash +./vsperf --conf-file=user_settings.py +``` + +Some tests allow for configurable parameters, including test duration (in +seconds) as well as packet sizes (in bytes). + +```bash +./vsperf --conf-file user_settings.py + --tests RFC2544Tput + --test-param "rfc2544_duration=10;packet_sizes=128" +``` + +For all available options, check out the help dialog: + +```bash +./vsperf --help +``` + +--- + +[installation instructions]: installation.md + diff --git a/packages.txt b/packages.txt new file mode 100644 index 00000000..f919fb6f --- /dev/null +++ b/packages.txt @@ -0,0 +1 @@ +pciutils diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..f7738754 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +pexpect==3.3 +linux-metrics==0.1.4 +tox==1.8.1 +jinja2==2.7.3 diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 00000000..9293b4f8 --- /dev/null +++ b/src/__init__.py @@ -0,0 +1,21 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""High level package for VSPERF dependencies + +No functionality is expected for this package and its purpose is just to +keep Python package structure intact without extra requirements for +PYTHONPATH. +""" + diff --git a/src/dpdk/__init__.py b/src/dpdk/__init__.py new file mode 100644 index 00000000..4be1e215 --- /dev/null +++ b/src/dpdk/__init__.py @@ -0,0 +1,21 @@ +# Copyright 2015 Intel Corporation. +# +# 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 collection of functions for automating the DPDK setup and teardown. + +These automation tasks include mounting/unmounting hugepages, inserting +and removing drivers and binding/unbinding NICs. +""" + +from src.dpdk.dpdk import * diff --git a/src/dpdk/dpdk.py b/src/dpdk/dpdk.py new file mode 100644 index 00000000..9b3d1385 --- /dev/null +++ b/src/dpdk/dpdk.py @@ -0,0 +1,377 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Automation of system configuration for DPDK use. + +Parts of this based on ``tools/pci_unbind.py`` script from Intel(R) DPDK. +""" + +from sys import platform as _platform + +import os +import re +import subprocess +import logging +import locale + +from tools import tasks +from conf import settings + +_LOGGER = logging.getLogger(__name__) +RTE_PCI_TOOL = os.path.join( + settings.getValue('RTE_SDK'), 'tools', 'dpdk_nic_bind.py') + +# +# system management +# + + +def init(): + """Setup system for DPDK. + """ + if not _is_linux(): + _LOGGER.error('Not running on a compatible Linux version. Exiting...') + return + + _mount_hugepages() + _insert_modules() + _remove_vhost_net() + _bind_nics() + _copy_dpdk_for_guest() + + +def cleanup(): + """Setup system for DPDK. + """ + if not _is_linux(): + _LOGGER.error('Not running on a compatible Linux version. Exiting...') + return + + _unbind_nics() + _remove_modules() + _umount_hugepages() + _vhost_user_cleanup() + + +# +# vhost specific modules management +# + + +def insert_vhost_modules(): + """Inserts VHOST related kernel modules + """ + mod_path_prefix = os.path.join(settings.getValue('RTE_SDK'), + 'lib', + 'librte_vhost') + _insert_module_group('VHOST_MODULE', mod_path_prefix) + + +def remove_vhost_modules(): + """Removes all VHOST related kernel modules + """ + _remove_module_group('VHOST_MODULE') + +# +# basic compatibility test +# + + +def _is_linux(): + """Check if running on Linux. + + Many of the functions in this file rely on features commonly found + only on Linux (i.e. ``/proc`` is not present on FreeBSD). Hence, this + check is important to ensure someone doesn't run this on an incompatible + OS or distro. + """ + return _platform.startswith('linux') and os.path.isdir('/proc') + +# +# hugepage management +# + + +def _is_hugepage_available(): + """Check if hugepages are available on the system. + """ + hugepage_re = re.compile(r'^HugePages_Free:\s+(?P<num_hp>\d+)$') + + # read in meminfo + with open('/proc/meminfo') as mem_file: + mem_info = mem_file.readlines() + + # first check if module is loaded + for line in mem_info: + result = hugepage_re.match(line) + if not result: + continue + + num_huge = result.group('num_hp') + if not num_huge: + _LOGGER.info('No free hugepages.') + else: + _LOGGER.info('Found \'%s\' free hugepage(s).', num_huge) + return True + + return False + + +def _is_hugepage_mounted(): + """Check if hugepages are mounted. + """ + output = subprocess.check_output(['mount'], shell=True) + my_encoding = locale.getdefaultlocale()[1] + for line in output.decode(my_encoding).split('\n'): + if 'hugetlbfs' in line: + return True + + return False + + +def _mount_hugepages(): + """Ensure hugepages are mounted. + """ + if not _is_hugepage_available(): + return + + if _is_hugepage_mounted(): + return + + if not os.path.exists(settings.getValue('HUGEPAGE_DIR')): + os.makedirs(settings.getValue('HUGEPAGE_DIR')) + try: + tasks.run_task(['sudo', 'mount', '-t', 'hugetlbfs', 'nodev', + settings.getValue('HUGEPAGE_DIR')], + _LOGGER, 'Mounting hugepages...', True) + except subprocess.CalledProcessError: + _LOGGER.error('Unable to mount hugepages.') + + +def _umount_hugepages(): + """Ensure hugepages are unmounted. + """ + if not _is_hugepage_mounted(): + return + + try: + tasks.run_task(['sudo', 'umount', settings.getValue('HUGEPAGE_DIR')], + _LOGGER, 'Unmounting hugepages...', True) + except subprocess.CalledProcessError: + _LOGGER.error('Unable to umount hugepages.') + +# +# module management +# + + +def _is_module_inserted(module): + """Check if a module is inserted on system. + """ + with open('/proc/modules') as mod_file: + loaded_mods = mod_file.readlines() + + # first check if module is loaded + for line in loaded_mods: + if line.startswith(module): + return True + return False + + +def _insert_modules(): + """Ensure required modules are inserted on system. + """ + for module in settings.getValue('SYS_MODULES'): + if _is_module_inserted(module): + continue + + try: + tasks.run_task(['sudo', 'modprobe', module], _LOGGER, + 'Inserting module \'%s\'...' % module, True) + except subprocess.CalledProcessError: + _LOGGER.error('Unable to insert module \'%s\'.', module) + raise # fail catastrophically + + mod_path_prefix = settings.getValue('OVS_DIR') + _insert_module_group('OVS_MODULES', mod_path_prefix) + mod_path_prefix = os.path.join(settings.getValue('RTE_SDK'), + settings.getValue('RTE_TARGET')) + _insert_module_group('DPDK_MODULES', mod_path_prefix) + + +def _insert_module_group(module_group, group_path_prefix): + """Ensure all modules in a group are inserted into the system. + + :param module_group: A name of configuration item containing a list + of module names + """ + for module in settings.getValue(module_group): + # first check if module is loaded + if _is_module_inserted(module[1]): + continue + + try: + mod_path = os.path.join(group_path_prefix, module[0], + '%s.ko' % module[1]) + tasks.run_task(['sudo', 'insmod', mod_path], _LOGGER, + 'Inserting module \'%s\'...' % module[1], True) + except subprocess.CalledProcessError: + _LOGGER.error('Unable to insert module \'%s\'.', module[1]) + raise # fail catastrophically + + +def _remove_modules(): + """Ensure required modules are removed from system. + """ + _remove_module_group('OVS_MODULES') + _remove_module_group('DPDK_MODULES') + + for module in settings.getValue('SYS_MODULES'): + # first check if module is loaded + if not _is_module_inserted(module): + continue + + try: + tasks.run_task(['sudo', 'rmmod', module], _LOGGER, + 'Removing module \'%s\'...' % module, True) + except subprocess.CalledProcessError: + _LOGGER.error('Unable to remove module \'%s\'.', module) + continue + + +def _remove_module_group(module_group): + """Ensure all modules in a group are removed from the system. + + :param module_group: A name of configuration item containing a list + of module names + """ + for module in settings.getValue(module_group): + # first check if module is loaded + if not _is_module_inserted(module[1]): + continue + + try: + tasks.run_task(['sudo', 'rmmod', module[1]], _LOGGER, + 'Removing module \'%s\'...' % module[1], True) + except subprocess.CalledProcessError: + _LOGGER.error('Unable to remove module \'%s\'.', module[1]) + continue + + +# +# 'vhost-net' module management +# + +def _remove_vhost_net(): + """Remove vhost-net driver and file. + """ + if _is_module_inserted('vhost_net'): + try: + tasks.run_task(['sudo', 'rmmod', 'vhost_net'], _LOGGER, + 'Removing \'/dev/vhost-net\' directory...', True) + except subprocess.CalledProcessError: + _LOGGER.error('Unable to remove module \'vhost_net\'.') + + try: + tasks.run_task(['sudo', 'rm', '-f', '/dev/vhost-net'], _LOGGER, + 'Removing \'/dev/vhost-net\' directory...', True) + except subprocess.CalledProcessError: + _LOGGER.error('Unable to remove directory \'/dev/vhost-net\'.') + +# +# NIC management +# + + +def _bind_nics(): + """Bind NICs using the Intel DPDK ``pci_unbind.py`` tool. + """ + try: + tasks.run_task(['sudo', RTE_PCI_TOOL, '--bind', 'igb_uio'] + + settings.getValue('WHITELIST_NICS'), _LOGGER, + 'Binding NICs %s...' % + settings.getValue('WHITELIST_NICS'), + True) + except subprocess.CalledProcessError: + _LOGGER.error('Unable to bind NICs %s', + str(settings.getValue('WHITELIST_NICS'))) + + +def _unbind_nics(): + """Unbind NICs using the Intel DPDK ``pci_unbind.py`` tool. + """ + try: + tasks.run_task(['sudo', RTE_PCI_TOOL, '--unbind'] + + settings.getValue('WHITELIST_NICS'), _LOGGER, + 'Unbinding NICs %s...' % + str(settings.getValue('WHITELIST_NICS')), + True) + except subprocess.CalledProcessError: + _LOGGER.error('Unable to unbind NICs %s', + str(settings.getValue('WHITELIST_NICS'))) + + +def _copy_dpdk_for_guest(): + """Copy dpdk code to GUEST_SHARE_DIR for use by guests. + """ + guest_share_dir = os.path.join( + settings.getValue('GUEST_SHARE_DIR'), 'DPDK') + + if not os.path.exists(guest_share_dir): + os.makedirs(guest_share_dir) + + try: + tasks.run_task(['rsync', '-a', '-r', '-l', r'--exclude="\.git"', + os.path.join(settings.getValue('RTE_SDK'), ''), + guest_share_dir], + _LOGGER, + 'Copying DPDK to shared directory...', + True) + except subprocess.CalledProcessError: + _LOGGER.error('Unable to copy DPDK to shared directory') + + +# +# Vhost-user cleanup +# + +def _vhost_user_cleanup(): + """Remove files created by vhost-user tests. + """ + for sock in settings.getValue('VHOST_USER_SOCKS'): + if os.path.exists(sock): + try: + tasks.run_task(['sudo', 'rm', sock], + _LOGGER, + 'Deleting vhost-user socket \'%s\'...' % + sock, + True) + + except subprocess.CalledProcessError: + _LOGGER.error('Unable to delete vhost-user socket \'%s\'.', + sock) + continue + + +class Dpdk(object): + """A context manager for the system init/cleanup. + """ + def __enter__(self): + _LOGGER.info('Setting up DPDK') + init() + return self + + def __exit__(self, type_, value, traceback): + _LOGGER.info('Cleaning up DPDK') + cleanup() diff --git a/src/ovs/__init__.py b/src/ovs/__init__.py new file mode 100644 index 00000000..1a31ea2e --- /dev/null +++ b/src/ovs/__init__.py @@ -0,0 +1,25 @@ +# Copyright 2015 Intel Corporation. +# +# 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 package for controlling Open vSwitch + +This package is intended to stay gneneric enough to support using any data +path of OVS (linux kernel, DPDK userspace, etc.) by different parameterization +and external setup of vswitchd-external process, kernel modules etc. + +""" + +from src.ovs.daemon import * +from src.ovs.ofctl import * diff --git a/src/ovs/daemon.py b/src/ovs/daemon.py new file mode 100644 index 00000000..ee3446d5 --- /dev/null +++ b/src/ovs/daemon.py @@ -0,0 +1,142 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Class wrapper for controlling an OVS instance. + +Wraps a pair of ``ovs-vswitchd`` and ``ovsdb-server`` processes. +""" + +import os +import logging +import pexpect + +from conf import settings +from tools import tasks + +_OVS_VSWITCHD_BIN = os.path.join( + settings.getValue('OVS_DIR'), 'vswitchd', 'ovs-vswitchd') +_OVSDB_TOOL_BIN = os.path.join( + settings.getValue('OVS_DIR'), 'ovsdb', 'ovsdb-tool') +_OVSDB_SERVER_BIN = os.path.join( + settings.getValue('OVS_DIR'), 'ovsdb', 'ovsdb-server') + +_OVS_VAR_DIR = '/usr/local/var/run/openvswitch/' +_OVS_ETC_DIR = '/usr/local/etc/openvswitch/' + +_LOG_FILE_VSWITCHD = os.path.join( + settings.getValue('LOG_DIR'), settings.getValue('LOG_FILE_VSWITCHD')) + +class VSwitchd(tasks.Process): + """Class wrapper for controlling an OVS instance. + + Wraps a pair of ``ovs-vswitchd`` and ``ovsdb-server`` processes. + """ + _ovsdb_pid = None + _logfile = _LOG_FILE_VSWITCHD + + + _expect = r'EAL: Master l*core \d+ is ready' + _proc_name = 'ovs-vswitchd' + + def __init__(self, timeout=30, vswitchd_args=None): + """Initialise the wrapper with a specific start timeout and extra + parameters. + + :param timeout: Timeout to wait for application to start. + :param vswitchd_args: Command line parameters for vswitchd. + + :returns: None + """ + self._logger = logging.getLogger(__name__) + self._timeout = timeout + vswitchd_args = vswitchd_args or [] + + self._cmd = ['sudo', '-E', _OVS_VSWITCHD_BIN] + vswitchd_args + + # startup/shutdown + + def start(self): + """ Start ``ovsdb-server`` and ``ovs-vswitchd`` instance. + + :returns: None + :raises: pexpect.EOF, pexpect.TIMEOUT + """ + self._reset_ovsdb() + self._start_ovsdb() # this has to be started first + + try: + super(VSwitchd, self).start() + self.relinquish() + except (pexpect.EOF, pexpect.TIMEOUT) as exc: + self._kill_ovsdb() + raise exc + + def kill(self): + """Kill ``ovs-vswitchd`` instance if it is alive. + + :returns: None + """ + self._logger.info('Killing ovs-vswitchd...') + + self._kill_ovsdb() + + super(VSwitchd, self).kill() + + # helper functions + + def _reset_ovsdb(self): + """Reset system for 'ovsdb'. + + :returns: None + """ + self._logger.info('Resetting system after last run...') + + tasks.run_task(['sudo', 'rm', '-rf', _OVS_VAR_DIR], self._logger) + tasks.run_task(['sudo', 'mkdir', '-p', _OVS_VAR_DIR], self._logger) + tasks.run_task(['sudo', 'rm', '-rf', _OVS_ETC_DIR], self._logger) + tasks.run_task(['sudo', 'mkdir', '-p', _OVS_ETC_DIR], self._logger) + + tasks.run_task(['sudo', 'rm', '-f', + os.path.join(_OVS_ETC_DIR, 'conf.db')], + self._logger) + + self._logger.info('System reset after last run.') + + def _start_ovsdb(self): + """Start ``ovsdb-server`` instance. + + :returns: None + """ + tasks.run_task(['sudo', _OVSDB_TOOL_BIN, 'create', + os.path.join(_OVS_ETC_DIR, 'conf.db'), + os.path.join(settings.getValue('OVS_DIR'), 'vswitchd', + 'vswitch.ovsschema')], + self._logger, + 'Creating ovsdb configuration database...') + + self._ovsdb_pid = tasks.run_background_task( + ['sudo', _OVSDB_SERVER_BIN, + '--remote=punix:%s' % os.path.join(_OVS_VAR_DIR, 'db.sock'), + '--remote=db:Open_vSwitch,Open_vSwitch,manager_options'], + self._logger, + 'Starting ovsdb-server...') + + def _kill_ovsdb(self): + """Kill ``ovsdb-server`` instance. + + :returns: None + """ + if self._ovsdb_pid: + tasks.run_task(['sudo', 'kill', '-2', str(self._ovsdb_pid)], + self._logger, 'Killing ovsdb-server...') diff --git a/src/ovs/ofctl.py b/src/ovs/ofctl.py new file mode 100644 index 00000000..c6aaddc9 --- /dev/null +++ b/src/ovs/ofctl.py @@ -0,0 +1,316 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Wrapper for an OVS bridge for convenient use of ``ovs-vsctl`` and +``ovs-ofctl`` on it. + +Much of this code is based on ``ovs-lib.py`` from Open Stack: + +https://github.com/openstack/neutron/blob/6eac1dc99124ca024d6a69b3abfa3bc69c735667/neutron/agent/linux/ovs_lib.py +""" + +import os +import logging +import string + +from tools import tasks +from conf import settings + +_OVS_VSCTL_BIN = os.path.join(settings.getValue('OVS_DIR'), 'utilities', + 'ovs-vsctl') +_OVS_OFCTL_BIN = os.path.join(settings.getValue('OVS_DIR'), 'utilities', + 'ovs-ofctl') + +class OFBase(object): + """Add/remove/show datapaths using ``ovs-ofctl``. + """ + def __init__(self, timeout=10): + """Initialise logger. + + :param timeout: Timeout to be used for each command + + :returns: None + """ + self.logger = logging.getLogger(__name__) + self.timeout = timeout + + # helpers + + def run_vsctl(self, args, check_error=False): + """Run ``ovs-vsctl`` with supplied arguments. + + :param args: Arguments to pass to ``ovs-vsctl`` + :param check_error: Throw exception on error + + :return: None + """ + cmd = ['sudo', _OVS_VSCTL_BIN, '--timeout', str(self.timeout)] + args + return tasks.run_task( + cmd, self.logger, 'Running ovs-vsctl...', check_error) + + # datapath management + + def add_br(self, br_name='br0'): + """Add datapath. + + :param br_name: Name of bridge + + :return: Instance of :class OFBridge: + """ + self.logger.debug('add bridge') + self.run_vsctl(['add-br', br_name]) + + return OFBridge(br_name, self.timeout) + + def del_br(self, br_name='br0'): + """Delete datapath. + + :param br_name: Name of bridge + + :return: None + """ + self.logger.debug('delete bridge') + self.run_vsctl(['del-br', br_name]) + + +class OFBridge(OFBase): + """Control a bridge instance using ``ovs-vsctl`` and ``ovs-ofctl``. + """ + def __init__(self, br_name='br0', timeout=10): + """Initialise bridge. + + :param br_name: Bridge name + :param timeout: Timeout to be used for each command + + :returns: None + """ + super(OFBridge, self).__init__(timeout) + self.br_name = br_name + self._ports = {} + + # context manager + + def __enter__(self): + """Create datapath + + :returns: self + """ + return self + + def __exit__(self, type_, value, traceback): + """Remove datapath. + """ + if not traceback: + self.destroy() + + # helpers + + def run_ofctl(self, args, check_error=False): + """Run ``ovs-ofctl`` with supplied arguments. + + :param args: Arguments to pass to ``ovs-ofctl`` + :param check_error: Throw exception on error + + :return: None + """ + cmd = ['sudo', _OVS_OFCTL_BIN, '--timeout', str(self.timeout)] + args + return tasks.run_task( + cmd, self.logger, 'Running ovs-ofctl...', check_error) + + def create(self): + """Create bridge. + """ + self.logger.debug('create bridge') + self.add_br(self.br_name) + + def destroy(self): + """Destroy bridge. + """ + self.logger.debug('destroy bridge') + self.del_br(self.br_name) + + def reset(self): + """Reset bridge. + """ + self.logger.debug('reset bridge') + self.destroy() + self.create() + + # port management + + def add_port(self, port_name, params): + """Add port to bridge. + + :param port_name: Name of port + :param params: Additional list of parameters to add-port + + :return: OpenFlow port number for the port + """ + self.logger.debug('add port') + self.run_vsctl(['add-port', self.br_name, port_name]+params) + + # This is how port number allocation works currently + # This possibly will not work correctly if there are port deletions + # in between + of_port = len(self._ports) + 1 + self._ports[port_name] = (of_port, params) + return of_port + + def del_port(self, port_name): + """Remove port from bridge. + + :param port_name: Name of port + + :return: None + """ + self.logger.debug('delete port') + self.run_vsctl(['del-port', self.br_name, port_name]) + self._ports.pop(port_name) + + def set_db_attribute(self, table_name, record, column, value): + """Set database attribute. + + :param table_name: Name of table + :param record: Name of record + :param column: Name of column + :param value: Value to set + + :return: None + """ + self.logger.debug('set attribute') + self.run_vsctl(['set', table_name, record, '%s=%s' % (column, value)]) + + def get_ports(self): + """Get the ports of this bridge + + Structure of the returned ports dictionary is + 'portname': (openflow_port_number, extra_parameters) + + Example: + ports = { + 'dpdkport0': + (1, ['--', 'set', 'Interface', 'dpdkport0', 'type=dpdk']), + 'dpdkvhostport0': + (2, ['--', 'set', 'Interface', 'dpdkvhostport0', + 'type=dpdkvhost']) + } + + :return: Dictionary of ports + """ + return self._ports + + def clear_db_attribute(self, table_name, record, column): + """Clear database attribute. + + :param table_name: Name of table + :param record: Name of record + :param column: Name of column + + :return: None + """ + self.logger.debug('clear attribute') + self.run_vsctl(['clear', table_name, record, column]) + + # flow mangement + + def add_flow(self, flow): + """Add flow to bridge. + + :param flow: Flow description as a dictionary + For flow dictionary structure, see function flow_key + + :return: None + """ + if not flow.get('actions'): + self.logger.error('add flow requires actions') + return + + self.logger.debug('add flow') + _flow_key = flow_key(flow) + self.logger.debug('key : %s', _flow_key) + self.run_ofctl(['add-flow', self.br_name, _flow_key]) + + def del_flow(self, flow): + """Delete flow from bridge. + + :param flow: Flow description as a dictionary + For flow dictionary structure, see function flow_key + flow=None will delete all flows + + :return: None + """ + self.logger.debug('delete flow') + _flow_key = flow_key(flow) + self.logger.debug('key : %s', _flow_key) + self.run_ofctl(['del-flows', self.br_name, _flow_key]) + + def del_flows(self): + """Delete all flows from bridge. + """ + self.logger.debug('delete flows') + self.run_ofctl(['del-flows', self.br_name]) + + def dump_flows(self): + """Dump all flows from bridge. + """ + self.logger.debug('dump flows') + self.run_ofctl(['dump-flows', self.br_name]) + +# +# helper functions +# + +def flow_key(flow): + """Model a flow key string for ``ovs-ofctl``. + + Syntax taken from ``ovs-ofctl`` manpages: + http://openvswitch.org/cgi-bin/ovsman.cgi?page=utilities%2Fovs-ofctl.8 + + Example flow dictionary: + flow = { + 'in_port': '1', + 'idle_timeout': '0', + 'actions': ['output:3'] + } + + :param flow: Flow description as a dictionary + + :return: String + :rtype: str + """ + _flow_add_key = string.Template('${fields},action=${actions}') + _flow_del_key = string.Template('${fields}') + + field_params = [] + + user_params = (x for x in list(flow.items()) if x[0] != 'actions') + for (key, default) in user_params: + field_params.append('%(field)s=%(value)s' % + {'field': key, 'value': default}) + + field_params = ','.join(field_params) + + _flow_key_param = { + 'fields': field_params, + } + + # no actions == delete key + if 'actions' in flow: + _flow_key_param['actions'] = ','.join(flow['actions']) + + flow_str = _flow_add_key.substitute(_flow_key_param) + else: + flow_str = _flow_del_key.substitute(_flow_key_param) + + return flow_str diff --git a/test_spec/vswitchperf_ltd.md b/test_spec/vswitchperf_ltd.md index 35a5307b..d5a44976 100755..100644 --- a/test_spec/vswitchperf_ltd.md +++ b/test_spec/vswitchperf_ltd.md @@ -899,6 +899,40 @@ The following represents possible deployments which can help to determine the pe - The forwarding rate of the DUT when forwarding broadcast traffic. +<br/> +---- +<a name="LatencyTests"></a> +####2.3.2 Packet Latency tests + These tests will measure the store and forward latency as well as the packet delay variation for various packet types through the virtual switch. + + The following list is not exhaustive but should indicate the type of tests that should be required. It is expected that more will be added. + + - #####Test ID: LTD.PacketLatency.InitialPacketProcessingLatency + **Title**: Initial Packet Processing Latency + + **Prerequisite Test**: N\A + + **Priority**: + + **Description**: + + In some virtual switch architectures, the first packets of a flow will take the system longer to process than subsequent packets in the flow. This test determines the latency for these packets. The test will measure the latency of the packets as they are processed by the flow-setup-path of the DUT. This test will send a single packet to the DUT after a fixed interval of time. The time interval will be equivalent to the amount of time it takes for a flow to time out in the virtual switch. Average packet latency will be determined over 1,000,000 packets. + + For this test, only unidirectional traffic is required. + + **Expected Result**: + The average latency for the initial packet of all flows should be greater than the latency of subsequent traffic. + + **Metrics Collected**: + + The following are the metrics collected for this test: + + - Average latency of the initial packets of all flows that are processed by the DUT. + + **Deployment scenario**: + + - Physical → Virtual Switch → Physical. +<br/> ---- [RFC1242]:(http://www.ietf.org/rfc/rfc1242.txt) [RFC2544]:(http://www.ietf.org/rfc/rfc2544.txt) diff --git a/testcases/__init__.py b/testcases/__init__.py new file mode 100644 index 00000000..addf63df --- /dev/null +++ b/testcases/__init__.py @@ -0,0 +1,17 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""This module contains test definitions. +""" +from testcases.testcase import (TestCase) diff --git a/testcases/testcase.py b/testcases/testcase.py new file mode 100644 index 00000000..76758c8f --- /dev/null +++ b/testcases/testcase.py @@ -0,0 +1,128 @@ +# Copyright 2015 Intel Corporation. +# +# 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. +"""TestCase base class +""" + +import time +import csv +import os +import logging +from collections import OrderedDict + +import core.component_factory as component_factory +from core.loader import Loader + +class TestCase(object): + """TestCase base class + + In this basic form runs RFC2544 throughput test + """ + def __init__(self, cfg, results_dir): + """Pull out fields from test config + + No external actions yet. + """ + self._logger = logging.getLogger(__name__) + self.name = cfg['Name'] + self.desc = cfg.get('Description', 'No description given.') + self._traffic_type = cfg['Traffic Type'] + self._deployment = cfg['Deployment'] + self._collector = cfg['Collector'] + self._results_dir = results_dir + + def run(self): + """Run the test + + All setup and teardown through controllers is included. + """ + self._logger.debug(self.name) + + self._logger.debug("Controllers:") + loader = Loader() + traffic_ctl = component_factory.create_traffic( + self._traffic_type, + loader.get_trafficgen_class()) + vnf_ctl = component_factory.create_vnf( + self._deployment, + loader.get_vnf_class()) + vswitch_ctl = component_factory.create_vswitch( + self._deployment, + loader.get_vswitch_class()) + collector_ctl = component_factory.create_collector( + self._collector, + loader.get_collector_class()) + + self._logger.debug("Setup:") + collector_ctl.log_cpu_stats() + with vswitch_ctl: + if vnf_ctl: + vnf_ctl.start() + #TODO 'traffic' is placeholder for traffic dict + traffic = {'test': 'rfc2544'} + with traffic_ctl: + traffic_ctl.send_traffic(traffic) + + + self._logger.debug("Traffic Results:") + traffic_ctl.print_results() + + self._logger.debug("Collector Results:") + self._logger.debug(collector_ctl.get_results()) + + + output_file = "result_" + self.name + "_" + self._deployment +".csv" + + self._write_result_to_file( + traffic_ctl.get_results(), + os.path.join(self._results_dir, output_file)) + + @staticmethod + def _write_result_to_file(results, output): + """Write list of dictionaries to a CSV file. + + Each element on list will create separate row in output file. + If output file already exists, data will be appended at the end, + otherwise it will be created. + + :param results: list of dictionaries. + :param output: path to output file. + """ + with open(output, 'a') as csvfile: + + logging.info("Write results to file: " + output) + fieldnames = TestCase._get_unique_keys(results) + + writer = csv.DictWriter(csvfile, fieldnames) + + if not csvfile.tell(): # file is now empty + writer.writeheader() + + for result in results: + writer.writerow(result) + + + @staticmethod + def _get_unique_keys(list_of_dicts): + """Gets unique key values as ordered list of strings in given dicts + + :param list_of_dicts: list of dictionaries. + + :returns: list of unique keys(strings). + """ + result = OrderedDict() + for item in list_of_dicts: + for key in item.keys(): + result[key] = '' + + return list(result.keys()) diff --git a/tools/__init__.py b/tools/__init__.py new file mode 100644 index 00000000..16e9790e --- /dev/null +++ b/tools/__init__.py @@ -0,0 +1,16 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Tools package. +""" diff --git a/tools/collectors/__init__.py b/tools/collectors/__init__.py new file mode 100644 index 00000000..f2f3adf3 --- /dev/null +++ b/tools/collectors/__init__.py @@ -0,0 +1,18 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Collectors package. + +Contains collector interface and its various implementations. +""" diff --git a/tools/collectors/collector/__init__.py b/tools/collectors/collector/__init__.py new file mode 100644 index 00000000..85de5749 --- /dev/null +++ b/tools/collectors/collector/__init__.py @@ -0,0 +1,18 @@ +# Copyright 2015 Intel Corporation. +# +# 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 collection of functions for automating a system metrics logger. +""" + +from tools.collectors.collector.collector import * diff --git a/tools/collectors/collector/collector.py b/tools/collectors/collector/collector.py new file mode 100644 index 00000000..27a07202 --- /dev/null +++ b/tools/collectors/collector/collector.py @@ -0,0 +1,38 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Abstract "system metrics logger" model. +""" + +CMD_PREFIX = 'metricscmd : ' + +class ICollector(object): + """This is an abstract class for system metrics loggers. + """ + + def log_mem_stats(self): + """Log memory statistics. + + Where implemented, this function should raise an exception on + failure. + """ + raise NotImplementedError('Please call an implementation.') + + def log_cpu_stats(self): + """Log cpu statistics. + + Where implemented, this function should raise an exception on + failure. + """ + raise NotImplementedError('Please call an implementation.') diff --git a/tools/collectors/sysmetrics/__init__.py b/tools/collectors/sysmetrics/__init__.py new file mode 100755 index 00000000..9ad1bf29 --- /dev/null +++ b/tools/collectors/sysmetrics/__init__.py @@ -0,0 +1,18 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Implementation of linux-metrics system metrics logger. +""" + +from tools.collectors.sysmetrics.linuxmetrics import * diff --git a/tools/collectors/sysmetrics/linuxmetrics.py b/tools/collectors/sysmetrics/linuxmetrics.py new file mode 100644 index 00000000..fdf30696 --- /dev/null +++ b/tools/collectors/sysmetrics/linuxmetrics.py @@ -0,0 +1,79 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""linux-metrics system statistics model. + +Provides linux-metrics system statistics generic "helper" functions. + +This requires the following setting in your config: + +* SYSMETRICS_LINUX_METRICS_CPU_SAMPLES_INTERVAL + Number of seconds in between samples to take for CPU percentages + +If this doesn't exist, the application will raise an exception +(EAFP). +""" + + +import logging +import os +from conf import settings +from tools.collectors.collector import collector +from linux_metrics import cpu_stat, mem_stat + +_ROOT_DIR = os.path.dirname(os.path.realpath(__file__)) + +class LinuxMetrics(collector.ICollector): + """A logger based on the linux-metrics module. + + Currently it supports the logging of memory and CPU statistics + """ + def __init__(self): + self._logger = logging.getLogger(__name__) + self._num_samples = settings.getValue( + 'SYSMETRICS_LINUX_METRICS_CPU_SAMPLES_INTERVAL') + self._mem_stats = [] + self._cpu_stats = [] + + def log_mem_stats(self): + """See ICollector for descripion + """ + self._mem_stats = mem_stat.mem_stats() + # pylint: disable=unbalanced-tuple-unpacking + mem_active, mem_total, mem_cached, mem_free, swap_total, swap_free = \ + self._mem_stats + self._logger.info('%s mem_active: %s, mem_total: %s, mem_cached: %s, ' + 'mem_free: %s, swap_total: %s, swap_free: %s', + collector.CMD_PREFIX, + mem_active, mem_total, mem_cached, mem_free, + swap_total, swap_free) + return self._mem_stats + + def log_cpu_stats(self): + """See ICollector for descripion + """ + self._cpu_stats = cpu_stat.cpu_percents(self._num_samples) + self._logger.info('%s user: %.2f%%, nice: %.2f%%, system: %.2f%%, ' + 'idle: %.2f%%, iowait: %.2f%%, irq: %.2f%%, ' + 'softirq: %.2f%%', + collector.CMD_PREFIX, + self._cpu_stats['user'], + self._cpu_stats['nice'], + self._cpu_stats['system'], + self._cpu_stats['idle'], + self._cpu_stats['iowait'], + self._cpu_stats['irq'], + self._cpu_stats['softirq']) + return self._cpu_stats + diff --git a/tools/pkt_gen/__init__.py b/tools/pkt_gen/__init__.py new file mode 100644 index 00000000..3068817d --- /dev/null +++ b/tools/pkt_gen/__init__.py @@ -0,0 +1,19 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +""" +Packet generators package which contain: +- All relevant implementations of packet generators. +- Interface definition stored in "trafficgen" +""" diff --git a/tools/pkt_gen/dummy/__init__.py b/tools/pkt_gen/dummy/__init__.py new file mode 100644 index 00000000..b6771d83 --- /dev/null +++ b/tools/pkt_gen/dummy/__init__.py @@ -0,0 +1,19 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +""" +Implementation of dummy traffic generator. +""" + +from .dummy import * diff --git a/tools/pkt_gen/dummy/dummy.py b/tools/pkt_gen/dummy/dummy.py new file mode 100755 index 00000000..f9ad1c8c --- /dev/null +++ b/tools/pkt_gen/dummy/dummy.py @@ -0,0 +1,224 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +""" +Dummy traffic generator, designed for user intput. + +Provides a model for the Dummy traffic generator - a psuedo "traffic +generator" that doesn't actually generate any traffic. Instead the +user is required to send traffic using their own choice of traffic +generator *outside of the framework*. The Dummy traffic generator +then returns the results - manually entered by the user - as its +own. +""" + +import json + +from tools.pkt_gen import trafficgen +from core.results.results_constants import ResultsConstants + +def _get_user_traffic_stat(stat_type): + """ + Request user input for traffic. + + :param stat_type: Name of statistic required from user + + :returns: Value of stat provided by user + """ + true_vals = ('yes', 'y', 'ye', None) + false_vals = ('no', 'n') + + while True: + result = input('What was the result for \'%s\'? ' % stat_type) + + try: + result = int(result) + except ValueError: + print('That was not a valid integer result. Try again.') + continue + + while True: + choice = input('Is \'%d\' correct? ' % result).lower() + if not choice or choice in true_vals: + return result + elif choice and choice in false_vals: + break + else: + print('Please respond with \'yes\' or \'no\' ', end='') + + +def get_user_traffic(traffic_type, traffic_conf, flow_conf, traffic_stats): + """ + Request user input for traffic. + + :param traffic_type: Name of traffic type. + :param traffic_conf: Configuration of traffic to be sent. + :param traffic_conf: Configuration of flow to be sent. + :param traffic_stats: Required output statistics (i.e. what's needed) + + :returns: List of stats corresponding to those in traffic_stats + """ + results = [] + + print('Please send \'%s\' traffic with the following stream config:\n%s\n' + 'and the following flow config:\n%s' + % (traffic_type, traffic_conf, json.dumps(flow_conf, indent=4))) + + for stat in traffic_stats: + results.append(_get_user_traffic_stat(stat)) + + return results + + +class Dummy(trafficgen.ITrafficGenerator): + """ + A dummy traffic generator whose data is generated by the user. + + This traffic generator is useful when a user does not wish to write + a wrapper for a given type of traffic generator. By using this + "traffic generator", the user is asked to send traffic when + required and enter the results manually. The user controls the + real traffic generator and is responsible for ensuring the flows + are setup correctly. + """ + def connect(self): + """ + Do nothing. + """ + return self + + def disconnect(self): + """ + Do nothing. + """ + pass + + def send_burst_traffic(self, traffic=None, numpkts=100, time=20, framerate=100): + """ + Send a burst of traffic. + """ + traffic_ = self.traffic_defaults.copy() + result = {} + + if traffic: + traffic_ = trafficgen.merge_spec(traffic_, traffic) + + results = get_user_traffic( + 'burst', + '%dpkts, %dmS' % (numpkts, time), + traffic_, + ('frames rx', 'payload errors', 'sequence errors')) + + # builds results by using user-supplied values where possible + # and guessing remainder using available info + result[ResultsConstants.TX_FRAMES] = numpkts + result[ResultsConstants.RX_FRAMES] = results[0] + result[ResultsConstants.TX_BYTES] = traffic_['l2']['framesize'] \ + * numpkts + result[ResultsConstants.RX_BYTES] = traffic_['l2']['framesize'] \ + * results[0] + result[ResultsConstants.PAYLOAD_ERR] = results[1] + result[ResultsConstants.SEQ_ERR] = results[2] + + return trafficgen.BurstResult(*results) + + def send_cont_traffic(self, traffic=None, time=20, framerate=0, + multistream=False): + """ + Send a continuous flow of traffic. + """ + traffic_ = self.traffic_defaults.copy() + result = {} + + if traffic: + traffic_ = trafficgen.merge_spec(traffic_, traffic) + + results = get_user_traffic( + 'continuous', + '%dmS, %dmpps, multistream %s' % (time, framerate, + multistream), traffic_, + ('frames tx', 'frames rx', 'min latency', 'max latency', + 'avg latency')) + + framesize = traffic_['l2']['framesize'] + + # builds results by using user-supplied values where possible + # and guessing remainder using available info + result[ResultsConstants.THROUGHPUT_TX_FPS] = float(results[0]) / time + result[ResultsConstants.THROUGHPUT_RX_FPS] = float(results[1]) / time + result[ResultsConstants.THROUGHPUT_TX_MBPS] = (float(results[0]) \ + * framesize) / time + result[ResultsConstants.THROUGHPUT_RX_MBPS] = (float(results[1]) \ + * framesize) / time + result[ResultsConstants.THROUGHPUT_TX_PERCENT] = 0.0 + result[ResultsConstants.THROUGHPUT_RX_PERCENT] = 0.0 + result[ResultsConstants.MIN_LATENCY_NS] = float(results[2]) + result[ResultsConstants.MAX_LATENCY_NS] = float(results[3]) + result[ResultsConstants.AVG_LATENCY_NS] = float(results[4]) + + return result + + def send_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + lossrate=0.0, multistream=False): + """ + Send traffic per RFC2544 throughput test specifications. + """ + traffic_ = self.traffic_defaults.copy() + result = {} + + if traffic: + traffic_ = trafficgen.merge_spec(traffic_, traffic) + + results = get_user_traffic( + 'throughput', + '%d trials, %d seconds iterations, %f packet loss, multistream ' + '%s' % (trials, duration, lossrate, + 'enabled' if multistream else 'disabled'), + traffic_, + ('frames tx', 'frames rx', 'min latency', 'max latency', + 'avg latency')) + + framesize = traffic_['l2']['framesize'] + + # builds results by using user-supplied values where possible + # and guessing remainder using available info + result[ResultsConstants.THROUGHPUT_TX_FPS] = float(results[0]) \ + / duration + result[ResultsConstants.THROUGHPUT_RX_FPS] = float(results[1]) \ + / duration + result[ResultsConstants.THROUGHPUT_TX_MBPS] = (float(results[0]) \ + * framesize) / duration + result[ResultsConstants.THROUGHPUT_RX_MBPS] = (float(results[1]) \ + * framesize) / duration + result[ResultsConstants.THROUGHPUT_TX_PERCENT] = 0.0 + result[ResultsConstants.THROUGHPUT_RX_PERCENT] = 0.0 + result[ResultsConstants.MIN_LATENCY_NS] = float(results[2]) + result[ResultsConstants.MAX_LATENCY_NS] = float(results[3]) + result[ResultsConstants.AVG_LATENCY_NS] = float(results[4]) + + return result + +if __name__ == '__main__': + TRAFFIC = { + 'l3': { + 'proto': 'tcp', + 'srcip': '1.1.1.1', + 'dstip': '90.90.90.90', + }, + } + + with Dummy() as dev: + print(dev.send_burst_traffic(traffic=TRAFFIC)) + print(dev.send_cont_traffic(traffic=TRAFFIC)) + print(dev.send_rfc(traffic=TRAFFIC)) diff --git a/tools/pkt_gen/ixia/__init__.py b/tools/pkt_gen/ixia/__init__.py new file mode 100644 index 00000000..2f3d814a --- /dev/null +++ b/tools/pkt_gen/ixia/__init__.py @@ -0,0 +1,18 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Implementation of IXIA traffic generator. +""" + +from .ixia import * diff --git a/tools/pkt_gen/ixia/ixia.py b/tools/pkt_gen/ixia/ixia.py new file mode 100755 index 00000000..92ef5203 --- /dev/null +++ b/tools/pkt_gen/ixia/ixia.py @@ -0,0 +1,328 @@ +# Copyright 2015 Intel Corporation. +# +# 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. +"""IXIA traffic generator model. + +Provides a model for the IXIA traffic generator. In addition, provides +a number of generic "helper" functions that are used to do the "heavy +lifting". + +This requires the following settings in your config file: + +* TRAFFICGEN_IXIA_LIB_PATH + IXIA libraries path +* TRAFFICGEN_IXIA_HOST + IXIA chassis IP address +* TRAFFICGEN_IXIA_CARD + IXIA card +* TRAFFICGEN_IXIA_PORT1 + IXIA Tx port +* TRAFFICGEN_IXIA_PORT2 + IXIA Rx port + +If any of these don't exist, the application will raise an exception +(EAFP). +""" + +import tkinter +import logging +import os + +from tools.pkt_gen import trafficgen +from conf import settings +from collections import OrderedDict +from core.results.results_constants import ResultsConstants + +_ROOT_DIR = os.path.dirname(os.path.realpath(__file__)) +_IXIA_ROOT_DIR = settings.getValue('TRAFFICGEN_IXIA_ROOT_DIR') + + +def configure_env(): + """Configure envionment for TCL. + + """ + os.environ['IXIA_HOME'] = _IXIA_ROOT_DIR + + # USER MAY NEED TO CHANGE THESE IF USING OWN TCL LIBRARY + os.environ['TCL_HOME'] = _IXIA_ROOT_DIR + os.environ['TCLver'] = '8.5' + + # USER NORMALLY DOES NOT CHANGE ANY LINES BELOW + os.environ['IxiaLibPath'] = os.path.expandvars('$IXIA_HOME/lib') + os.environ['IxiaBinPath'] = os.path.expandvars('$IXIA_HOME/bin') + + os.environ['TCLLibPath'] = os.path.expandvars('$TCL_HOME/lib') + os.environ['TCLBinPath'] = os.path.expandvars('$TCL_HOME/bin') + + os.environ['TCL_LIBRARY'] = os.path.expandvars('$TCLLibPath/tcl$TCLver') + os.environ['TK_LIBRARY'] = os.path.expandvars('$TCLLibPath/tk$TCLver') + + os.environ['PATH'] = os.path.expandvars('$IxiaBinPath:.:$TCLBinPath:$PATH') + os.environ['TCLLIBPATH'] = os.path.expandvars('$IxiaLibPath') + os.environ['LD_LIBRARY_PATH'] = os.path.expandvars( + '$IxiaLibPath:$TCLLibPath:$LD_LIBRARY_PATH') + + os.environ['IXIA_RESULTS_DIR'] = '/tmp/Ixia/Results' + os.environ['IXIA_LOGS_DIR'] = '/tmp/Ixia/Logs' + os.environ['IXIA_TCL_DIR'] = os.path.expandvars('$IxiaLibPath') + os.environ['IXIA_SAMPLES'] = os.path.expandvars('$IxiaLibPath/ixTcl1.0') + os.environ['IXIA_VERSION'] = '6.60.1000.11' + + +def _build_set_cmds(values, prefix='dict set'): + """Generate a list of 'dict set' args for Tcl. + + Parse a dictionary and recursively build the arguments for the + 'dict set' Tcl command, given that this is of the format: + + dict set [name...] [key] [value] + + For example, for a non-nested dict (i.e. a non-dict element): + + dict set mydict mykey myvalue + + For a nested dict (i.e. a dict element): + + dict set mydict mysubdict mykey myvalue + + :param values: Dictionary to yield values for + :param prefix: Prefix to append to output string. Generally the + already generated part of the command. + + :yields: Output strings to be passed to a `Tcl` instance. + """ + for key in values: + value = values[key] + + # Not allowing derived dictionary types for now + # pylint: disable=unidiomatic-typecheck + if type(value) == dict: + _prefix = ' '.join([prefix, key]).strip() + for subkey in _build_set_cmds(value, _prefix): + yield subkey + continue + + # tcl doesn't recognise the strings "True" or "False", only "1" + # or "0". Special case to convert them + if type(value) == bool: + value = str(int(value)) + else: + value = str(value) + + if prefix: + yield ' '.join([prefix, key, value]).strip() + else: + yield ' '.join([key, value]).strip() + + +class Ixia(trafficgen.ITrafficGenerator): + """A wrapper around the IXIA traffic generator. + + Runs different traffic generator tests through an Ixia traffic + generator chassis by generating TCL scripts from templates. + """ + _script = os.path.join(os.path.dirname(__file__), 'pass_fail.tcl') + _tclsh = tkinter.Tcl() + _logger = logging.getLogger(__name__) + + def run_tcl(self, cmd): + """Run a TCL script using the TCL interpreter found in ``tkinter``. + + :param cmd: Command to execute + + :returns: Output of command, where applicable. + """ + self._logger.debug('%s%s', trafficgen.CMD_PREFIX, cmd) + + output = self._tclsh.eval(cmd) + + return output.split() + + def connect(self): + """Connect to Ixia chassis. + """ + ixia_cfg = { + 'lib_path': os.path.join(_IXIA_ROOT_DIR, 'lib', 'ixTcl1.0'), + 'host': settings.getValue('TRAFFICGEN_IXIA_HOST'), + 'card': settings.getValue('TRAFFICGEN_IXIA_CARD'), + 'port1': settings.getValue('TRAFFICGEN_IXIA_PORT1'), + 'port2': settings.getValue('TRAFFICGEN_IXIA_PORT2'), + } + + self._logger.info('Connecting to IXIA...') + + self._logger.debug('IXIA configuration configuration : %s', ixia_cfg) + + configure_env() + + for cmd in _build_set_cmds(ixia_cfg, prefix='set'): + self.run_tcl(cmd) + + output = self.run_tcl('source {%s}' % self._script) + if output: + self._logger.critical( + 'An error occured when connecting to IXIA...') + raise RuntimeError('Ixia failed to initialise.') + + self._logger.info('Connected to IXIA...') + + return self + + def disconnect(self): + """Disconnect from Ixia chassis. + """ + self._logger.info('Disconnecting from IXIA...') + + self.run_tcl('cleanUp') + + self._logger.info('Disconnected from IXIA...') + + def _send_traffic(self, flow, traffic): + """Send regular traffic. + + :param flow: Flow specification + :param traffic: Traffic specification + + :returns: Results from IXIA + """ + params = {} + + params['flow'] = flow + params['traffic'] = self.traffic_defaults.copy() + + if traffic: + params['traffic'] = trafficgen.merge_spec( + params['traffic'], traffic) + + for cmd in _build_set_cmds(params): + self.run_tcl(cmd) + + result = self.run_tcl('sendTraffic $flow $traffic') + + return result + + def send_burst_traffic(self, traffic=None, numpkts=100, time=20, + framerate=100): + """See ITrafficGenerator for description + """ + flow = { + 'numpkts': numpkts, + 'time': time, + 'type': 'stopStream', + 'framerate': framerate, + } + + result = self._send_traffic(flow, traffic) + + assert len(result) == 6 # fail-fast if underlying Tcl code changes + + #TODO - implement Burst results setting via TrafficgenResults. + + def send_cont_traffic(self, traffic=None, time=20, framerate=100, + multistream=False): + """See ITrafficGenerator for description + """ + flow = { + 'numpkts': 100, + 'time': time, + 'type': 'contPacket', + 'framerate': framerate, + 'multipleStreams': multistream, + } + + result = self._send_traffic(flow, traffic) + + return Ixia._create_result(result) + + def start_cont_traffic(self, traffic=None, time=20, framerate=100, + multistream=False): + """See ITrafficGenerator for description + """ + return self.send_cont_traffic(traffic, 0, framerate) + + def stop_cont_traffic(self): + """See ITrafficGenerator for description + """ + return self.run_tcl('stopTraffic') + + def send_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + lossrate=0.0, multistream=False): + """See ITrafficGenerator for description + """ + params = {} + + params['config'] = { + 'trials': trials, + 'duration': duration, + 'lossrate': lossrate, + 'multipleStreams': multistream, + } + params['traffic'] = self.traffic_defaults.copy() + + if traffic: + params['traffic'] = trafficgen.merge_spec( + params['traffic'], traffic) + + for cmd in _build_set_cmds(params): + self.run_tcl(cmd) + + # this will return a list with one result + result = self.run_tcl('rfcThroughputTest $config $traffic') + + return Ixia._create_result(result) + + @staticmethod + def _create_result(result): + """Create result based on list returned from tcl script. + + :param result: list representing output from tcl script. + + :returns: dictionary strings representing results from + traffic generator. + """ + assert len(result) == 8 # fail-fast if underlying Tcl code changes + + result_dict = OrderedDict() + # drop the first 4 elements as we don't use/need them. In + # addition, IxExplorer does not support latency or % line rate + # metrics so we have to return dummy values for these metrics + result_dict[ResultsConstants.THROUGHPUT_RX_FPS] = result[4] + result_dict[ResultsConstants.THROUGHPUT_TX_FPS] = result[5] + result_dict[ResultsConstants.THROUGHPUT_RX_MBPS] = result[6] + result_dict[ResultsConstants.THROUGHPUT_TX_MBPS] = result[7] + result_dict[ResultsConstants.THROUGHPUT_TX_PERCENT] = \ + ResultsConstants.UNKNOWN_VALUE + result_dict[ResultsConstants.THROUGHPUT_RX_PERCENT] = \ + ResultsConstants.UNKNOWN_VALUE + result_dict[ResultsConstants.MIN_LATENCY_NS] = \ + ResultsConstants.UNKNOWN_VALUE + result_dict[ResultsConstants.MAX_LATENCY_NS] = \ + ResultsConstants.UNKNOWN_VALUE + result_dict[ResultsConstants.AVG_LATENCY_NS] = \ + ResultsConstants.UNKNOWN_VALUE + + return result_dict + +if __name__ == '__main__': + TRAFFIC = { + 'l3': { + 'proto': 'udp', + 'srcip': '10.1.1.1', + 'dstip': '10.1.1.254', + }, + } + + with Ixia() as dev: + print(dev.send_burst_traffic(traffic=TRAFFIC)) + print(dev.send_cont_traffic(traffic=TRAFFIC)) + print(dev.send_rfc2544_throughput(traffic=TRAFFIC)) diff --git a/tools/pkt_gen/ixia/pass_fail.tcl b/tools/pkt_gen/ixia/pass_fail.tcl new file mode 100755 index 00000000..63d4d914 --- /dev/null +++ b/tools/pkt_gen/ixia/pass_fail.tcl @@ -0,0 +1,721 @@ +#!/usr/bin/env tclsh + +# Copyright (c) 2014, Ixia +# Copyright (c) 2015, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +# This file is a modified version of a script generated by Ixia +# IxExplorer. + +lappend auto_path [list $lib_path] + +package req IxTclHal + +################################################################### +########################## Configuration ########################## +################################################################### + +# Verify that the IXIA chassis spec is given + +set reqVars [list "host" "card" "port1" "port2"] + +foreach var $reqVars { + set var_ns [namespace which -variable "$var"] + if { [string compare $var_ns ""] == 0 } { + errorMsg "The '$var' variable is undefined. Did you set it?" + return -1 + } +} + +# constants + +set fullHex "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFF" +set hexToC5 "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5" + +#set payloadLookup(64) [string range $fullHex 0 11] +set payloadLookup(64) "000102030405" +set payloadLookup(128) "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445" +set payloadLookup(256) "$hexToC5" +set payloadLookup(512) "$fullHex$hexToC5" +set payloadLookup(1024) "$fullHex$fullHex$fullHex$hexToC5" + +################################################################### +###################### Chassis Configuration ###################### +################################################################### + +if {[isUNIX]} { + if {[ixConnectToTclServer $host]} { + errorMsg "Error connecting to Tcl Server $host" + return $::TCL_ERROR + } +} + +######### Chassis ######### + +# Now connect to the chassis +if [ixConnectToChassis $host] { + ixPuts $::ixErrorInfo + return 1 +} + +# Get the chassis ID to use in port lists +set chassis [ixGetChassisID $host] + +######### Ports ######### + +set portList [list [list $chassis $card $port1] \ + [list $chassis $card $port2]] + +# Clear ownership of the ports we’ll use +if [ixClearOwnership $portList force] { + ixPuts $::ixErrorInfo + return 1 +} + +# Take ownership of the ports we’ll use +if [ixTakeOwnership $portList] { + ixPuts $::ixErrorInfo + return 1 +} + +foreach portElem $portList { + set chasNum [lindex $portElem 0] + set cardNum [lindex $portElem 1] + set portNum [lindex $portElem 2] + + port setFactoryDefaults $chasNum $cardNum $portNum + port config -speed 10000 + port config -flowControl true + port config -transmitMode portTxModeAdvancedScheduler + port config -receiveMode [expr $::portCapture|$::portRxModeWidePacketGroup] + port config -advertise100FullDuplex false + port config -advertise100HalfDuplex false + port config -advertise10FullDuplex false + port config -advertise10HalfDuplex false + port config -portMode port10GigLanMode + port config -enableTxRxSyncStatsMode true + port config -txRxSyncInterval 2000 + port config -enableTransparentDynamicRateChange true + port config -enableDynamicMPLSMode true + if {[port set $chasNum $cardNum $portNum]} { + errorMsg "Error calling port set $chasNum $cardNum $portNum" + } + + packetGroup setDefault + packetGroup config -numTimeBins 1 + if {[packetGroup setRx $chasNum $cardNum $portNum]} { + errorMsg "Error calling packetGroup setRx $chasNum $cardNum $portNum" + } + + sfpPlus setDefault + sfpPlus config -enableAutomaticDetect false + sfpPlus config -txPreTapControlValue 1 + sfpPlus config -txMainTapControlValue 63 + sfpPlus config -txPostTapControlValue 2 + sfpPlus config -rxEqualizerControlValue 0 + if {[sfpPlus set $chasNum $cardNum $portNum]} { + errorMsg "Error calling sfpPlus set $chasNum $cardNum $portNum" + } + + filter setDefault + filter config -captureTriggerFrameSizeFrom 48 + filter config -captureTriggerFrameSizeTo 48 + filter config -captureFilterFrameSizeFrom 48 + filter config -captureFilterFrameSizeTo 48 + filter config -userDefinedStat1FrameSizeFrom 48 + filter config -userDefinedStat1FrameSizeTo 48 + filter config -userDefinedStat2FrameSizeFrom 48 + filter config -userDefinedStat2FrameSizeTo 48 + filter config -asyncTrigger1FrameSizeFrom 48 + filter config -asyncTrigger1FrameSizeTo 48 + filter config -asyncTrigger2FrameSizeFrom 48 + filter config -asyncTrigger2FrameSizeTo 48 + filter config -userDefinedStat1Enable true + filter config -userDefinedStat2Enable true + filter config -asyncTrigger1Enable true + filter config -asyncTrigger2Enable true + if {[filter set $chasNum $cardNum $portNum]} { + errorMsg "Error calling filter set $chasNum $cardNum $portNum" + } + + filterPallette setDefault + filterPallette config -pattern1 00 + filterPallette config -patternMask1 00 + filterPallette config -patternOffset1 20 + filterPallette config -patternOffset2 20 + if {[filterPallette set $chasNum $cardNum $portNum]} { + errorMsg "Error calling filterPallette set $chasNum $cardNum $portNum" + } + + capture setDefault + capture config -sliceSize 65536 + if {[capture set $chasNum $cardNum $portNum]} { + errorMsg "Error calling capture set $chasNum $cardNum $portNum" + } + + if {[interfaceTable select $chasNum $cardNum $portNum]} { + errorMsg "Error calling interfaceTable select $chasNum $cardNum $portNum" + } + + interfaceTable setDefault + if {[interfaceTable set]} { + errorMsg "Error calling interfaceTable set" + } + + interfaceTable clearAllInterfaces + if {[interfaceTable write]} { + errorMsg "Error calling interfaceTable write" + } + + ixEnablePortIntrinsicLatencyAdjustment $chasNum $cardNum $portNum true +} + +ixWritePortsToHardware portList + +if {[ixCheckLinkState $portList] != 0} { + errorMsg "One or more port links are down" +} + +proc sendTraffic { flowSpec trafficSpec } { + # Send traffic from IXIA. + # + # Transmits traffic from Rx port (port1), and captures traffic at + # Tx port (port2). + # + # Parameters: + # flowSpec - a dict detailing how the packet should be sent. Should be + # of format: + # {type, numpkts, time, framerate} + # trafficSpec - a dict describing the packet to be sent. Should be + # of format: + # { l2, vlan, l3} + # where each item is in turn a dict detailing the configuration of each + # layer of the packet + # Returns: + # Output from Rx end of Ixia if time != 0, else 0 + + ################################################## + ################# Initialisation ################# + ################################################## + + # Configure global variables. See documentation on 'global' for more + # information on why this is necessary + # https://www.tcl.tk/man/tcl8.5/tutorial/Tcl13.html + global portList + + # Extract the provided dictionaries to local variables to simplify the + # rest of the script + + # flow spec + + set streamType [dict get $flowSpec type] + set numPkts [dict get $flowSpec numpkts] + set time [expr {[dict get $flowSpec time] * 1000}] + set frameRate [dict get $flowSpec framerate] + + # traffic spec + + # extract nested dictionaries + set trafficSpec_l2 [dict get $trafficSpec l2] + set trafficSpec_l3 [dict get $trafficSpec l3] + set trafficSpec_vlan [dict get $trafficSpec vlan] + + set frameSize [dict get $trafficSpec_l2 framesize] + set srcMac [dict get $trafficSpec_l2 srcmac] + set dstMac [dict get $trafficSpec_l2 dstmac] + set srcPort [dict get $trafficSpec_l2 srcport] + set dstPort [dict get $trafficSpec_l2 dstport] + + set proto [dict get $trafficSpec_l3 proto] + set srcIp [dict get $trafficSpec_l3 srcip] + set dstIp [dict get $trafficSpec_l3 dstip] + + set vlanEnabled [dict get $trafficSpec_vlan enabled] + if {$vlanEnabled == 1 } { + # these keys won't exist if vlan wasn't enabled + set vlanId [dict get $trafficSpec_vlan id] + set vlanUserPrio [dict get $trafficSpec_vlan priority] + set vlanCfi [dict get $trafficSpec_vlan cfi] + } + + ################################################## + ##################### Streams #################### + ################################################## + + streamRegion get $::chassis $::card $::port1 + if {[streamRegion enableGenerateWarningList $::chassis $::card $::port1 false]} { + errorMsg "Error calling streamRegion enableGenerateWarningList $::chassis $::card $::port1 false" + } + + set streamId 1 + + stream setDefault + stream config -ifg 9.6 + stream config -ifgMIN 19.2 + stream config -ifgMAX 25.6 + stream config -ibg 9.6 + stream config -isg 9.6 + stream config -rateMode streamRateModePercentRate + stream config -percentPacketRate $frameRate + stream config -framesize $frameSize + stream config -frameType "08 00" + stream config -sa $srcMac + stream config -da $dstMac + stream config -numSA 16 + stream config -numDA 16 + stream config -asyncIntEnable true + stream config -dma $streamType + stream config -numBursts 1 + stream config -numFrames $numPkts + stream config -patternType incrByte + stream config -dataPattern x00010203 + stream config -pattern "00 01 02 03" + + protocol setDefault + protocol config -name ipV4 + protocol config -ethernetType ethernetII + if {$vlanEnabled == 1} { + protocol config -enable802dot1qTag vlanSingle + } + + ip setDefault + ip config -ipProtocol ipV4Protocol[string totitle $proto] + ip config -checksum "f6 75" + ip config -sourceIpAddr $srcIp + ip config -sourceIpAddrRepeatCount 10 + ip config -sourceClass classA + ip config -destIpAddr $dstIp + ip config -destIpAddrRepeatCount 10 + ip config -destClass classA + ip config -destMacAddr $dstMac + ip config -destDutIpAddr 0.0.0.0 + ip config -ttl 64 + if {[ip set $::chassis $::card $::port1]} { + errorMsg "Error calling ip set $::chassis $::card $::port1" + } + + "$proto" setDefault + "$proto" config -checksum "25 81" + if {["$proto" set $::chassis $::card $::port1]} { + errorMsg "Error calling $proto set $::chassis $::card $::port" + } + + if {$vlanEnabled == 1 } { + vlan setDefault + vlan config -vlanID $vlanId + vlan config -userPriority $vlanUserPrio + vlan config -cfi $vlanCfi + vlan config -mode vIdle + vlan config -repeat 10 + vlan config -step 1 + vlan config -maskval "0000XXXXXXXXXXXX" + vlan config -protocolTagId vlanProtocolTag8100 + } + + if {[vlan set $::chassis $::card $::port1]} { + errorMsg "Error calling vlan set $::chassis $::card $::port1" + } + + if {[port isValidFeature $::chassis $::card $::port1 $::portFeatureTableUdf]} { + tableUdf setDefault + tableUdf clearColumns + if {[tableUdf set $::chassis $::card $::port1]} { + errorMsg "Error calling tableUdf set $::chassis $::card $::port1" + } + } + + if {[port isValidFeature $::chassis $::card $::port1 $::portFeatureRandomFrameSizeWeightedPair]} { + weightedRandomFramesize setDefault + if {[weightedRandomFramesize set $::chassis $::card $::port1]} { + errorMsg "Error calling weightedRandomFramesize set $::chassis $::card $::port1" + } + } + + if {$proto == "tcp"} { + tcp setDefault + tcp config -sourcePort $srcPort + tcp config -destPort $dstPort + if {[tcp set $::chassis $::card $::port1 ]} { + errorMsg "Error setting tcp on port $::chassis.$::card.$::port1" + } + + if {$vlanEnabled != 1} { + udf setDefault + udf config -repeat 1 + udf config -continuousCount true + udf config -initval {00 00 00 01} + udf config -updown uuuu + udf config -cascadeType udfCascadeNone + udf config -step 1 + + packetGroup setDefault + packetGroup config -insertSequenceSignature true + packetGroup config -sequenceNumberOffset 38 + packetGroup config -signatureOffset 42 + packetGroup config -signature "08 71 18 05" + packetGroup config -groupIdOffset 52 + packetGroup config -groupId $streamId + packetGroup config -allocateUdf true + if {[packetGroup setTx $::chassis $::card $::port1 $streamId]} { + errorMsg "Error calling packetGroup setTx $::chassis $::card $::port1 $streamId" + } + } + } elseif {$proto == "udp"} { + udp setDefault + udp config -sourcePort $srcPort + udp config -destPort $dstPort + if {[udp set $::chassis $::card $::port1]} { + errorMsg "Error setting udp on port $::chassis.$::card.$::port1" + } + } + + if {[stream set $::chassis $::card $::port1 $streamId]} { + errorMsg "Error calling stream set $::chassis $::card $::port1 $streamId" + } + + incr streamId + streamRegion generateWarningList $::chassis $::card $::port1 + ixWriteConfigToHardware portList -noProtocolServer + + if {[packetGroup getRx $::chassis $::card $::port2]} { + errorMsg "Error calling packetGroup getRx $::chassis $::card $::port2" + } + + ################################################## + ######### Traffic Transmit and Results ########### + ################################################## + + # Transmit traffic + + logMsg "Clearing stats for all ports" + ixClearStats portList + + logMsg "Starting packet groups on port $::port2" + ixStartPortPacketGroups $::chassis $::card $::port2 + + logMsg "Starting Capture on port $::port2" + ixStartPortCapture $::chassis $::card $::port2 + + logMsg "Starting transmit on port $::port1" + ixStartPortTransmit $::chassis $::card $::port1 + + # If time=0 is passed, exit after starting transmit + + if {$time == 0} { + logMsg "Sending traffic until interrupted" + return + } + + logMsg "Waiting for $time ms" + + # Wait for time - 1 second to get traffic rate + + after [expr "$time - 1"] + + # Get result + + set result [stopTraffic] + + if {$streamType == "contPacket"} { + return $result + } elseif {$streamType == "stopStream"} { + set payError 0 + set seqError 0 + set captureLimit 3000 + + # explode results from 'stopTraffic' for ease of use later + set framesSent [lindex $result 0] + set framesRecv [lindex $result 1] + set bytesSent [lindex $result 2] + set bytesRecv [lindex $result 3] + + if {$framesSent <= $captureLimit} { + captureBuffer get $::chassis $::card $::port2 1 $framesSent + set capturedFrames [captureBuffer cget -numFrames] + + set notCaptured [expr "$framesRecv - $capturedFrames"] + if {$notCaptured != 0} { + errorMsg "'$notCaptured' frames were not captured" + } + + if {$proto == "tcp"} { + for {set z 1} {$z <= $capturedFrames} {incr z} { + captureBuffer getframe $z + set capFrame [captureBuffer cget -frame] + regsub -all " " $capFrame "" frameNoSpaces + set frameNoSpaces + + set startPayload 108 + set endPayload [expr "[expr "$frameSize * 2"] - 9"] + set payload [string range $frameNoSpaces $startPayload $endPayload] + + if {$vlanEnabled != 1} { + set startSequence 76 + set endSequence 83 + set sequence [string range $frameNoSpaces $startSequence $endSequence] + scan $sequence %x seqDecimal + set seqDecimal + if {"$payload" != $::payloadLookup($frameSize)} { + errorMsg "frame '$z' payload: invalid payload" + incr payError + } + # variable z increments from 1 to total number of packets + # captured TCP sequence numbers start at 0, not 1. When + # comparing sequence numbers for captured frames, reduce + # variable z by 1 i.e. frame 1 with sequence 0 is compared + # to expected sequence 0. + if {$seqDecimal != $z-1} { + errorMsg "frame '$z' sequence number: Found '$seqDecimal'. Expected '$z'" + incr seqError + } + } + } + } + logMsg "Sequence Errors: $seqError" + logMsg "Payload Errors: $payError\n" + } else { + errorMsg "Too many packets for capture." + } + + set result [list $framesSent $framesRecv $bytesSent $bytesRecv $payError $seqError] + return $result + } else { + errorMsg "streamtype is not supported: '$streamType'" + } +} + +proc stopTraffic {} { + # Stop sending traffic from IXIA. + # + # Stops Transmit of traffic from Rx port. + # + # Returns: + # Output from Rx end of Ixia. + + ################################################## + ################# Initialisation ################# + ################################################## + + # Configure global variables. See documentation on 'global' for more + # information on why this is necessary + # https://www.tcl.tk/man/tcl8.5/tutorial/Tcl13.html + global portList + + ################################################## + ####### Stop Traffic Transmit and Results ######## + ################################################## + + # Read frame rate of transmission + + if {[stat getRate statAllStats $::chassis $::card $::port1]} { + errorMsg "Error reading stat rate on port $::chassis $::card $::port1" + return $::TCL_ERROR + } + + set sendRate [stat cget -framesSent] + set sendRateBytes [stat cget -bytesSent] + + if {[stat getRate statAllStats $::chassis $::card $::port2]} { + errorMsg "Error reading stat rate on port $::chassis $::card $::port2" + return $::TCL_ERROR + } + + set recvRate [stat cget -framesReceived] + set recvRateBytes [stat cget -bytesReceived] + + # Wait for a second, else we get funny framerate statistics + after 1 + + # Stop transmission of traffic + ixStopTransmit portList + + if {[ixCheckTransmitDone portList] == $::TCL_ERROR} { + return -code error + } else { + logMsg "Transmission is complete.\n" + } + + ixStopPacketGroups portList + ixStopCapture portList + + # Get statistics + + if {[stat get statAllStats $::chassis $::card $::port1]} { + errorMsg "Error reading stat on port $::chassis $::card $::port1" + return $::TCL_ERROR + } + + set bytesSent [stat cget -bytesSent] + set framesSent [stat cget -framesSent] + + if {[stat get statAllStats $::chassis $::card $::port2]} { + errorMsg "Error reading stat on port $::chassis $::card $::port2" + return $::TCL_ERROR + } + + set bytesRecv [stat cget -bytesReceived] + set framesRecv [stat cget -framesReceived] + + set bytesDropped [expr "$bytesSent - $bytesRecv"] + set framesDropped [expr "$framesSent - $framesRecv"] + + logMsg "Frames Sent: $framesSent" + logMsg "Frames Recv: $framesRecv" + logMsg "Frames Dropped: $framesDropped\n" + + logMsg "Bytes Sent: $bytesSent" + logMsg "Bytes Recv: $bytesRecv" + logMsg "Bytes Dropped: $bytesDropped\n" + + logMsg "Frame Rate Sent: $sendRate" + logMsg "Frame Rate Recv: $recvRate\n" + + set result [list $framesSent $framesRecv $bytesSent $bytesRecv $sendRate $recvRate $sendRateBytes $recvRateBytes] + + return $result +} + +proc rfcThroughputTest { testSpec trafficSpec } { + # Execute RFC tests from IXIA. + # + # Wraps the sendTraffic proc, repeatedly calling it, storing the result and + # performing an iterative binary search to find the highest possible RFC + # transmission rate. Abides by the specification of RFC2544 as given by the + # IETF: + # + # https://www.ietf.org/rfc/rfc2544.txt + # + # Parameters: + # testSpec - a dict detailing how the test should be run. Should be + # of format: + # {numtrials, duration, lossrate} + # trafficSpec - a dict describing the packet to be sent. Should be + # of format: + # { l2, l3} + # where each item is in turn a dict detailing the configuration of each + # layer of the packet + # Returns: + # Highest rate with acceptable packet loss. + + ################################################## + ################# Initialisation ################# + ################################################## + + # Configure global variables. See documentation on 'global' for more + # information on why this is necessary + # https://www.tcl.tk/man/tcl8.5/tutorial/Tcl13.html + global portList + + # Extract the provided dictionaries to local variables to simplify the + # rest of the script + + # testSpec + + set numTrials [dict get $testSpec trials] ;# we don't use this yet + set duration [dict get $testSpec duration] + set lossRate [dict get $testSpec lossrate] + set multipleStream [dict get $testSpec multipleStreams] ;# we don't use this yet + + # variables used for binary search of results + set min 1 + set max 100 + set diff [expr "$max - $min"] + + set result [list 0 0 0 0 0 0 0 0] ;# best result found so far + set percentRate 100 ;# starting throughput percentage rate + + ################################################## + ######### Traffic Transmit and Results ########### + ################################################## + + # iterate a maximum of 20 times, sending packets at a set rate to + # find fastest possible rate with acceptable packetloss + # + # As a reminder, the binary search works something like this: + # + # percentRate < idealValue --> min = percentRate + # percentRate > idealValue --> max = percentRate + # percentRate = idealValue --> max = min = percentRate + # + for {set i 0} {$i < 20} {incr i} { + dict set flowSpec type "contPacket" + dict set flowSpec numpkts 100 ;# this can be bypassed + dict set flowSpec time $duration + dict set flowSpec framerate $percentRate + + set flowStats [sendTraffic $flowSpec $trafficSpec] + + # explode results from 'sendTraffic' for ease of use later + set framesSent [lindex $flowStats 0] + set framesRecv [lindex $flowStats 1] + set sendRate [lindex $flowStats 4] + + set framesDropped [expr "$framesSent - $framesRecv"] + if {$framesSent > 0} { + set framesDroppedRate [expr "double($framesDropped) / $framesSent"] + } else { + set framesDroppedRate 100 + } + + # check if we've already found the rate before 10 iterations, i.e. + # 'percentRate = idealValue'. This is as accurate as we can get with + # integer values. + if {[expr "$max - $min"] <= 0.5 } { + break + } + + # handle 'percentRate <= idealValue' case + if {$framesDroppedRate <= $lossRate} { + logMsg "Frame sendRate of '$sendRate' pps succeeded ('$framesDropped' frames dropped)" + + set result $flowStats + set min $percentRate + + set percentRate [expr "$percentRate + ([expr "$max - $min"] * 0.5)"] + # handle the 'percentRate > idealValue' case + } else { + if {$framesDropped == $framesSent} { + errorMsg "Dropped all frames!" + } + + errorMsg "Frame sendRate of '$sendRate' pps failed ('$framesDropped' frames dropped)" + + set max $percentRate + set percentRate [expr "$percentRate - ([expr "$max - $min"] * 0.5)"] + } + } + + set bestRate [lindex $result 4] + + logMsg "$lossRate% packet loss rate: $bestRate" + + return $result +} diff --git a/tools/pkt_gen/ixnet/__init__.py b/tools/pkt_gen/ixnet/__init__.py new file mode 100755 index 00000000..dd84c45a --- /dev/null +++ b/tools/pkt_gen/ixnet/__init__.py @@ -0,0 +1,18 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Implementation of IXIA ixnet-based traffic generator. +""" + +from .ixnet import * diff --git a/tools/pkt_gen/ixnet/ixnet.py b/tools/pkt_gen/ixnet/ixnet.py new file mode 100755 index 00000000..fdea4bfd --- /dev/null +++ b/tools/pkt_gen/ixnet/ixnet.py @@ -0,0 +1,516 @@ +# Copyright 2015 Intel Corporation. +# +# 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. +"""IxNetwork traffic generator model. + +Provides a model for an IxNetwork machine and appropriate applications. + +This requires the following settings in your config file: + +* TRAFFICGEN_IXNET_LIB_PATH + IxNetwork libraries path +* TRAFFICGEN_IXNET_HOST + IxNetwork host IP address +* TRAFFICGEN_IXNET_PORT + IxNetwork host port number +* TRAFFICGEN_IXNET_USER + IxNetwork host user name +* TRAFFICGEN_IXNET_TESTER_RESULT_DIR + The result directory on the IxNetwork computer +* TRAFFICGEN_IXNET_DUT_RESULT_DIR + The result directory on DUT. This needs to map to the same directory + as the previous one + +The following settings are also required. These can likely be shared +an 'Ixia' traffic generator instance: + +* TRAFFICGEN_IXIA_HOST + IXIA chassis IP address +* TRAFFICGEN_IXIA_CARD + IXIA card +* TRAFFICGEN_IXIA_PORT1 + IXIA Tx port +* TRAFFICGEN_IXIA_PORT2 + IXIA Rx port + +If any of these don't exist, the application will raise an exception +(EAFP). + +Additional Configuration: +------------------------- + +You will also need to configure the IxNetwork machine to start the IXIA +IxNetworkTclServer. This can be started like so: + +1. Connect to the IxNetwork machine using RDP +2. Go to: + + Start-> + Programs -> + Ixia -> + IxNetwork -> + IxNetwork 7.21.893.14 GA -> + IxNetworkTclServer + + Pin a shortcut to this application to the taskbar. +3. Before running it right click the pinned shortcut and go to + "Properties". Here change the port number to your own port number. + This will be the same value as "TRAFFICGEN_IXNET_PORT" above. +4. You will find this on the shortcut tab under the heading "Target" +5. Finally run it. If you see the following error check that you + followed the above steps exactly: + + ERROR: couldn't open socket : connection refused + +Debugging: +---------- + +This method of automation is quite error prone as the IxNetwork API +does not give any feedback as to the status of tests. As such, it can +be expected that the user have access to the IxNetwork machine should +this trafficgen need to be debugged. +""" + +import tkinter +import logging +import os +import re +import csv + +from collections import OrderedDict +from tools.pkt_gen import trafficgen +from conf import settings +from core.results.results_constants import ResultsConstants + +_ROOT_DIR = os.path.dirname(os.path.realpath(__file__)) + +_RESULT_RE = r'(?:\{kString,result\},\{kString,)(\w+)(?:\})' +_RESULTPATH_RE = r'(?:\{kString,resultPath\},\{kString,)([\\\w\.\-]+)(?:\})' + + +def _build_set_cmds(values, prefix='dict set'): + """Generate a list of 'dict set' args for Tcl. + + Parse a dictionary and recursively build the arguments for the + 'dict set' Tcl command, given that this is of the format: + + dict set [name...] [key] [value] + + For example, for a non-nested dict (i.e. a non-dict element): + + dict set mydict mykey myvalue + + For a nested dict (i.e. a dict element): + + dict set mydict mysubdict mykey myvalue + + :param values: Dictionary to yield values for + :param prefix: Prefix to append to output string. Generally the + already generated part of the command. + + :yields: Output strings to be passed to a `Tcl` instance. + """ + for key in values: + value = values[key] + + # Not allowing derived dictionary types for now + # pylint: disable=unidiomatic-typecheck + if type(value) == dict: + _prefix = ' '.join([prefix, key]).strip() + for subkey in _build_set_cmds(value, _prefix): + yield subkey + continue + + # pylint: disable=unidiomatic-typecheck + # tcl doesn't recognise the strings "True" or "False", only "1" + # or "0". Special case to convert them + if type(value) == bool: + value = str(int(value)) + else: + value = str(value) + + if prefix: + yield ' '.join([prefix, key, value]).strip() + else: + yield ' '.join([key, value]).strip() + + +class IxNet(trafficgen.ITrafficGenerator): + """A wrapper around IXIA IxNetwork applications. + + Runs different traffic generator tests through an Ixia traffic + generator chassis by generating TCL scripts from templates. + + Currently only the RFC2544 tests are implemented. + """ + _script = os.path.join(os.path.dirname(__file__), 'ixnetrfc2544.tcl') + _tclsh = tkinter.Tcl() + _cfg = None + _logger = logging.getLogger(__name__) + _params = None + + def run_tcl(self, cmd): + """Run a TCL script using the TCL interpreter found in ``tkinter``. + + :param cmd: Command to execute + + :returns: Output of command, where applicable. + """ + self._logger.debug('%s%s', trafficgen.CMD_PREFIX, cmd) + + output = self._tclsh.eval(cmd) + + return output.split() + + def connect(self): + """Configure system for IxNetwork. + """ + self._cfg = { + 'lib_path': settings.getValue('TRAFFICGEN_IXNET_LIB_PATH'), + # IxNetwork machine configuration + 'machine': settings.getValue('TRAFFICGEN_IXNET_MACHINE'), + 'port': settings.getValue('TRAFFICGEN_IXNET_PORT'), + 'user': settings.getValue('TRAFFICGEN_IXNET_USER'), + # IXIA chassis configuration + 'chassis': settings.getValue('TRAFFICGEN_IXIA_HOST'), + 'card': settings.getValue('TRAFFICGEN_IXIA_CARD'), + 'port1': settings.getValue('TRAFFICGEN_IXIA_PORT1'), + 'port2': settings.getValue('TRAFFICGEN_IXIA_PORT2'), + 'output_dir': settings.getValue( + 'TRAFFICGEN_IXNET_TESTER_RESULT_DIR'), + } + + self._logger.debug('IXIA configuration configuration : %s', self._cfg) + + return self + + def disconnect(self): + """Disconnect from Ixia chassis. + """ + pass + + def send_cont_traffic(self, traffic=None, time=20, framerate=0, + multistream=False): + """See ITrafficGenerator for description + """ + self.start_cont_traffic(traffic, time, framerate, multistream) + + return self.stop_cont_traffic() + + def start_cont_traffic(self, traffic=None, time=20, framerate=0, + multistream=False): + """Start transmission. + """ + self._params = {} + + self._params['config'] = { + 'binary': False, # don't do binary search and send one stream + 'time': time, + 'framerate': framerate, + 'multipleStreams': multistream, + 'rfc2544TestType': 'throughput', + } + self._params['traffic'] = self.traffic_defaults.copy() + + if traffic: + self._params['traffic'] = trafficgen.merge_spec( + self._params['traffic'], traffic) + + for cmd in _build_set_cmds(self._cfg, prefix='set'): + self.run_tcl(cmd) + + for cmd in _build_set_cmds(self._params): + self.run_tcl(cmd) + + output = self.run_tcl('source {%s}' % self._script) + if output: + self._logger.critical( + 'An error occured when connecting to IxNetwork machine...') + raise RuntimeError('Ixia failed to initialise.') + + self.run_tcl('startRfc2544Test $config $traffic') + if output: + self._logger.critical( + 'Failed to start continuous traffic test') + raise RuntimeError('Continuous traffic test failed to start.') + + def stop_cont_traffic(self): + """See ITrafficGenerator for description + """ + return self._wait_result() + + def send_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + lossrate=0.0, multistream=False): + """See ITrafficGenerator for description + """ + self.start_rfc2544_throughput(traffic, trials, duration, lossrate, + multistream) + + return self.wait_rfc2544_throughput() + + def start_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + lossrate=0.0, multistream=False): + """Start transmission. + """ + self._params = {} + + self._params['config'] = { + 'binary': True, + 'trials': trials, + 'duration': duration, + 'lossrate': lossrate, + 'multipleStreams': multistream, + 'rfc2544TestType': 'throughput', + } + self._params['traffic'] = self.traffic_defaults.copy() + + if traffic: + self._params['traffic'] = trafficgen.merge_spec( + self._params['traffic'], traffic) + + for cmd in _build_set_cmds(self._cfg, prefix='set'): + self.run_tcl(cmd) + + for cmd in _build_set_cmds(self._params): + self.run_tcl(cmd) + + output = self.run_tcl('source {%s}' % self._script) + if output: + self._logger.critical( + 'An error occured when connecting to IxNetwork machine...') + raise RuntimeError('Ixia failed to initialise.') + + self.run_tcl('startRfc2544Test $config $traffic') + if output: + self._logger.critical( + 'Failed to start RFC2544 test') + raise RuntimeError('RFC2544 test failed to start.') + + def wait_rfc2544_throughput(self): + """See ITrafficGenerator for description + """ + return self._wait_result() + + def _wait_result(self): + """Wait for results. + """ + def parse_result_string(results): + """Get path to results file from output + + Check for related errors + + :param results: Text stream from test. + + :returns: Path to results file. + """ + result_status = re.search(_RESULT_RE, results) + result_path = re.search(_RESULTPATH_RE, results) + + if not result_status or not result_path: + self._logger.critical( + 'Could not parse results from IxNetwork machine...') + raise ValueError('Failed to parse output.') + + if result_status.group(1) != 'pass': + self._logger.critical( + 'An error occured when running tests...') + raise RuntimeError('Ixia failed to initialise.') + + # transform path into someting useful + + path = result_path.group(1).replace('\\', '/') + path = os.path.join(path, 'results.csv') + path = path.replace( + settings.getValue('TRAFFICGEN_IXNET_TESTER_RESULT_DIR'), + settings.getValue('TRAFFICGEN_IXNET_DUT_RESULT_DIR')) + return path + + def parse_ixnet_rfc_results(path): + """Parse CSV output of IxNet RFC2544 test run. + + :param path: Input file path + """ + results = OrderedDict() + + with open(path, 'r') as in_file: + reader = csv.reader(in_file, delimiter=',') + next(reader) + for row in reader: + #Replace null entries added by Ixia with 0s. + row = [entry if len(entry) > 0 else '0' for entry in row] + # calculate tx fps by (rx fps * (tx % / rx %)) + tx_fps = float(row[9]) * (float(row[8]) / float(row[7])) + # calculate tx mbps by (rx mbps * (tx % / rx %)) + tx_mbps = float(row[10]) * (float(row[8]) / float(row[7])) + + if bool(results.get(ResultsConstants.THROUGHPUT_RX_FPS)) \ + == False: + prev_percent_rx = 0.0 + else: + prev_percent_rx = \ + float(results.get(ResultsConstants.THROUGHPUT_RX_FPS)) + if float(row[9]) >= prev_percent_rx: + results[ResultsConstants.THROUGHPUT_TX_FPS] = tx_fps + results[ResultsConstants.THROUGHPUT_RX_FPS] = row[9] + results[ResultsConstants.THROUGHPUT_TX_MBPS] = tx_mbps + results[ResultsConstants.THROUGHPUT_RX_MBPS] = row[10] + results[ResultsConstants.THROUGHPUT_TX_PERCENT] = row[7] + results[ResultsConstants.THROUGHPUT_TX_PERCENT] = row[8] + results[ResultsConstants.MIN_LATENCY_NS] = row[15] + results[ResultsConstants.MAX_LATENCY_NS] = row[16] + results[ResultsConstants.AVG_LATENCY_NS] = row[17] + return results + + output = self.run_tcl('waitForRfc2544Test') + + # the run_tcl function will return a list with one element. We extract + # that one element (a string representation of an IXIA-specific Tcl + # datatype), parse it to find the path of the results file then parse + # the results file + return parse_ixnet_rfc_results(parse_result_string(output[0])) + + def send_rfc2544_back2back(self, traffic=None, trials=1, duration=20, + lossrate=0.0, multistream=False): + """See ITrafficGenerator for description + """ + self.start_rfc2544_back2back(traffic, trials, duration, lossrate, + multistream) + + return self.wait_rfc2544_back2back() + + def start_rfc2544_back2back(self, traffic=None, trials=1, duration=20, + lossrate=0.0, multistream=False): + """Start transmission. + """ + self._params = {} + + self._params['config'] = { + 'binary': True, + 'trials': trials, + 'duration': duration, + 'lossrate': lossrate, + 'multipleStreams': multistream, + 'rfc2544TestType': 'back2back', + } + self._params['traffic'] = self.traffic_defaults.copy() + + if traffic: + self._params['traffic'] = trafficgen.merge_spec( + self._params['traffic'], traffic) + + for cmd in _build_set_cmds(self._cfg, prefix='set'): + self.run_tcl(cmd) + + for cmd in _build_set_cmds(self._params): + self.run_tcl(cmd) + + output = self.run_tcl('source {%s}' % self._script) + if output: + self._logger.critical( + 'An error occured when connecting to IxNetwork machine...') + raise RuntimeError('Ixia failed to initialise.') + + self.run_tcl('startRfc2544Test $config $traffic') + if output: + self._logger.critical( + 'Failed to start RFC2544 test') + raise RuntimeError('RFC2544 test failed to start.') + + def wait_rfc2544_back2back(self): + """Wait for results. + """ + def parse_result_string(results): + """Get path to results file from output + + Check for related errors + + :param results: Text stream from test. + + :returns: Path to results file. + """ + result_status = re.search(_RESULT_RE, results) + result_path = re.search(_RESULTPATH_RE, results) + + if not result_status or not result_path: + self._logger.critical( + 'Could not parse results from IxNetwork machine...') + raise ValueError('Failed to parse output.') + + if result_status.group(1) != 'pass': + self._logger.critical( + 'An error occured when running tests...') + raise RuntimeError('Ixia failed to initialise.') + + # transform path into something useful + + path = result_path.group(1).replace('\\', '/') + path = os.path.join(path, 'iteration.csv') + path = path.replace( + settings.getValue('TRAFFICGEN_IXNET_TESTER_RESULT_DIR'), + settings.getValue('TRAFFICGEN_IXNET_DUT_RESULT_DIR')) + + return path + + def parse_ixnet_rfc_results(path): + """Parse CSV output of IxNet RFC2544 Back2Back test run. + + :param path: Input file path + + :returns: Best parsed result from CSV file. + """ + results = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] + + with open(path, 'r') as in_file: + reader = csv.reader(in_file, delimiter=',') + next(reader) + for row in reader: + # if back2back count higher than previously found, store it + # Note: row[N] here refers to the Nth column of a row + if float(row[14]) <= self._params['config']['lossrate']: + if int(row[12]) > int(results[5]): + results = [ + float(row[9]), # rx throughput (fps) + float(row[10]), # rx throughput (mbps) + float(row[7]), # tx rate (% linerate) + float(row[8]), # rx rate (% linerate) + int(row[11]), # tx count (frames) + int(row[12]), # back2back count (frames) + int(row[13]), # frame loss (frames) + float(row[14]), # frame loss (%) + ] + + return results + + self.run_tcl('waitForRfc2544Test') + + # the run_tcl function will return a list with one element. We extract + # that one element (a string representation of an IXIA-specific Tcl + # datatype), parse it to find the path of the results file then parse + # the results file + + #TODO implement back2back result via IResult interface. + #return parse_ixnet_rfc_results(parse_result_string(output[0])) + + +if __name__ == '__main__': + TRAFFIC = { + 'l3': { + 'proto': 'udp', + 'srcip': '10.1.1.1', + 'dstip': '10.1.1.254', + }, + } + + with IxNet() as dev: + print(dev.send_cont_traffic()) + print(dev.send_rfc2544_throughput()) diff --git a/tools/pkt_gen/ixnet/ixnetrfc2544.tcl b/tools/pkt_gen/ixnet/ixnetrfc2544.tcl new file mode 100755 index 00000000..a294e74a --- /dev/null +++ b/tools/pkt_gen/ixnet/ixnetrfc2544.tcl @@ -0,0 +1,8101 @@ +#!/usr/bin/env tclsh + +# Copyright (c) 2014, Ixia +# Copyright (c) 2015, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +# This file is a modified version of a script generated by Ixia +# IxNetwork. + +lappend auto_path [list $lib_path] + +################################################################### +########################## Configuration ########################## +################################################################### + +# verify that the IXIA chassis spec is given + +set reqVars [list "machine" "port" "user" "chassis" "card" "port1" "port2" "output_dir"] +set rfc2544test "" + +foreach var $reqVars { + set var_ns [namespace which -variable "$var"] + if { [string compare $var_ns ""] == 0 } { + errorMsg "The '$var' variable is undefined. Did you set it?" + return -1 + } +} + +# machine configuration + +set ::IxNserver $machine +set ::IxNport $port + +# change to windows path format and append directory +set output_dir [string map {"/" "\\"} $output_dir] +set output_dir "$output_dir\\rfctests" +puts "Output directory is $output_dir" + +proc startRfc2544Test { testSpec trafficSpec } { + # Start RFC2544 quicktest. + + # Configure global variables. See documentation on 'global' for more + # information on why this is necessary + # https://www.tcl.tk/man/tcl8.5/tutorial/Tcl13.html + global rfc2544test + global sg_rfc2544throughput + global sg_rfc2544back2back + + # flow spec + + set rfc2544TestType [dict get $testSpec rfc2544TestType] + + set binary [dict get $testSpec binary] + + if {$binary} { + set numTrials [dict get $testSpec trials] + set duration [dict get $testSpec duration] + set frameRate 100 + set tolerance [dict get $testSpec lossrate] + set loadType binary + } else { + set numTrials 1 + set duration [dict get $testSpec time] + set frameRate [dict get $testSpec framerate] + set tolerance 0.0 + set loadType custom + } + + set learningFrames True + + if {$learningFrames} { + set learningFrequency oncePerTest + set fastPathEnable True + } else { + set learningFrequency never + set fastPathEnable False + } + + set multipleStreams [dict get $testSpec multipleStreams] + + if {$multipleStreams} { + set multipleStreams increment + } else { + set multipleStreams singleValue + } + + set fastConvergence True + set convergenceDuration [expr $duration/10] + + # traffic spec + + # extract nested dictionaries + set trafficSpec_l2 [dict get $trafficSpec l2] + set trafficSpec_l3 [dict get $trafficSpec l3] + set trafficSpec_vlan [dict get $trafficSpec vlan] + + set frameSize [dict get $trafficSpec_l2 framesize] + set srcMac [dict get $trafficSpec_l2 srcmac] + set dstMac [dict get $trafficSpec_l2 dstmac] + set srcPort [dict get $trafficSpec_l2 srcport] + set dstPort [dict get $trafficSpec_l2 dstport] + + set proto [dict get $trafficSpec_l3 proto] + set srcIp [dict get $trafficSpec_l3 srcip] + set dstIp [dict get $trafficSpec_l3 dstip] + + + if {$frameSize < 68 } { + if {$rfc2544TestType == "back2back"} { + puts "WARNING: Packet size too small, packet size will be \ + increased to 68 for this test" + } + } + # constants + + set VERSION [package require IxTclNetwork] + + ################################################################### + ############################ Operation ############################ + ################################################################### + + puts "Connecting to IxNetwork machine..." + + ixNet connect $::IxNserver -port $::IxNport -version $VERSION + + puts "Connected to IxNetwork machine" + + puts "Configuring IxNetwork machine..." + + set ::_sg_cc 0 + proc sg_commit {} {ixNet commit} + + ixNet rollback + ixNet setSessionParameter version 6.30.701.16 + ixNet execute newConfig + set ixNetSG_Stack(0) [ixNet getRoot] + + # + # setting global options + # + set sg_top [ixNet getRoot] + ixNet setMultiAttrs $sg_top/availableHardware \ + -offChassisHwM {} \ + -isOffChassis False + ixNet setMultiAttrs $sg_top/globals/preferences \ + -connectPortsOnLoadConfig True \ + -rebootPortsOnConnect False + ixNet setMultiAttrs $sg_top/globals/interfaces \ + -arpOnLinkup True \ + -nsOnLinkup True \ + -sendSingleArpPerGateway True \ + -sendSingleNsPerGateway True + ixNet setMultiAttrs $sg_top/impairment/defaultProfile/checksums \ + -dropRxL2FcsErrors False \ + -correctTxL2FcsErrors False \ + -alwaysCorrectWhenModifying True \ + -correctTxChecksumOverIp False \ + -correctTxIpv4Checksum False + ixNet setMultiAttrs $sg_top/impairment/defaultProfile/rxRateLimit \ + -enabled False \ + -value 8 \ + -units {kKilobitsPerSecond} + ixNet setMultiAttrs $sg_top/impairment/defaultProfile/drop \ + -enabled False \ + -clusterSize 1 \ + -percentRate 0 + ixNet setMultiAttrs $sg_top/impairment/defaultProfile/reorder \ + -enabled False \ + -clusterSize 1 \ + -percentRate 0 \ + -skipCount 1 + ixNet setMultiAttrs $sg_top/impairment/defaultProfile/duplicate \ + -enabled False \ + -clusterSize 1 \ + -percentRate 0 \ + -duplicateCount 1 + ixNet setMultiAttrs $sg_top/impairment/defaultProfile/bitError \ + -enabled False \ + -logRate 3 \ + -skipEndOctets 0 \ + -skipStartOctets 0 + ixNet setMultiAttrs $sg_top/impairment/defaultProfile/delay \ + -enabled False \ + -value 300 \ + -units {kMicroseconds} + ixNet setMultiAttrs $sg_top/impairment/defaultProfile/delayVariation \ + -uniformSpread 0 \ + -enabled False \ + -units {kMicroseconds} \ + -distribution {kUniform} \ + -exponentialMeanArrival 0 \ + -gaussianStandardDeviation 0 + ixNet setMultiAttrs $sg_top/impairment/defaultProfile/customDelayVariation \ + -enabled False \ + -name {} + ixNet setMultiAttrs $sg_top/statistics \ + -additionalFcoeStat2 fcoeInvalidFrames \ + -csvLogPollIntervalMultiplier 1 \ + -pollInterval 2 \ + -guardrailEnabled True \ + -enableCsvLogging False \ + -dataStorePollingIntervalMultiplier 1 \ + -maxNumberOfStatsPerCustomGraph 16 \ + -additionalFcoeStat1 fcoeInvalidDelimiter \ + -timestampPrecision 3 \ + -enableDataCenterSharedStats False \ + -timeSynchronization syncTimeToTestStart \ + -enableAutoDataStore False + ixNet setMultiAttrs $sg_top/statistics/measurementMode \ + -measurementMode mixedMode + ixNet setMultiAttrs $sg_top/eventScheduler \ + -licenseServerLocation {127.0.0.1} + ixNet setMultiAttrs $sg_top/traffic \ + -destMacRetryCount 1 \ + -maxTrafficGenerationQueries 500 \ + -enableStaggeredTransmit False \ + -learningFrameSize 64 \ + -useTxRxSync True \ + -enableDestMacRetry True \ + -enableMulticastScalingFactor False \ + -destMacRetryDelay 5 \ + -largeErrorThreshhold 2 \ + -refreshLearnedInfoBeforeApply False \ + -enableMinFrameSize False \ + -macChangeOnFly False \ + -waitTime 1 \ + -enableInstantaneousStatsSupport False \ + -learningFramesCount 10 \ + -globalStreamControl continuous \ + -displayMplsCurrentLabelValue False \ + -mplsLabelLearningTimeout 30 \ + -enableStaggeredStartDelay True \ + -enableDataIntegrityCheck False \ + -enableSequenceChecking False \ + -globalStreamControlIterations 1 \ + -enableStreamOrdering False \ + -frameOrderingMode none \ + -learningFramesRate 100 + ixNet setMultiAttrs $sg_top/traffic/statistics/latency \ + -enabled True \ + -mode storeForward + ixNet setMultiAttrs $sg_top/traffic/statistics/interArrivalTimeRate \ + -enabled False + ixNet setMultiAttrs $sg_top/traffic/statistics/delayVariation \ + -enabled False \ + -statisticsMode rxDelayVariationErrorsAndRate \ + -latencyMode storeForward \ + -largeSequenceNumberErrorThreshold 2 + ixNet setMultiAttrs $sg_top/traffic/statistics/sequenceChecking \ + -enabled False \ + -sequenceMode rxThreshold + ixNet setMultiAttrs $sg_top/traffic/statistics/advancedSequenceChecking \ + -enabled False \ + -advancedSequenceThreshold 1 + ixNet setMultiAttrs $sg_top/traffic/statistics/cpdpConvergence \ + -enabled False \ + -dataPlaneJitterWindow 10485760 \ + -dataPlaneThreshold 95 \ + -enableDataPlaneEventsRateMonitor False \ + -enableControlPlaneEvents False + ixNet setMultiAttrs $sg_top/traffic/statistics/packetLossDuration \ + -enabled False + ixNet setMultiAttrs $sg_top/traffic/statistics/dataIntegrity \ + -enabled False + ixNet setMultiAttrs $sg_top/traffic/statistics/errorStats \ + -enabled False + ixNet setMultiAttrs $sg_top/traffic/statistics/prbs \ + -enabled False + ixNet setMultiAttrs $sg_top/traffic/statistics/iptv \ + -enabled False + ixNet setMultiAttrs $sg_top/traffic/statistics/l1Rates \ + -enabled False + ixNet setMultiAttrs $sg_top/quickTest/globals \ + -productLabel {Your switch/router name here} \ + -serialNumber {Your switch/router serial number here} \ + -version {Your firmware version here} \ + -comments {} \ + -titlePageComments {} \ + -maxLinesToDisplay 100 \ + -enableCheckLinkState False \ + -enableAbortIfLinkDown False \ + -enableSwitchToStats True \ + -enableCapture False \ + -enableSwitchToResult True \ + -enableGenerateReportAfterRun False \ + -enableRebootCpu False \ + -saveCaptureBeforeRun False \ + -linkDownTimeout 5 \ + -sleepTimeAfterReboot 10 \ + -useDefaultRootPath False \ + -outputRootPath $::output_dir + sg_commit + set sg_top [lindex [ixNet remapIds $sg_top] 0] + set ixNetSG_Stack(0) $sg_top + + ### + ### /vport area + ### + + # + # configuring the object that corresponds to /vport:1 + # + set sg_vport [ixNet add $ixNetSG_Stack(0) vport] + ixNet setMultiAttrs $sg_vport \ + -transmitIgnoreLinkStatus False \ + -txGapControlMode averageMode \ + -type tenGigLan \ + -connectedTo ::ixNet::OBJ-null \ + -txMode interleaved \ + -isPullOnly False \ + -rxMode captureAndMeasure \ + -name {10GE LAN - 001} + ixNet setMultiAttrs $sg_vport/l1Config \ + -currentType tenGigLan + ixNet setMultiAttrs $sg_vport/l1Config/tenGigLan \ + -ppm 0 \ + -flowControlDirectedAddress "01 80 C2 00 00 01" \ + -enablePPM False \ + -autoInstrumentation endOfFrame \ + -transmitClocking internal \ + -txIgnoreRxLinkFaults False \ + -loopback False \ + -enableLASIMonitoring False \ + -enabledFlowControl True + ixNet setMultiAttrs $sg_vport/l1Config/tenGigLan/oam \ + -tlvType {00} \ + -linkEvents False \ + -enabled False \ + -vendorSpecificInformation {00 00 00 00} \ + -macAddress "00:00:00:00:00:00" \ + -loopback False \ + -idleTimer 5 \ + -tlvValue {00} \ + -enableTlvOption False \ + -maxOAMPDUSize 64 \ + -organizationUniqueIdentifier {000000} + ixNet setMultiAttrs $sg_vport/l1Config/tenGigLan/fcoe \ + -supportDataCenterMode False \ + -priorityGroupSize priorityGroupSize-8 \ + -pfcPauseDelay 1 \ + -pfcPriorityGroups {0 1 2 3 4 5 6 7} \ + -flowControlType ieee802.1Qbb \ + -enablePFCPauseDelay False + ixNet setMultiAttrs $sg_vport/l1Config/fortyGigLan \ + -ppm 0 \ + -flowControlDirectedAddress "01 80 C2 00 00 01" \ + -enablePPM False \ + -autoInstrumentation endOfFrame \ + -transmitClocking internal \ + -txIgnoreRxLinkFaults False \ + -loopback False \ + -enableLASIMonitoring False \ + -enabledFlowControl False + ixNet setMultiAttrs $sg_vport/l1Config/fortyGigLan/fcoe \ + -supportDataCenterMode False \ + -priorityGroupSize priorityGroupSize-8 \ + -pfcPauseDelay 1 \ + -pfcPriorityGroups {0 1 2 3 4 5 6 7} \ + -flowControlType ieee802.1Qbb \ + -enablePFCPauseDelay False + ixNet setMultiAttrs $sg_vport/l1Config/OAM \ + -tlvType {00} \ + -linkEvents False \ + -enabled False \ + -vendorSpecificInformation {00 00 00 00} \ + -macAddress "00:00:00:00:00:00" \ + -loopback False \ + -idleTimer 5 \ + -tlvValue {00} \ + -enableTlvOption False \ + -maxOAMPDUSize 64 \ + -organizationUniqueIdentifier {000000} + ixNet setMultiAttrs $sg_vport/l1Config/rxFilters/filterPalette \ + -sourceAddress1Mask {00:00:00:00:00:00} \ + -destinationAddress1Mask {00:00:00:00:00:00} \ + -sourceAddress2 {00:00:00:00:00:00} \ + -pattern2OffsetType fromStartOfFrame \ + -pattern2Offset 20 \ + -pattern1Mask {00} \ + -sourceAddress2Mask {00:00:00:00:00:00} \ + -destinationAddress2 {00:00:00:00:00:00} \ + -destinationAddress1 {00:00:00:00:00:00} \ + -sourceAddress1 {00:00:00:00:00:00} \ + -pattern1 {00} \ + -destinationAddress2Mask {00:00:00:00:00:00} \ + -pattern2Mask {00} \ + -pattern1Offset 20 \ + -pattern2 {00} \ + -pattern1OffsetType fromStartOfFrame + ixNet setMultiAttrs $sg_vport/protocols/arp \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/bfd \ + -enabled False \ + -intervalValue 0 \ + -packetsPerInterval 0 + ixNet setMultiAttrs $sg_vport/protocols/bgp \ + -autoFillUpDutIp False \ + -disableReceivedUpdateValidation False \ + -enableAdVplsPrefixLengthInBits False \ + -enableExternalActiveConnect True \ + -enableInternalActiveConnect True \ + -enableVpnLabelExchangeOverLsp True \ + -enabled False \ + -externalRetries 0 \ + -externalRetryDelay 120 \ + -internalRetries 0 \ + -internalRetryDelay 120 \ + -mldpP2mpFecType 6 \ + -triggerVplsPwInitiation False + ixNet setMultiAttrs $sg_vport/protocols/cfm \ + -enableOptionalLmFunctionality False \ + -enableOptionalTlvValidation True \ + -enabled False \ + -receiveCcm True \ + -sendCcm True \ + -suppressErrorsOnAis True + ixNet setMultiAttrs $sg_vport/protocols/eigrp \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/elmi \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/igmp \ + -enabled False \ + -numberOfGroups 0 \ + -numberOfQueries 0 \ + -queryTimePeriod 0 \ + -sendLeaveOnStop True \ + -statsEnabled False \ + -timePeriod 0 + ixNet setMultiAttrs $sg_vport/protocols/isis \ + -allL1RbridgesMac "01:80:c2:00:00:40" \ + -emulationType isisL3Routing \ + -enabled False \ + -helloMulticastMac "01:80:c2:00:00:41" \ + -lspMgroupPdusPerInterval 0 \ + -nlpId 192 \ + -rateControlInterval 0 \ + -sendP2PHellosToUnicastMac True \ + -spbAllL1BridgesMac "09:00:2b:00:00:05" \ + -spbHelloMulticastMac "09:00:2b:00:00:05" \ + -spbNlpId 192 + ixNet setMultiAttrs $sg_vport/protocols/lacp \ + -enablePreservePartnerInfo False \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/ldp \ + -enableDiscardSelfAdvFecs False \ + -enableHelloJitter True \ + -enableVpnLabelExchangeOverLsp True \ + -enabled False \ + -helloHoldTime 15 \ + -helloInterval 5 \ + -keepAliveHoldTime 30 \ + -keepAliveInterval 10 \ + -p2mpCapabilityParam 1288 \ + -p2mpFecType 6 \ + -targetedHelloInterval 15 \ + -targetedHoldTime 45 \ + -useTransportLabelsForMplsOam False + ixNet setMultiAttrs $sg_vport/protocols/linkOam \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/lisp \ + -burstIntervalInMs 0 \ + -enabled False \ + -ipv4MapRegisterPacketsPerBurst 0 \ + -ipv4MapRequestPacketsPerBurst 0 \ + -ipv4SmrPacketsPerBurst 0 \ + -ipv6MapRegisterPacketsPerBurst 0 \ + -ipv6MapRequestPacketsPerBurst 0 \ + -ipv6SmrPacketsPerBurst 0 + ixNet setMultiAttrs $sg_vport/protocols/mld \ + -enableDoneOnStop True \ + -enabled False \ + -mldv2Report type143 \ + -numberOfGroups 0 \ + -numberOfQueries 0 \ + -queryTimePeriod 0 \ + -timePeriod 0 + ixNet setMultiAttrs $sg_vport/protocols/mplsOam \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/mplsTp \ + -apsChannelType {00 02 } \ + -bfdCcChannelType {00 07 } \ + -delayManagementChannelType {00 05 } \ + -enableHighPerformanceMode True \ + -enabled False \ + -faultManagementChannelType {00 58 } \ + -lossMeasurementChannelType {00 04 } \ + -onDemandCvChannelType {00 09 } \ + -pwStatusChannelType {00 0B } \ + -y1731ChannelType {7F FA } + ixNet setMultiAttrs $sg_vport/protocols/ospf \ + -enableDrOrBdr False \ + -enabled False \ + -floodLinkStateUpdatesPerInterval 0 \ + -rateControlInterval 0 + ixNet setMultiAttrs $sg_vport/protocols/ospfV3 \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/pimsm \ + -bsmFramePerInterval 0 \ + -crpFramePerInterval 0 \ + -dataMdtFramePerInterval 0 \ + -denyGrePimIpPrefix {0.0.0.0/32} \ + -enableDiscardJoinPruneProcessing False \ + -enableRateControl False \ + -enabled False \ + -helloMsgsPerInterval 0 \ + -interval 0 \ + -joinPruneMessagesPerInterval 0 \ + -registerMessagesPerInterval 0 \ + -registerStopMessagesPerInterval 0 + ixNet setMultiAttrs $sg_vport/protocols/ping \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/rip \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/ripng \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/rsvp \ + -enableControlLspInitiationRate False \ + -enableShowTimeValue False \ + -enableVpnLabelExchangeOverLsp True \ + -enabled False \ + -maxLspInitiationsPerSec 400 \ + -useTransportLabelsForMplsOam False + ixNet setMultiAttrs $sg_vport/protocols/stp \ + -enabled False + ixNet setMultiAttrs $sg_vport/rateControlParameters \ + -maxRequestsPerBurst 1 \ + -maxRequestsPerSec 250 \ + -minRetryInterval 10 \ + -retryCount 3 \ + -sendInBursts False \ + -sendRequestsAsFastAsPossible False + ixNet setMultiAttrs $sg_vport/capture \ + -controlCaptureTrigger {} \ + -controlCaptureFilter {} \ + -hardwareEnabled False \ + -softwareEnabled False \ + -displayFiltersDataCapture {} \ + -displayFiltersControlCapture {} \ + -controlBufferSize 30 \ + -controlBufferBehaviour bufferLiveNonCircular + ixNet setMultiAttrs $sg_vport/protocolStack/options \ + -routerSolicitationDelay 1 \ + -routerSolicitationInterval 4 \ + -routerSolicitations 3 \ + -retransTime 1000 \ + -dadTransmits 1 \ + -dadEnabled True \ + -ipv4RetransTime 3000 \ + -ipv4McastSolicit 4 + sg_commit + set sg_vport [lindex [ixNet remapIds $sg_vport] 0] + set ixNetSG_ref(2) $sg_vport + set ixNetSG_Stack(1) $sg_vport + + # + # configuring the object that corresponds to /vport:1/l1Config/rxFilters/uds:1 + # + set sg_uds $ixNetSG_Stack(1)/l1Config/rxFilters/uds:1 + ixNet setMultiAttrs $sg_uds \ + -destinationAddressSelector anyAddr \ + -customFrameSizeTo 0 \ + -customFrameSizeFrom 0 \ + -error errAnyFrame \ + -patternSelector anyPattern \ + -sourceAddressSelector anyAddr \ + -isEnabled True \ + -frameSizeType any + sg_commit + set sg_uds [lindex [ixNet remapIds $sg_uds] 0] + + # + # configuring the object that corresponds to /vport:1/l1Config/rxFilters/uds:2 + # + set sg_uds $ixNetSG_Stack(1)/l1Config/rxFilters/uds:2 + ixNet setMultiAttrs $sg_uds \ + -destinationAddressSelector anyAddr \ + -customFrameSizeTo 0 \ + -customFrameSizeFrom 0 \ + -error errAnyFrame \ + -patternSelector anyPattern \ + -sourceAddressSelector anyAddr \ + -isEnabled True \ + -frameSizeType any + sg_commit + set sg_uds [lindex [ixNet remapIds $sg_uds] 0] + + # + # configuring the object that corresponds to /vport:1/l1Config/rxFilters/uds:3 + # + set sg_uds $ixNetSG_Stack(1)/l1Config/rxFilters/uds:3 + ixNet setMultiAttrs $sg_uds \ + -destinationAddressSelector anyAddr \ + -customFrameSizeTo 0 \ + -customFrameSizeFrom 0 \ + -error errAnyFrame \ + -patternSelector anyPattern \ + -sourceAddressSelector anyAddr \ + -isEnabled True \ + -frameSizeType any + sg_commit + set sg_uds [lindex [ixNet remapIds $sg_uds] 0] + + # + # configuring the object that corresponds to /vport:1/l1Config/rxFilters/uds:4 + # + set sg_uds $ixNetSG_Stack(1)/l1Config/rxFilters/uds:4 + ixNet setMultiAttrs $sg_uds \ + -destinationAddressSelector anyAddr \ + -customFrameSizeTo 0 \ + -customFrameSizeFrom 0 \ + -error errAnyFrame \ + -patternSelector anyPattern \ + -sourceAddressSelector anyAddr \ + -isEnabled True \ + -frameSizeType any + sg_commit + set sg_uds [lindex [ixNet remapIds $sg_uds] 0] + + # + # configuring the object that corresponds to /vport:1/l1Config/rxFilters/uds:5 + # + set sg_uds $ixNetSG_Stack(1)/l1Config/rxFilters/uds:5 + ixNet setMultiAttrs $sg_uds \ + -destinationAddressSelector anyAddr \ + -customFrameSizeTo 0 \ + -customFrameSizeFrom 0 \ + -error errAnyFrame \ + -patternSelector anyPattern \ + -sourceAddressSelector anyAddr \ + -isEnabled True \ + -frameSizeType any + sg_commit + set sg_uds [lindex [ixNet remapIds $sg_uds] 0] + + # + # configuring the object that corresponds to /vport:1/l1Config/rxFilters/uds:6 + # + set sg_uds $ixNetSG_Stack(1)/l1Config/rxFilters/uds:6 + ixNet setMultiAttrs $sg_uds \ + -destinationAddressSelector anyAddr \ + -customFrameSizeTo 0 \ + -customFrameSizeFrom 0 \ + -error errAnyFrame \ + -patternSelector anyPattern \ + -sourceAddressSelector anyAddr \ + -isEnabled True \ + -frameSizeType any + sg_commit + set sg_uds [lindex [ixNet remapIds $sg_uds] 0] + + # + # configuring the object that corresponds to /vport:1/protocols/static/lan:1 + # + set sg_lan [ixNet add $ixNetSG_Stack(1)/protocols/static lan] + ixNet setMultiAttrs $sg_lan \ + -atmEncapsulation ::ixNet::OBJ-null \ + -count 1 \ + -countPerVc 1 \ + -enableIncrementMac False \ + -enableIncrementVlan False \ + -enableSiteId False \ + -enableVlan False \ + -enabled True \ + -frEncapsulation ::ixNet::OBJ-null \ + -incrementPerVcVlanMode noIncrement \ + -incrementVlanMode noIncrement \ + -mac "00:00:00:00:00:01" \ + -macRangeMode normal \ + -numberOfVcs 1 \ + -siteId 0 \ + -skipVlanIdZero True \ + -tpid {0x8100} \ + -trafficGroupId ::ixNet::OBJ-null \ + -vlanCount 1 \ + -vlanId {1} \ + -vlanPriority {0} + sg_commit + set sg_lan [lindex [ixNet remapIds $sg_lan] 0] + + # + # configuring the object that corresponds to /vport:2 + # + set sg_vport [ixNet add $ixNetSG_Stack(0) vport] + ixNet setMultiAttrs $sg_vport \ + -transmitIgnoreLinkStatus False \ + -txGapControlMode averageMode \ + -type tenGigLan \ + -connectedTo ::ixNet::OBJ-null \ + -txMode interleaved \ + -isPullOnly False \ + -rxMode captureAndMeasure \ + -name {10GE LAN - 002} + ixNet setMultiAttrs $sg_vport/l1Config \ + -currentType tenGigLan + ixNet setMultiAttrs $sg_vport/l1Config/tenGigLan \ + -ppm 0 \ + -flowControlDirectedAddress "01 80 C2 00 00 01" \ + -enablePPM False \ + -autoInstrumentation endOfFrame \ + -transmitClocking internal \ + -txIgnoreRxLinkFaults False \ + -loopback False \ + -enableLASIMonitoring False \ + -enabledFlowControl False + ixNet setMultiAttrs $sg_vport/l1Config/tenGigLan/oam \ + -tlvType {00} \ + -linkEvents False \ + -enabled False \ + -vendorSpecificInformation {00 00 00 00} \ + -macAddress "00:00:00:00:00:00" \ + -loopback False \ + -idleTimer 5 \ + -tlvValue {00} \ + -enableTlvOption False \ + -maxOAMPDUSize 64 \ + -organizationUniqueIdentifier {000000} + ixNet setMultiAttrs $sg_vport/l1Config/tenGigLan/fcoe \ + -supportDataCenterMode False \ + -priorityGroupSize priorityGroupSize-8 \ + -pfcPauseDelay 1 \ + -pfcPriorityGroups {0 1 2 3 4 5 6 7} \ + -flowControlType ieee802.1Qbb \ + -enablePFCPauseDelay False + ixNet setMultiAttrs $sg_vport/l1Config/fortyGigLan \ + -ppm 0 \ + -flowControlDirectedAddress "01 80 C2 00 00 01" \ + -enablePPM False \ + -autoInstrumentation endOfFrame \ + -transmitClocking internal \ + -txIgnoreRxLinkFaults False \ + -loopback False \ + -enableLASIMonitoring False \ + -enabledFlowControl False + ixNet setMultiAttrs $sg_vport/l1Config/fortyGigLan/fcoe \ + -supportDataCenterMode False \ + -priorityGroupSize priorityGroupSize-8 \ + -pfcPauseDelay 1 \ + -pfcPriorityGroups {0 1 2 3 4 5 6 7} \ + -flowControlType ieee802.1Qbb \ + -enablePFCPauseDelay False + ixNet setMultiAttrs $sg_vport/l1Config/OAM \ + -tlvType {00} \ + -linkEvents False \ + -enabled False \ + -vendorSpecificInformation {00 00 00 00} \ + -macAddress "00:00:00:00:00:00" \ + -loopback False \ + -idleTimer 5 \ + -tlvValue {00} \ + -enableTlvOption False \ + -maxOAMPDUSize 64 \ + -organizationUniqueIdentifier {000000} + ixNet setMultiAttrs $sg_vport/l1Config/rxFilters/filterPalette \ + -sourceAddress1Mask {00:00:00:00:00:00} \ + -destinationAddress1Mask {00:00:00:00:00:00} \ + -sourceAddress2 {00:00:00:00:00:00} \ + -pattern2OffsetType fromStartOfFrame \ + -pattern2Offset 20 \ + -pattern1Mask {00} \ + -sourceAddress2Mask {00:00:00:00:00:00} \ + -destinationAddress2 {00:00:00:00:00:00} \ + -destinationAddress1 {00:00:00:00:00:00} \ + -sourceAddress1 {00:00:00:00:00:00} \ + -pattern1 {00} \ + -destinationAddress2Mask {00:00:00:00:00:00} \ + -pattern2Mask {00} \ + -pattern1Offset 20 \ + -pattern2 {00} \ + -pattern1OffsetType fromStartOfFrame + ixNet setMultiAttrs $sg_vport/protocols/arp \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/bfd \ + -enabled False \ + -intervalValue 0 \ + -packetsPerInterval 0 + ixNet setMultiAttrs $sg_vport/protocols/bgp \ + -autoFillUpDutIp False \ + -disableReceivedUpdateValidation False \ + -enableAdVplsPrefixLengthInBits False \ + -enableExternalActiveConnect True \ + -enableInternalActiveConnect True \ + -enableVpnLabelExchangeOverLsp True \ + -enabled False \ + -externalRetries 0 \ + -externalRetryDelay 120 \ + -internalRetries 0 \ + -internalRetryDelay 120 \ + -mldpP2mpFecType 6 \ + -triggerVplsPwInitiation False + ixNet setMultiAttrs $sg_vport/protocols/cfm \ + -enableOptionalLmFunctionality False \ + -enableOptionalTlvValidation True \ + -enabled False \ + -receiveCcm True \ + -sendCcm True \ + -suppressErrorsOnAis True + ixNet setMultiAttrs $sg_vport/protocols/eigrp \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/elmi \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/igmp \ + -enabled False \ + -numberOfGroups 0 \ + -numberOfQueries 0 \ + -queryTimePeriod 0 \ + -sendLeaveOnStop True \ + -statsEnabled False \ + -timePeriod 0 + ixNet setMultiAttrs $sg_vport/protocols/isis \ + -allL1RbridgesMac "01:80:c2:00:00:40" \ + -emulationType isisL3Routing \ + -enabled False \ + -helloMulticastMac "01:80:c2:00:00:41" \ + -lspMgroupPdusPerInterval 0 \ + -nlpId 192 \ + -rateControlInterval 0 \ + -sendP2PHellosToUnicastMac True \ + -spbAllL1BridgesMac "09:00:2b:00:00:05" \ + -spbHelloMulticastMac "09:00:2b:00:00:05" \ + -spbNlpId 192 + ixNet setMultiAttrs $sg_vport/protocols/lacp \ + -enablePreservePartnerInfo False \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/ldp \ + -enableDiscardSelfAdvFecs False \ + -enableHelloJitter True \ + -enableVpnLabelExchangeOverLsp True \ + -enabled False \ + -helloHoldTime 15 \ + -helloInterval 5 \ + -keepAliveHoldTime 30 \ + -keepAliveInterval 10 \ + -p2mpCapabilityParam 1288 \ + -p2mpFecType 6 \ + -targetedHelloInterval 15 \ + -targetedHoldTime 45 \ + -useTransportLabelsForMplsOam False + ixNet setMultiAttrs $sg_vport/protocols/linkOam \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/lisp \ + -burstIntervalInMs 0 \ + -enabled False \ + -ipv4MapRegisterPacketsPerBurst 0 \ + -ipv4MapRequestPacketsPerBurst 0 \ + -ipv4SmrPacketsPerBurst 0 \ + -ipv6MapRegisterPacketsPerBurst 0 \ + -ipv6MapRequestPacketsPerBurst 0 \ + -ipv6SmrPacketsPerBurst 0 + ixNet setMultiAttrs $sg_vport/protocols/mld \ + -enableDoneOnStop True \ + -enabled False \ + -mldv2Report type143 \ + -numberOfGroups 0 \ + -numberOfQueries 0 \ + -queryTimePeriod 0 \ + -timePeriod 0 + ixNet setMultiAttrs $sg_vport/protocols/mplsOam \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/mplsTp \ + -apsChannelType {00 02 } \ + -bfdCcChannelType {00 07 } \ + -delayManagementChannelType {00 05 } \ + -enableHighPerformanceMode True \ + -enabled False \ + -faultManagementChannelType {00 58 } \ + -lossMeasurementChannelType {00 04 } \ + -onDemandCvChannelType {00 09 } \ + -pwStatusChannelType {00 0B } \ + -y1731ChannelType {7F FA } + ixNet setMultiAttrs $sg_vport/protocols/ospf \ + -enableDrOrBdr False \ + -enabled False \ + -floodLinkStateUpdatesPerInterval 0 \ + -rateControlInterval 0 + ixNet setMultiAttrs $sg_vport/protocols/ospfV3 \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/pimsm \ + -bsmFramePerInterval 0 \ + -crpFramePerInterval 0 \ + -dataMdtFramePerInterval 0 \ + -denyGrePimIpPrefix {0.0.0.0/32} \ + -enableDiscardJoinPruneProcessing False \ + -enableRateControl False \ + -enabled False \ + -helloMsgsPerInterval 0 \ + -interval 0 \ + -joinPruneMessagesPerInterval 0 \ + -registerMessagesPerInterval 0 \ + -registerStopMessagesPerInterval 0 + ixNet setMultiAttrs $sg_vport/protocols/ping \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/rip \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/ripng \ + -enabled False + ixNet setMultiAttrs $sg_vport/protocols/rsvp \ + -enableControlLspInitiationRate False \ + -enableShowTimeValue False \ + -enableVpnLabelExchangeOverLsp True \ + -enabled False \ + -maxLspInitiationsPerSec 400 \ + -useTransportLabelsForMplsOam False + ixNet setMultiAttrs $sg_vport/protocols/stp \ + -enabled False + ixNet setMultiAttrs $sg_vport/rateControlParameters \ + -maxRequestsPerBurst 1 \ + -maxRequestsPerSec 250 \ + -minRetryInterval 10 \ + -retryCount 3 \ + -sendInBursts False \ + -sendRequestsAsFastAsPossible False + ixNet setMultiAttrs $sg_vport/capture \ + -controlCaptureTrigger {} \ + -controlCaptureFilter {} \ + -hardwareEnabled False \ + -softwareEnabled False \ + -displayFiltersDataCapture {} \ + -displayFiltersControlCapture {} \ + -controlBufferSize 30 \ + -controlBufferBehaviour bufferLiveNonCircular + ixNet setMultiAttrs $sg_vport/protocolStack/options \ + -routerSolicitationDelay 1 \ + -routerSolicitationInterval 4 \ + -routerSolicitations 3 \ + -retransTime 1000 \ + -dadTransmits 1 \ + -dadEnabled True \ + -ipv4RetransTime 3000 \ + -ipv4McastSolicit 4 + sg_commit + set sg_vport [lindex [ixNet remapIds $sg_vport] 0] + set ixNetSG_ref(10) $sg_vport + set ixNetSG_Stack(1) $sg_vport + + # + # configuring the object that corresponds to /vport:2/l1Config/rxFilters/uds:1 + # + set sg_uds $ixNetSG_Stack(1)/l1Config/rxFilters/uds:1 + ixNet setMultiAttrs $sg_uds \ + -destinationAddressSelector anyAddr \ + -customFrameSizeTo 0 \ + -customFrameSizeFrom 0 \ + -error errAnyFrame \ + -patternSelector anyPattern \ + -sourceAddressSelector anyAddr \ + -isEnabled True \ + -frameSizeType any + sg_commit + set sg_uds [lindex [ixNet remapIds $sg_uds] 0] + + # + # configuring the object that corresponds to /vport:2/l1Config/rxFilters/uds:2 + # + set sg_uds $ixNetSG_Stack(1)/l1Config/rxFilters/uds:2 + ixNet setMultiAttrs $sg_uds \ + -destinationAddressSelector anyAddr \ + -customFrameSizeTo 0 \ + -customFrameSizeFrom 0 \ + -error errAnyFrame \ + -patternSelector anyPattern \ + -sourceAddressSelector anyAddr \ + -isEnabled True \ + -frameSizeType any + sg_commit + set sg_uds [lindex [ixNet remapIds $sg_uds] 0] + + # + # configuring the object that corresponds to /vport:2/l1Config/rxFilters/uds:3 + # + set sg_uds $ixNetSG_Stack(1)/l1Config/rxFilters/uds:3 + ixNet setMultiAttrs $sg_uds \ + -destinationAddressSelector anyAddr \ + -customFrameSizeTo 0 \ + -customFrameSizeFrom 0 \ + -error errAnyFrame \ + -patternSelector anyPattern \ + -sourceAddressSelector anyAddr \ + -isEnabled True \ + -frameSizeType any + sg_commit + set sg_uds [lindex [ixNet remapIds $sg_uds] 0] + + # + # configuring the object that corresponds to /vport:2/l1Config/rxFilters/uds:4 + # + set sg_uds $ixNetSG_Stack(1)/l1Config/rxFilters/uds:4 + ixNet setMultiAttrs $sg_uds \ + -destinationAddressSelector anyAddr \ + -customFrameSizeTo 0 \ + -customFrameSizeFrom 0 \ + -error errAnyFrame \ + -patternSelector anyPattern \ + -sourceAddressSelector anyAddr \ + -isEnabled True \ + -frameSizeType any + sg_commit + set sg_uds [lindex [ixNet remapIds $sg_uds] 0] + + # + # configuring the object that corresponds to /vport:2/l1Config/rxFilters/uds:5 + # + set sg_uds $ixNetSG_Stack(1)/l1Config/rxFilters/uds:5 + ixNet setMultiAttrs $sg_uds \ + -destinationAddressSelector anyAddr \ + -customFrameSizeTo 0 \ + -customFrameSizeFrom 0 \ + -error errAnyFrame \ + -patternSelector anyPattern \ + -sourceAddressSelector anyAddr \ + -isEnabled True \ + -frameSizeType any + sg_commit + set sg_uds [lindex [ixNet remapIds $sg_uds] 0] + + # + # configuring the object that corresponds to /vport:2/l1Config/rxFilters/uds:6 + # + set sg_uds $ixNetSG_Stack(1)/l1Config/rxFilters/uds:6 + ixNet setMultiAttrs $sg_uds \ + -destinationAddressSelector anyAddr \ + -customFrameSizeTo 0 \ + -customFrameSizeFrom 0 \ + -error errAnyFrame \ + -patternSelector anyPattern \ + -sourceAddressSelector anyAddr \ + -isEnabled True \ + -frameSizeType any + sg_commit + set sg_uds [lindex [ixNet remapIds $sg_uds] 0] + + # + # configuring the object that corresponds to /vport:2/protocols/static/lan:1 + # + set sg_lan [ixNet add $ixNetSG_Stack(1)/protocols/static lan] + ixNet setMultiAttrs $sg_lan \ + -atmEncapsulation ::ixNet::OBJ-null \ + -count 1 \ + -countPerVc 1 \ + -enableIncrementMac False \ + -enableIncrementVlan False \ + -enableSiteId False \ + -enableVlan False \ + -enabled True \ + -frEncapsulation ::ixNet::OBJ-null \ + -incrementPerVcVlanMode noIncrement \ + -incrementVlanMode noIncrement \ + -mac "00:01:00:05:08:00" \ + -macRangeMode normal \ + -numberOfVcs 1 \ + -siteId 0 \ + -skipVlanIdZero True \ + -tpid {0x8100} \ + -trafficGroupId ::ixNet::OBJ-null \ + -vlanCount 1 \ + -vlanId {1} \ + -vlanPriority {0} + sg_commit + set sg_lan [lindex [ixNet remapIds $sg_lan] 0] + + ### + ### /availableHardware area + ### + + # + # configuring the object that corresponds to /availableHardware/chassis" + # + set sg_chassis [ixNet add $ixNetSG_Stack(0)/availableHardware chassis] + ixNet setMultiAttrs $sg_chassis \ + -masterChassis {} \ + -sequenceId 1 \ + -cableLength 0 \ + -hostname $::chassis + sg_commit + set sg_chassis [lindex [ixNet remapIds $sg_chassis] 0] + set ixNetSG_Stack(1) $sg_chassis + + # + # configuring the object that corresponds to /availableHardware/chassis/card + # + set sg_card $ixNetSG_Stack(1)/card:$::card + ixNet setMultiAttrs $sg_card \ + -aggregationMode normal + sg_commit + set sg_card [lindex [ixNet remapIds $sg_card] 0] + set ixNetSG_ref(19) $sg_card + set ixNetSG_Stack(2) $sg_card + + # + # configuring the object that corresponds to /availableHardware/chassis/card/aggregation:1 + # + set sg_aggregation $ixNetSG_Stack(2)/aggregation:1 + ixNet setMultiAttrs $sg_aggregation \ + -mode normal + sg_commit + set sg_aggregation [lindex [ixNet remapIds $sg_aggregation] 0] + + # + # configuring the object that corresponds to /availableHardware/chassis/card/aggregation:2 + # + set sg_aggregation $ixNetSG_Stack(2)/aggregation:2 + ixNet setMultiAttrs $sg_aggregation \ + -mode normal + sg_commit + set sg_aggregation [lindex [ixNet remapIds $sg_aggregation] 0] + + # + # configuring the object that corresponds to /availableHardware/chassis/card/aggregation:3 + # + set sg_aggregation $ixNetSG_Stack(2)/aggregation:3 + ixNet setMultiAttrs $sg_aggregation \ + -mode normal + sg_commit + set sg_aggregation [lindex [ixNet remapIds $sg_aggregation] 0] + + # + # configuring the object that corresponds to /availableHardware/chassis/card/aggregation:4 + # + set sg_aggregation $ixNetSG_Stack(2)/aggregation:4 + ixNet setMultiAttrs $sg_aggregation \ + -mode normal + sg_commit + set sg_aggregation [lindex [ixNet remapIds $sg_aggregation] 0] + ixNet setMultiAttrs $ixNetSG_ref(2) \ + -connectedTo $ixNetSG_ref(19)/port:$::port1 + sg_commit + ixNet setMultiAttrs $ixNetSG_ref(10) \ + -connectedTo $ixNetSG_ref(19)/port:$::port2 + sg_commit + sg_commit + + ### + ### /impairment area + ### + + # + # configuring the object that corresponds to /impairment/profile:3 + # + set sg_profile [ixNet add $ixNetSG_Stack(0)/impairment profile] + ixNet setMultiAttrs $sg_profile \ + -enabled False \ + -name {Impairment Profile 1} \ + -links {} \ + -allLinks True \ + -priority 1 + ixNet setMultiAttrs $sg_profile/checksums \ + -dropRxL2FcsErrors False \ + -correctTxL2FcsErrors False \ + -alwaysCorrectWhenModifying True \ + -correctTxChecksumOverIp False \ + -correctTxIpv4Checksum False + ixNet setMultiAttrs $sg_profile/rxRateLimit \ + -enabled False \ + -value 8 \ + -units {kKilobitsPerSecond} + ixNet setMultiAttrs $sg_profile/drop \ + -enabled True \ + -clusterSize 1 \ + -percentRate 0 + ixNet setMultiAttrs $sg_profile/reorder \ + -enabled False \ + -clusterSize 1 \ + -percentRate 0 \ + -skipCount 1 + ixNet setMultiAttrs $sg_profile/duplicate \ + -enabled False \ + -clusterSize 1 \ + -percentRate 0 \ + -duplicateCount 1 + ixNet setMultiAttrs $sg_profile/bitError \ + -enabled False \ + -logRate 3 \ + -skipEndOctets 0 \ + -skipStartOctets 0 + ixNet setMultiAttrs $sg_profile/delay \ + -enabled True \ + -value 300 \ + -units {kMicroseconds} + ixNet setMultiAttrs $sg_profile/delayVariation \ + -uniformSpread 0 \ + -enabled False \ + -units {kMicroseconds} \ + -distribution {kUniform} \ + -exponentialMeanArrival 0 \ + -gaussianStandardDeviation 0 + ixNet setMultiAttrs $sg_profile/customDelayVariation \ + -enabled False \ + -name {} + sg_commit + set sg_profile [lindex [ixNet remapIds $sg_profile] 0] + set ixNetSG_Stack(1) $sg_profile + + # + # configuring the object that corresponds to /impairment/profile:3/fixedClassifier:1 + # + set sg_fixedClassifier [ixNet add $ixNetSG_Stack(1) fixedClassifier] + sg_commit + set sg_fixedClassifier [lindex [ixNet remapIds $sg_fixedClassifier] 0] + + ### + ### /traffic area + ### + + # + # configuring the object that corresponds to /traffic/trafficItem:1 + # + set sg_trafficItem [ixNet add $ixNetSG_Stack(0)/traffic trafficItem] + ixNet setMultiAttrs $sg_trafficItem \ + -transportRsvpTePreference one \ + -trafficItemType l2L3 \ + -biDirectional False \ + -mergeDestinations True \ + -hostsPerNetwork 1 \ + -transmitMode interleaved \ + -ordinalNo 0 \ + -trafficType {ethernetVlan} \ + -interAsLdpPreference two \ + -allowSelfDestined False \ + -enabled True \ + -maxNumberOfVpnLabelStack 2 \ + -interAsBgpPreference one \ + -suspend False \ + -transportLdpPreference two \ + -egressEnabled False \ + -enableDynamicMplsLabelValues False \ + -routeMesh oneToOne \ + -name {Traffic Item 1} \ + -srcDestMesh oneToOne + sg_commit + set sg_trafficItem [lindex [ixNet remapIds $sg_trafficItem] 0] + set ixNetSG_ref(26) $sg_trafficItem + set ixNetSG_Stack(1) $sg_trafficItem + + # + # configuring the object that corresponds to /traffic/trafficItem:1/endpointSet:1 + # + set sg_endpointSet [ixNet add $ixNetSG_Stack(1) endpointSet] + ixNet setMultiAttrs $sg_endpointSet \ + -destinations [list $ixNetSG_ref(10)/protocols] \ + -destinationFilter {} \ + -sourceFilter {} \ + -trafficGroups {} \ + -sources [list $ixNetSG_ref(2)/protocols] \ + -name {EndpointSet-1} + sg_commit + set sg_endpointSet [lindex [ixNet remapIds $sg_endpointSet] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1 + # + set sg_configElement $ixNetSG_Stack(1)/configElement:1 + ixNet setMultiAttrs $sg_configElement \ + -crc goodCrc \ + -preambleCustomSize 8 \ + -enableDisparityError False \ + -preambleFrameSizeMode auto \ + -destinationMacMode manual + ixNet setMultiAttrs $sg_configElement/frameSize \ + -weightedPairs {} \ + -fixedSize 64 \ + -incrementFrom 64 \ + -randomMin 64 \ + -randomMax 1518 \ + -quadGaussian {} \ + -type fixed \ + -presetDistribution cisco \ + -incrementStep 1 \ + -incrementTo 1518 + ixNet setMultiAttrs $sg_configElement/frameRate \ + -bitRateUnitsType bitsPerSec \ + -rate 10 \ + -enforceMinimumInterPacketGap 0 \ + -type percentLineRate \ + -interPacketGapUnitsType nanoseconds + ixNet setMultiAttrs $sg_configElement/framePayload \ + -type incrementByte \ + -customRepeat True \ + -customPattern {} + ixNet setMultiAttrs $sg_configElement/frameRateDistribution \ + -streamDistribution applyRateToAll \ + -portDistribution applyRateToAll + ixNet setMultiAttrs $sg_configElement/transmissionControl \ + -frameCount 1 \ + -minGapBytes 12 \ + -interStreamGap 0 \ + -interBurstGap 0 \ + -interBurstGapUnits nanoseconds \ + -type continuous \ + -duration 1 \ + -repeatBurst 1 \ + -enableInterStreamGap False \ + -startDelayUnits bytes \ + -iterationCount 1 \ + -burstPacketCount 1 \ + -enableInterBurstGap False \ + -startDelay 0 + sg_commit + set sg_configElement [lindex [ixNet remapIds $sg_configElement] 0] + set ixNetSG_Stack(2) $sg_configElement + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ethernet-1" + # + set sg_stack $ixNetSG_Stack(2)/stack:"ethernet-1" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ethernet-1"/field:"ethernet.header.destinationAddress-1" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.destinationAddress-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {00:00:00:00:00:00} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{00:00:00:00:00:00}} \ + -stepValue {00:00:00:00:00:00} \ + -fixedBits {00:00:00:00:00:00} \ + -fieldValue {00:00:00:00:00:00} \ + -auto False \ + -randomMask {00:00:00:00:00:00} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {00:00:00:00:00:00} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ethernet-1"/field:"ethernet.header.sourceAddress-2" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.sourceAddress-2" + ixNet setMultiAttrs $sg_field \ + -singleValue {00:00:00:00:00:00} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{00:00:00:00:00:00}} \ + -stepValue {00:00:00:00:00:00} \ + -fixedBits {00:00:00:00:00:00} \ + -fieldValue {00:00:00:00:00:00} \ + -auto False \ + -randomMask {00:00:00:00:00:00} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {00:00:00:00:00:00} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ethernet-1"/field:"ethernet.header.etherType-3" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.etherType-3" + ixNet setMultiAttrs $sg_field \ + -singleValue {800} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0xFFFF}} \ + -stepValue {0xFFFF} \ + -fixedBits {0xFFFF} \ + -fieldValue {800} \ + -auto True \ + -randomMask {0xFFFF} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0xFFFF} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ethernet-1"/field:"ethernet.header.pfcQueue-4" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.pfcQueue-4" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2" + # + set sg_stack $ixNetSG_Stack(2)/stack:"ipv4-2" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.version-1" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.version-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{4}} \ + -stepValue {4} \ + -fixedBits {4} \ + -fieldValue {4} \ + -auto False \ + -randomMask {4} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {4} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.headerLength-2" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.headerLength-2" + ixNet setMultiAttrs $sg_field \ + -singleValue {5} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {5} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.raw-3" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.raw-3" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.tos.precedence-4" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.precedence-4" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {000 Routine} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.tos.delay-5" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.delay-5" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.tos.throughput-6" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.throughput-6" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.tos.reliability-7" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.reliability-7" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.tos.monetary-8" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.monetary-8" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.tos.unused-9" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.unused-9" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.defaultPHB.defaultPHB-10" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.defaultPHB.defaultPHB-10" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.defaultPHB.unused-11" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.defaultPHB.unused-11" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.classSelectorPHB.classSelectorPHB-12" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.classSelectorPHB.classSelectorPHB-12" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {Precedence 1} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.classSelectorPHB.unused-13" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.classSelectorPHB.unused-13" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.assuredForwardingPHB-14" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.assuredForwardingPHB-14" + ixNet setMultiAttrs $sg_field \ + -singleValue {10} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{10}} \ + -stepValue {10} \ + -fixedBits {10} \ + -fieldValue {Class 1, Low drop precedence} \ + -auto False \ + -randomMask {10} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {10} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.unused-15" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.unused-15" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.expeditedForwardingPHB-16" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.expeditedForwardingPHB-16" + ixNet setMultiAttrs $sg_field \ + -singleValue {46} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{46}} \ + -stepValue {46} \ + -fixedBits {46} \ + -fieldValue {46} \ + -auto False \ + -randomMask {46} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {46} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.unused-17" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.unused-17" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.totalLength-18" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.totalLength-18" + ixNet setMultiAttrs $sg_field \ + -singleValue {46} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{20}} \ + -stepValue {20} \ + -fixedBits {20} \ + -fieldValue {46} \ + -auto True \ + -randomMask {20} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {20} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.identification-19" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.identification-19" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.flags.reserved-20" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.flags.reserved-20" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.flags.fragment-21" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.flags.fragment-21" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {May fragment} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.flags.lastFragment-22" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.flags.lastFragment-22" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Last fragment} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.fragmentOffset-23" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.fragmentOffset-23" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.ttl-24" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.ttl-24" + ixNet setMultiAttrs $sg_field \ + -singleValue {64} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{64}} \ + -stepValue {64} \ + -fixedBits {64} \ + -fieldValue {64} \ + -auto False \ + -randomMask {64} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {64} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.protocol-25" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.protocol-25" + ixNet setMultiAttrs $sg_field \ + -singleValue {17} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{61}} \ + -stepValue {61} \ + -fixedBits {61} \ + -fieldValue {UDP} \ + -auto True \ + -randomMask {61} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {61} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.checksum-26" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.checksum-26" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.srcIp-27" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.srcIp-27" + ixNet setMultiAttrs $sg_field \ + -singleValue {1.1.1.1} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0.0.0.0}} \ + -stepValue {0.0.0.0} \ + -fixedBits {0.0.0.0} \ + -fieldValue {1.1.1.1} \ + -auto False \ + -randomMask {0.0.0.0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0.0.0.0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.dstIp-28" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.dstIp-28" + ixNet setMultiAttrs $sg_field \ + -singleValue {90.90.90.90} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0.0.0.0}} \ + -stepValue {0.0.0.0} \ + -fixedBits {0.0.0.0} \ + -fieldValue {90.90.90.90} \ + -auto False \ + -randomMask {0.0.0.0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0.0.0.0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.nop-29" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.nop-29" + ixNet setMultiAttrs $sg_field \ + -singleValue {1} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{1}} \ + -stepValue {1} \ + -fixedBits {1} \ + -fieldValue {1} \ + -auto False \ + -randomMask {1} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {1} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.type-30" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.type-30" + ixNet setMultiAttrs $sg_field \ + -singleValue {130} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{130}} \ + -stepValue {130} \ + -fixedBits {130} \ + -fieldValue {130} \ + -auto False \ + -randomMask {130} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {130} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.length-31" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.length-31" + ixNet setMultiAttrs $sg_field \ + -singleValue {11} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{11}} \ + -stepValue {11} \ + -fixedBits {11} \ + -fieldValue {11} \ + -auto False \ + -randomMask {11} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {11} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.security-32" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.security-32" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Unclassified} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.compartments-33" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.compartments-33" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.handling-34" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.handling-34" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.tcc-35" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.tcc-35" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.lsrr.type-36" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.lsrr.type-36" + ixNet setMultiAttrs $sg_field \ + -singleValue {131} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{131}} \ + -stepValue {131} \ + -fixedBits {131} \ + -fieldValue {131} \ + -auto False \ + -randomMask {131} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {131} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.lsrr.length-37" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.lsrr.length-37" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {8} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.pointer-38" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.pointer-38" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{4}} \ + -stepValue {4} \ + -fixedBits {4} \ + -fieldValue {4} \ + -auto False \ + -randomMask {4} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {4} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routeData-39" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routeData-39" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.ssrr.type-40" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.ssrr.type-40" + ixNet setMultiAttrs $sg_field \ + -singleValue {137} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{137}} \ + -stepValue {137} \ + -fixedBits {137} \ + -fieldValue {137} \ + -auto False \ + -randomMask {137} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {137} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.ssrr.length-41" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.ssrr.length-41" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {8} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.recordRoute.type-42" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.recordRoute.type-42" + ixNet setMultiAttrs $sg_field \ + -singleValue {7} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{7}} \ + -stepValue {7} \ + -fixedBits {7} \ + -fieldValue {7} \ + -auto False \ + -randomMask {7} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {7} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.recordRoute.length-43" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.recordRoute.length-43" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {8} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.streamId.type-44" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.streamId.type-44" + ixNet setMultiAttrs $sg_field \ + -singleValue {136} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{136}} \ + -stepValue {136} \ + -fixedBits {136} \ + -fieldValue {136} \ + -auto False \ + -randomMask {136} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {136} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.streamId.length-45" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.streamId.length-45" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{4}} \ + -stepValue {4} \ + -fixedBits {4} \ + -fieldValue {4} \ + -auto False \ + -randomMask {4} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {4} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.streamId.id-46" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.streamId.id-46" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.type-47" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.type-47" + ixNet setMultiAttrs $sg_field \ + -singleValue {68} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{68}} \ + -stepValue {68} \ + -fixedBits {68} \ + -fieldValue {68} \ + -auto False \ + -randomMask {68} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {68} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.length-48" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.length-48" + ixNet setMultiAttrs $sg_field \ + -singleValue {12} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{12}} \ + -stepValue {12} \ + -fixedBits {12} \ + -fieldValue {12} \ + -auto False \ + -randomMask {12} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {12} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.pointer-49" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.pointer-49" + ixNet setMultiAttrs $sg_field \ + -singleValue {5} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{5}} \ + -stepValue {5} \ + -fixedBits {5} \ + -fieldValue {5} \ + -auto False \ + -randomMask {5} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {5} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.overflow-50" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.overflow-50" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.flags-51" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.flags-51" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Timestamps only, in consecutive 32-bit words} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.pair.address-52" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.pair.address-52" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.pair.timestamp-53" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.pair.timestamp-53" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.last-54" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.last-54" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routerAlert.type-55" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routerAlert.type-55" + ixNet setMultiAttrs $sg_field \ + -singleValue {94} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0x94}} \ + -stepValue {0x94} \ + -fixedBits {0x94} \ + -fieldValue {94} \ + -auto False \ + -randomMask {0x94} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0x94} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routerAlert.length-56" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routerAlert.length-56" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0x04}} \ + -stepValue {0x04} \ + -fixedBits {0x04} \ + -fieldValue {4} \ + -auto False \ + -randomMask {0x04} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0x04} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routerAlert.value-57" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routerAlert.value-57" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Router shall examine packet} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"ipv4-2"/field:"ipv4.header.options.pad-58" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.pad-58" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"udp-3" + # + set sg_stack $ixNetSG_Stack(2)/stack:"udp-3" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"udp-3"/field:"udp.header.srcPort-1" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.srcPort-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {63} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{63}} \ + -stepValue {63} \ + -fixedBits {63} \ + -fieldValue {Default} \ + -auto True \ + -randomMask {63} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {63} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"udp-3"/field:"udp.header.dstPort-2" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.dstPort-2" + ixNet setMultiAttrs $sg_field \ + -singleValue {63} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{63}} \ + -stepValue {1} \ + -fixedBits {63} \ + -fieldValue {Default} \ + -auto False \ + -randomMask {63} \ + -trackingEnabled False \ + -valueType $multipleStreams \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {64000} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"udp-3"/field:"udp.header.length-3" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.length-3" + ixNet setMultiAttrs $sg_field \ + -singleValue {26} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {26} \ + -auto True \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"udp-3"/field:"udp.header.checksum-4" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.checksum-4" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"fcs-4" + # + set sg_stack $ixNetSG_Stack(2)/stack:"fcs-4" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/stack:"fcs-4"/field:"ethernet.fcs-1" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.fcs-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/configElement:1/transmissionDistribution + # + set sg_transmissionDistribution $ixNetSG_Stack(2)/transmissionDistribution + ixNet setMultiAttrs $sg_transmissionDistribution \ + -distributions {} + sg_commit + set sg_transmissionDistribution [lindex [ixNet remapIds $sg_transmissionDistribution] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1 + # + set sg_highLevelStream $ixNetSG_Stack(1)/highLevelStream:1 + ixNet setMultiAttrs $sg_highLevelStream \ + -destinationMacMode manual \ + -crc goodCrc \ + -txPortId $ixNetSG_ref(2) \ + -preambleFrameSizeMode auto \ + -rxPortIds [list $ixNetSG_ref(10)] \ + -suspend False \ + -preambleCustomSize 8 \ + -name {Traffic Item 1-EndpointSet-1 - Flow Group 0001} + ixNet setMultiAttrs $sg_highLevelStream/frameSize \ + -weightedPairs {} \ + -fixedSize 64 \ + -incrementFrom 64 \ + -randomMin 64 \ + -randomMax 1518 \ + -quadGaussian {} \ + -type fixed \ + -presetDistribution cisco \ + -incrementStep 1 \ + -incrementTo 1518 + ixNet setMultiAttrs $sg_highLevelStream/frameRate \ + -bitRateUnitsType bitsPerSec \ + -rate 10 \ + -enforceMinimumInterPacketGap 0 \ + -type percentLineRate \ + -interPacketGapUnitsType nanoseconds + ixNet setMultiAttrs $sg_highLevelStream/framePayload \ + -type incrementByte \ + -customRepeat True \ + -customPattern {} + ixNet setMultiAttrs $sg_highLevelStream/transmissionControl \ + -frameCount 1 \ + -minGapBytes 12 \ + -interStreamGap 0 \ + -interBurstGap 0 \ + -interBurstGapUnits nanoseconds \ + -type continuous \ + -duration 1 \ + -repeatBurst 1 \ + -enableInterStreamGap False \ + -startDelayUnits bytes \ + -iterationCount 1 \ + -burstPacketCount 1 \ + -enableInterBurstGap False \ + -startDelay 0 + sg_commit + set sg_highLevelStream [lindex [ixNet remapIds $sg_highLevelStream] 0] + set ixNetSG_Stack(2) $sg_highLevelStream + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ethernet-1" + # + set sg_stack $ixNetSG_Stack(2)/stack:"ethernet-1" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ethernet-1"/field:"ethernet.header.destinationAddress-1" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.destinationAddress-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {00:01:00:05:08:00} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{LearntInfo}} \ + -stepValue {00:00:00:00:00:00} \ + -fixedBits {00:00:00:00:00:00} \ + -fieldValue {00:01:00:05:08:00} \ + -auto False \ + -randomMask {00:00:00:00:00:00} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {00:00:00:00:00:00} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ethernet-1"/field:"ethernet.header.sourceAddress-2" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.sourceAddress-2" + ixNet setMultiAttrs $sg_field \ + -singleValue {00:00:00:00:00:01} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{LearntInfo}} \ + -stepValue {00:00:00:00:00:00} \ + -fixedBits {00:00:00:00:00:00} \ + -fieldValue {00:00:00:00:00:01} \ + -auto False \ + -randomMask {00:00:00:00:00:00} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {00:00:00:00:00:00} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ethernet-1"/field:"ethernet.header.etherType-3" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.etherType-3" + ixNet setMultiAttrs $sg_field \ + -singleValue {800} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0xFFFF}} \ + -stepValue {0xFFFF} \ + -fixedBits {0xFFFF} \ + -fieldValue {800} \ + -auto True \ + -randomMask {0xFFFF} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0xFFFF} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ethernet-1"/field:"ethernet.header.pfcQueue-4" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.pfcQueue-4" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2" + # + set sg_stack $ixNetSG_Stack(2)/stack:"ipv4-2" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.version-1" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.version-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{4}} \ + -stepValue {4} \ + -fixedBits {4} \ + -fieldValue {4} \ + -auto False \ + -randomMask {4} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {4} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.headerLength-2" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.headerLength-2" + ixNet setMultiAttrs $sg_field \ + -singleValue {5} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {5} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.raw-3" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.raw-3" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.tos.precedence-4" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.precedence-4" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {000 Routine} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.tos.delay-5" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.delay-5" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.tos.throughput-6" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.throughput-6" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.tos.reliability-7" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.reliability-7" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.tos.monetary-8" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.monetary-8" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.tos.unused-9" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.unused-9" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.defaultPHB.defaultPHB-10" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.defaultPHB.defaultPHB-10" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.defaultPHB.unused-11" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.defaultPHB.unused-11" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.classSelectorPHB.classSelectorPHB-12" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.classSelectorPHB.classSelectorPHB-12" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {Precedence 1} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.classSelectorPHB.unused-13" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.classSelectorPHB.unused-13" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.assuredForwardingPHB-14" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.assuredForwardingPHB-14" + ixNet setMultiAttrs $sg_field \ + -singleValue {10} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{10}} \ + -stepValue {10} \ + -fixedBits {10} \ + -fieldValue {Class 1, Low drop precedence} \ + -auto False \ + -randomMask {10} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {10} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.unused-15" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.unused-15" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.expeditedForwardingPHB-16" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.expeditedForwardingPHB-16" + ixNet setMultiAttrs $sg_field \ + -singleValue {46} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{46}} \ + -stepValue {46} \ + -fixedBits {46} \ + -fieldValue {46} \ + -auto False \ + -randomMask {46} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {46} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.unused-17" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.unused-17" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.totalLength-18" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.totalLength-18" + ixNet setMultiAttrs $sg_field \ + -singleValue {46} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{20}} \ + -stepValue {20} \ + -fixedBits {20} \ + -fieldValue {46} \ + -auto True \ + -randomMask {20} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {20} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.identification-19" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.identification-19" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.flags.reserved-20" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.flags.reserved-20" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.flags.fragment-21" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.flags.fragment-21" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {May fragment} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.flags.lastFragment-22" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.flags.lastFragment-22" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Last fragment} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.fragmentOffset-23" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.fragmentOffset-23" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.ttl-24" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.ttl-24" + ixNet setMultiAttrs $sg_field \ + -singleValue {64} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{64}} \ + -stepValue {64} \ + -fixedBits {64} \ + -fieldValue {64} \ + -auto False \ + -randomMask {64} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {64} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.protocol-25" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.protocol-25" + ixNet setMultiAttrs $sg_field \ + -singleValue {17} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{61}} \ + -stepValue {61} \ + -fixedBits {61} \ + -fieldValue {UDP} \ + -auto True \ + -randomMask {61} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {61} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.checksum-26" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.checksum-26" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.srcIp-27" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.srcIp-27" + ixNet setMultiAttrs $sg_field \ + -singleValue {1.1.1.1} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0.0.0.0}} \ + -stepValue {0.0.0.0} \ + -fixedBits {0.0.0.0} \ + -fieldValue {1.1.1.1} \ + -auto False \ + -randomMask {0.0.0.0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0.0.0.0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.dstIp-28" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.dstIp-28" + ixNet setMultiAttrs $sg_field \ + -singleValue {90.90.90.90} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0.0.0.0}} \ + -stepValue {0.0.0.0} \ + -fixedBits {0.0.0.0} \ + -fieldValue {90.90.90.90} \ + -auto False \ + -randomMask {0.0.0.0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0.0.0.0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.nop-29" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.nop-29" + ixNet setMultiAttrs $sg_field \ + -singleValue {1} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{1}} \ + -stepValue {1} \ + -fixedBits {1} \ + -fieldValue {1} \ + -auto False \ + -randomMask {1} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {1} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.type-30" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.type-30" + ixNet setMultiAttrs $sg_field \ + -singleValue {130} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{130}} \ + -stepValue {130} \ + -fixedBits {130} \ + -fieldValue {130} \ + -auto False \ + -randomMask {130} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {130} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.length-31" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.length-31" + ixNet setMultiAttrs $sg_field \ + -singleValue {11} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{11}} \ + -stepValue {11} \ + -fixedBits {11} \ + -fieldValue {11} \ + -auto False \ + -randomMask {11} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {11} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.security-32" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.security-32" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Unclassified} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.compartments-33" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.compartments-33" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.handling-34" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.handling-34" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.tcc-35" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.tcc-35" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.lsrr.type-36" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.lsrr.type-36" + ixNet setMultiAttrs $sg_field \ + -singleValue {131} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{131}} \ + -stepValue {131} \ + -fixedBits {131} \ + -fieldValue {131} \ + -auto False \ + -randomMask {131} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {131} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.lsrr.length-37" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.lsrr.length-37" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {8} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.pointer-38" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.pointer-38" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{4}} \ + -stepValue {4} \ + -fixedBits {4} \ + -fieldValue {4} \ + -auto False \ + -randomMask {4} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {4} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routeData-39" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routeData-39" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.ssrr.type-40" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.ssrr.type-40" + ixNet setMultiAttrs $sg_field \ + -singleValue {137} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{137}} \ + -stepValue {137} \ + -fixedBits {137} \ + -fieldValue {137} \ + -auto False \ + -randomMask {137} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {137} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.ssrr.length-41" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.ssrr.length-41" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {8} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.recordRoute.type-42" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.recordRoute.type-42" + ixNet setMultiAttrs $sg_field \ + -singleValue {7} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{7}} \ + -stepValue {7} \ + -fixedBits {7} \ + -fieldValue {7} \ + -auto False \ + -randomMask {7} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {7} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.recordRoute.length-43" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.recordRoute.length-43" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {8} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.streamId.type-44" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.streamId.type-44" + ixNet setMultiAttrs $sg_field \ + -singleValue {136} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{136}} \ + -stepValue {136} \ + -fixedBits {136} \ + -fieldValue {136} \ + -auto False \ + -randomMask {136} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {136} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.streamId.length-45" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.streamId.length-45" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{4}} \ + -stepValue {4} \ + -fixedBits {4} \ + -fieldValue {4} \ + -auto False \ + -randomMask {4} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {4} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.streamId.id-46" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.streamId.id-46" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.type-47" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.type-47" + ixNet setMultiAttrs $sg_field \ + -singleValue {68} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{68}} \ + -stepValue {68} \ + -fixedBits {68} \ + -fieldValue {68} \ + -auto False \ + -randomMask {68} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {68} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.length-48" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.length-48" + ixNet setMultiAttrs $sg_field \ + -singleValue {12} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{12}} \ + -stepValue {12} \ + -fixedBits {12} \ + -fieldValue {12} \ + -auto False \ + -randomMask {12} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {12} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.pointer-49" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.pointer-49" + ixNet setMultiAttrs $sg_field \ + -singleValue {5} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{5}} \ + -stepValue {5} \ + -fixedBits {5} \ + -fieldValue {5} \ + -auto False \ + -randomMask {5} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {5} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.overflow-50" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.overflow-50" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.flags-51" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.flags-51" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Timestamps only, in consecutive 32-bit words} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.pair.address-52" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.pair.address-52" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.pair.timestamp-53" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.pair.timestamp-53" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.last-54" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.last-54" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routerAlert.type-55" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routerAlert.type-55" + ixNet setMultiAttrs $sg_field \ + -singleValue {94} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0x94}} \ + -stepValue {0x94} \ + -fixedBits {0x94} \ + -fieldValue {94} \ + -auto False \ + -randomMask {0x94} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0x94} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routerAlert.length-56" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routerAlert.length-56" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0x04}} \ + -stepValue {0x04} \ + -fixedBits {0x04} \ + -fieldValue {4} \ + -auto False \ + -randomMask {0x04} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0x04} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routerAlert.value-57" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routerAlert.value-57" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Router shall examine packet} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"ipv4-2"/field:"ipv4.header.options.pad-58" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.pad-58" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"udp-3" + # + set sg_stack $ixNetSG_Stack(2)/stack:"udp-3" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"udp-3"/field:"udp.header.srcPort-1" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.srcPort-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {63} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{63}} \ + -stepValue {63} \ + -fixedBits {63} \ + -fieldValue {Default} \ + -auto True \ + -randomMask {63} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {63} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"udp-3"/field:"udp.header.dstPort-2" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.dstPort-2" + ixNet setMultiAttrs $sg_field \ + -singleValue {63} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{63}} \ + -stepValue {1} \ + -fixedBits {63} \ + -fieldValue {Default} \ + -auto False \ + -randomMask {63} \ + -trackingEnabled False \ + -valueType $multipleStreams \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {64000} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"udp-3"/field:"udp.header.length-3" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.length-3" + ixNet setMultiAttrs $sg_field \ + -singleValue {26} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {26} \ + -auto True \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"udp-3"/field:"udp.header.checksum-4" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.checksum-4" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"fcs-4" + # + set sg_stack $ixNetSG_Stack(2)/stack:"fcs-4" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/highLevelStream:1/stack:"fcs-4"/field:"ethernet.fcs-1" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.fcs-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/transmissionDistribution + # + set sg_transmissionDistribution $ixNetSG_Stack(1)/transmissionDistribution + ixNet setMultiAttrs $sg_transmissionDistribution \ + -distributions {} + sg_commit + set sg_transmissionDistribution [lindex [ixNet remapIds $sg_transmissionDistribution] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking + # + set sg_tracking $ixNetSG_Stack(1)/tracking + ixNet setMultiAttrs $sg_tracking \ + -offset 0 \ + -oneToOneMesh False \ + -trackBy {} \ + -values {} \ + -fieldWidth thirtyTwoBits \ + -protocolOffset {Root.0} + ixNet setMultiAttrs $sg_tracking/egress \ + -offset {Outer VLAN Priority (3 bits)} \ + -enabled False \ + -customOffsetBits 0 \ + -encapsulation {Ethernet} \ + -customWidthBits 0 + ixNet setMultiAttrs $sg_tracking/latencyBin \ + -enabled False \ + -binLimits {1 1.42 2 2.82 4 5.66 8 11.32} \ + -numberOfBins 8 + sg_commit + set sg_tracking [lindex [ixNet remapIds $sg_tracking] 0] + set ixNetSG_Stack(2) $sg_tracking + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ethernet-1" + # + set sg_stack $ixNetSG_Stack(2)/egress/fieldOffset/stack:"ethernet-1" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ethernet-1"/field:"ethernet.header.destinationAddress-1" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.destinationAddress-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {00:00:00:00:00:00} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{00:00:00:00:00:00}} \ + -stepValue {00:00:00:00:00:00} \ + -fixedBits {00:00:00:00:00:00} \ + -fieldValue {00:00:00:00:00:00} \ + -auto False \ + -randomMask {00:00:00:00:00:00} \ + -trackingEnabled True \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {00:00:00:00:00:00} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ethernet-1"/field:"ethernet.header.sourceAddress-2" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.sourceAddress-2" + ixNet setMultiAttrs $sg_field \ + -singleValue {00:00:00:00:00:00} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{00:00:00:00:00:00}} \ + -stepValue {00:00:00:00:00:00} \ + -fixedBits {00:00:00:00:00:00} \ + -fieldValue {00:00:00:00:00:00} \ + -auto False \ + -randomMask {00:00:00:00:00:00} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {00:00:00:00:00:00} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ethernet-1"/field:"ethernet.header.etherType-3" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.etherType-3" + ixNet setMultiAttrs $sg_field \ + -singleValue {800} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0xFFFF}} \ + -stepValue {0xFFFF} \ + -fixedBits {0xFFFF} \ + -fieldValue {800} \ + -auto True \ + -randomMask {0xFFFF} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0xFFFF} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ethernet-1"/field:"ethernet.header.pfcQueue-4" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.pfcQueue-4" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2" + # + set sg_stack $ixNetSG_Stack(2)/egress/fieldOffset/stack:"ipv4-2" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.version-1" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.version-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{4}} \ + -stepValue {4} \ + -fixedBits {4} \ + -fieldValue {4} \ + -auto False \ + -randomMask {4} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {4} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.headerLength-2" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.headerLength-2" + ixNet setMultiAttrs $sg_field \ + -singleValue {5} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {5} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.raw-3" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.raw-3" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.tos.precedence-4" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.precedence-4" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {000 Routine} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.tos.delay-5" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.delay-5" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.tos.throughput-6" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.throughput-6" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.tos.reliability-7" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.reliability-7" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.tos.monetary-8" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.monetary-8" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.tos.unused-9" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.unused-9" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.defaultPHB.defaultPHB-10" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.defaultPHB.defaultPHB-10" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.defaultPHB.unused-11" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.defaultPHB.unused-11" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.classSelectorPHB.classSelectorPHB-12" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.classSelectorPHB.classSelectorPHB-12" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {Precedence 1} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.classSelectorPHB.unused-13" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.classSelectorPHB.unused-13" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.assuredForwardingPHB-14" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.assuredForwardingPHB-14" + ixNet setMultiAttrs $sg_field \ + -singleValue {10} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{10}} \ + -stepValue {10} \ + -fixedBits {10} \ + -fieldValue {Class 1, Low drop precedence} \ + -auto False \ + -randomMask {10} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {10} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.unused-15" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.unused-15" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.expeditedForwardingPHB-16" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.expeditedForwardingPHB-16" + ixNet setMultiAttrs $sg_field \ + -singleValue {46} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{46}} \ + -stepValue {46} \ + -fixedBits {46} \ + -fieldValue {46} \ + -auto False \ + -randomMask {46} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {46} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.unused-17" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.unused-17" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.totalLength-18" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.totalLength-18" + ixNet setMultiAttrs $sg_field \ + -singleValue {92} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{20}} \ + -stepValue {20} \ + -fixedBits {20} \ + -fieldValue {92} \ + -auto True \ + -randomMask {20} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {20} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.identification-19" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.identification-19" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.flags.reserved-20" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.flags.reserved-20" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.flags.fragment-21" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.flags.fragment-21" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {May fragment} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.flags.lastFragment-22" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.flags.lastFragment-22" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Last fragment} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.fragmentOffset-23" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.fragmentOffset-23" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.ttl-24" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.ttl-24" + ixNet setMultiAttrs $sg_field \ + -singleValue {64} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{64}} \ + -stepValue {64} \ + -fixedBits {64} \ + -fieldValue {64} \ + -auto False \ + -randomMask {64} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {64} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.protocol-25" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.protocol-25" + ixNet setMultiAttrs $sg_field \ + -singleValue {17} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{61}} \ + -stepValue {61} \ + -fixedBits {61} \ + -fieldValue {UDP} \ + -auto True \ + -randomMask {61} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {61} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.checksum-26" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.checksum-26" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.srcIp-27" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.srcIp-27" + ixNet setMultiAttrs $sg_field \ + -singleValue {0.0.0.0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0.0.0.0}} \ + -stepValue {0.0.0.0} \ + -fixedBits {0.0.0.0} \ + -fieldValue {0.0.0.0} \ + -auto False \ + -randomMask {0.0.0.0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0.0.0.0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.dstIp-28" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.dstIp-28" + ixNet setMultiAttrs $sg_field \ + -singleValue {0.0.0.0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0.0.0.0}} \ + -stepValue {0.0.0.0} \ + -fixedBits {0.0.0.0} \ + -fieldValue {0.0.0.0} \ + -auto False \ + -randomMask {0.0.0.0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0.0.0.0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.nop-29" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.nop-29" + ixNet setMultiAttrs $sg_field \ + -singleValue {1} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{1}} \ + -stepValue {1} \ + -fixedBits {1} \ + -fieldValue {1} \ + -auto False \ + -randomMask {1} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {1} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.type-30" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.type-30" + ixNet setMultiAttrs $sg_field \ + -singleValue {130} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{130}} \ + -stepValue {130} \ + -fixedBits {130} \ + -fieldValue {130} \ + -auto False \ + -randomMask {130} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {130} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.length-31" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.length-31" + ixNet setMultiAttrs $sg_field \ + -singleValue {11} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{11}} \ + -stepValue {11} \ + -fixedBits {11} \ + -fieldValue {11} \ + -auto False \ + -randomMask {11} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {11} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.security-32" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.security-32" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Unclassified} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.compartments-33" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.compartments-33" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.handling-34" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.handling-34" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.tcc-35" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.tcc-35" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.lsrr.type-36" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.lsrr.type-36" + ixNet setMultiAttrs $sg_field \ + -singleValue {131} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{131}} \ + -stepValue {131} \ + -fixedBits {131} \ + -fieldValue {131} \ + -auto False \ + -randomMask {131} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {131} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.lsrr.length-37" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.lsrr.length-37" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {8} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.pointer-38" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.pointer-38" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{4}} \ + -stepValue {4} \ + -fixedBits {4} \ + -fieldValue {4} \ + -auto False \ + -randomMask {4} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {4} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routeData-39" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routeData-39" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.ssrr.type-40" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.ssrr.type-40" + ixNet setMultiAttrs $sg_field \ + -singleValue {137} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{137}} \ + -stepValue {137} \ + -fixedBits {137} \ + -fieldValue {137} \ + -auto False \ + -randomMask {137} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {137} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.ssrr.length-41" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.ssrr.length-41" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {8} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.recordRoute.type-42" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.recordRoute.type-42" + ixNet setMultiAttrs $sg_field \ + -singleValue {7} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{7}} \ + -stepValue {7} \ + -fixedBits {7} \ + -fieldValue {7} \ + -auto False \ + -randomMask {7} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {7} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.recordRoute.length-43" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.recordRoute.length-43" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {8} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.streamId.type-44" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.streamId.type-44" + ixNet setMultiAttrs $sg_field \ + -singleValue {136} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{136}} \ + -stepValue {136} \ + -fixedBits {136} \ + -fieldValue {136} \ + -auto False \ + -randomMask {136} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {136} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.streamId.length-45" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.streamId.length-45" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{4}} \ + -stepValue {4} \ + -fixedBits {4} \ + -fieldValue {4} \ + -auto False \ + -randomMask {4} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {4} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.streamId.id-46" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.streamId.id-46" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.type-47" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.type-47" + ixNet setMultiAttrs $sg_field \ + -singleValue {68} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{68}} \ + -stepValue {68} \ + -fixedBits {68} \ + -fieldValue {68} \ + -auto False \ + -randomMask {68} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {68} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.length-48" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.length-48" + ixNet setMultiAttrs $sg_field \ + -singleValue {12} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{12}} \ + -stepValue {12} \ + -fixedBits {12} \ + -fieldValue {12} \ + -auto False \ + -randomMask {12} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {12} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.pointer-49" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.pointer-49" + ixNet setMultiAttrs $sg_field \ + -singleValue {5} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{5}} \ + -stepValue {5} \ + -fixedBits {5} \ + -fieldValue {5} \ + -auto False \ + -randomMask {5} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {5} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.overflow-50" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.overflow-50" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.flags-51" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.flags-51" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Timestamps only, in consecutive 32-bit words} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.pair.address-52" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.pair.address-52" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.pair.timestamp-53" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.pair.timestamp-53" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.last-54" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.last-54" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routerAlert.type-55" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routerAlert.type-55" + ixNet setMultiAttrs $sg_field \ + -singleValue {94} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0x94}} \ + -stepValue {0x94} \ + -fixedBits {0x94} \ + -fieldValue {94} \ + -auto False \ + -randomMask {0x94} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0x94} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routerAlert.length-56" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routerAlert.length-56" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0x04}} \ + -stepValue {0x04} \ + -fixedBits {0x04} \ + -fieldValue {4} \ + -auto False \ + -randomMask {0x04} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0x04} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routerAlert.value-57" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routerAlert.value-57" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Router shall examine packet} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.pad-58" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.pad-58" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"udp-3" + # + set sg_stack $ixNetSG_Stack(2)/egress/fieldOffset/stack:"udp-3" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"udp-3"/field:"udp.header.srcPort-1" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.srcPort-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {63} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{63}} \ + -stepValue {63} \ + -fixedBits {63} \ + -fieldValue {Default} \ + -auto True \ + -randomMask {63} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {63} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"udp-3"/field:"udp.header.dstPort-2" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.dstPort-2" + ixNet setMultiAttrs $sg_field \ + -singleValue {63} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{63}} \ + -stepValue {63} \ + -fixedBits {63} \ + -fieldValue {Default} \ + -auto True \ + -randomMask {63} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {63} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"udp-3"/field:"udp.header.length-3" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.length-3" + ixNet setMultiAttrs $sg_field \ + -singleValue {72} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {72} \ + -auto True \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"udp-3"/field:"udp.header.checksum-4" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.checksum-4" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"fcs-4" + # + set sg_stack $ixNetSG_Stack(2)/egress/fieldOffset/stack:"fcs-4" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/tracking/egress/fieldOffset/stack:"fcs-4"/field:"ethernet.fcs-1" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.fcs-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1 + # + set sg_egressTracking [ixNet add $ixNetSG_Stack(1) egressTracking] + ixNet setMultiAttrs $sg_egressTracking \ + -offset {Outer VLAN Priority (3 bits)} \ + -customOffsetBits 0 \ + -encapsulation {Ethernet} \ + -customWidthBits 0 + sg_commit + set sg_egressTracking [lindex [ixNet remapIds $sg_egressTracking] 0] + set ixNetSG_Stack(2) $sg_egressTracking + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ethernet-1" + # + set sg_stack $ixNetSG_Stack(2)/fieldOffset/stack:"ethernet-1" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ethernet-1"/field:"ethernet.header.destinationAddress-1" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.destinationAddress-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {00:00:00:00:00:00} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{00:00:00:00:00:00}} \ + -stepValue {00:00:00:00:00:00} \ + -fixedBits {00:00:00:00:00:00} \ + -fieldValue {00:00:00:00:00:00} \ + -auto False \ + -randomMask {00:00:00:00:00:00} \ + -trackingEnabled True \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {00:00:00:00:00:00} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ethernet-1"/field:"ethernet.header.sourceAddress-2" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.sourceAddress-2" + ixNet setMultiAttrs $sg_field \ + -singleValue {00:00:00:00:00:00} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{00:00:00:00:00:00}} \ + -stepValue {00:00:00:00:00:00} \ + -fixedBits {00:00:00:00:00:00} \ + -fieldValue {00:00:00:00:00:00} \ + -auto False \ + -randomMask {00:00:00:00:00:00} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {00:00:00:00:00:00} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ethernet-1"/field:"ethernet.header.etherType-3" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.etherType-3" + ixNet setMultiAttrs $sg_field \ + -singleValue {800} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0xFFFF}} \ + -stepValue {0xFFFF} \ + -fixedBits {0xFFFF} \ + -fieldValue {800} \ + -auto True \ + -randomMask {0xFFFF} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0xFFFF} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ethernet-1"/field:"ethernet.header.pfcQueue-4" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.header.pfcQueue-4" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2" + # + set sg_stack $ixNetSG_Stack(2)/fieldOffset/stack:"ipv4-2" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.version-1" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.version-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{4}} \ + -stepValue {4} \ + -fixedBits {4} \ + -fieldValue {4} \ + -auto False \ + -randomMask {4} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {4} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.headerLength-2" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.headerLength-2" + ixNet setMultiAttrs $sg_field \ + -singleValue {5} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {5} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.raw-3" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.raw-3" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.tos.precedence-4" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.precedence-4" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {000 Routine} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.tos.delay-5" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.delay-5" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.tos.throughput-6" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.throughput-6" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.tos.reliability-7" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.reliability-7" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.tos.monetary-8" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.monetary-8" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Normal} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.tos.unused-9" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.tos.unused-9" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.defaultPHB.defaultPHB-10" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.defaultPHB.defaultPHB-10" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.defaultPHB.unused-11" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.defaultPHB.unused-11" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.classSelectorPHB.classSelectorPHB-12" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.classSelectorPHB.classSelectorPHB-12" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {Precedence 1} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.classSelectorPHB.unused-13" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.classSelectorPHB.unused-13" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.assuredForwardingPHB-14" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.assuredForwardingPHB-14" + ixNet setMultiAttrs $sg_field \ + -singleValue {10} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{10}} \ + -stepValue {10} \ + -fixedBits {10} \ + -fieldValue {Class 1, Low drop precedence} \ + -auto False \ + -randomMask {10} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {10} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.unused-15" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.assuredForwardingPHB.unused-15" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.expeditedForwardingPHB-16" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.expeditedForwardingPHB-16" + ixNet setMultiAttrs $sg_field \ + -singleValue {46} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{46}} \ + -stepValue {46} \ + -fixedBits {46} \ + -fieldValue {46} \ + -auto False \ + -randomMask {46} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {46} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.unused-17" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.priority.ds.phb.expeditedForwardingPHB.unused-17" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.totalLength-18" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.totalLength-18" + ixNet setMultiAttrs $sg_field \ + -singleValue {92} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{20}} \ + -stepValue {20} \ + -fixedBits {20} \ + -fieldValue {92} \ + -auto True \ + -randomMask {20} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {20} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.identification-19" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.identification-19" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.flags.reserved-20" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.flags.reserved-20" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.flags.fragment-21" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.flags.fragment-21" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {May fragment} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.flags.lastFragment-22" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.flags.lastFragment-22" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Last fragment} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.fragmentOffset-23" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.fragmentOffset-23" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.ttl-24" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.ttl-24" + ixNet setMultiAttrs $sg_field \ + -singleValue {64} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{64}} \ + -stepValue {64} \ + -fixedBits {64} \ + -fieldValue {64} \ + -auto False \ + -randomMask {64} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {64} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.protocol-25" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.protocol-25" + ixNet setMultiAttrs $sg_field \ + -singleValue {17} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{61}} \ + -stepValue {61} \ + -fixedBits {61} \ + -fieldValue {UDP} \ + -auto True \ + -randomMask {61} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {61} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.checksum-26" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.checksum-26" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.srcIp-27" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.srcIp-27" + ixNet setMultiAttrs $sg_field \ + -singleValue {0.0.0.0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0.0.0.0}} \ + -stepValue {0.0.0.0} \ + -fixedBits {0.0.0.0} \ + -fieldValue {0.0.0.0} \ + -auto False \ + -randomMask {0.0.0.0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0.0.0.0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.dstIp-28" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.dstIp-28" + ixNet setMultiAttrs $sg_field \ + -singleValue {0.0.0.0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0.0.0.0}} \ + -stepValue {0.0.0.0} \ + -fixedBits {0.0.0.0} \ + -fieldValue {0.0.0.0} \ + -auto False \ + -randomMask {0.0.0.0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0.0.0.0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.nop-29" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.nop-29" + ixNet setMultiAttrs $sg_field \ + -singleValue {1} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{1}} \ + -stepValue {1} \ + -fixedBits {1} \ + -fieldValue {1} \ + -auto False \ + -randomMask {1} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice True \ + -startValue {1} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.type-30" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.type-30" + ixNet setMultiAttrs $sg_field \ + -singleValue {130} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{130}} \ + -stepValue {130} \ + -fixedBits {130} \ + -fieldValue {130} \ + -auto False \ + -randomMask {130} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {130} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.length-31" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.length-31" + ixNet setMultiAttrs $sg_field \ + -singleValue {11} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{11}} \ + -stepValue {11} \ + -fixedBits {11} \ + -fieldValue {11} \ + -auto False \ + -randomMask {11} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {11} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.security-32" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.security-32" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Unclassified} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.compartments-33" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.compartments-33" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.handling-34" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.handling-34" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.security.tcc-35" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.security.tcc-35" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.lsrr.type-36" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.lsrr.type-36" + ixNet setMultiAttrs $sg_field \ + -singleValue {131} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{131}} \ + -stepValue {131} \ + -fixedBits {131} \ + -fieldValue {131} \ + -auto False \ + -randomMask {131} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {131} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.lsrr.length-37" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.lsrr.length-37" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {8} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.pointer-38" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.pointer-38" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{4}} \ + -stepValue {4} \ + -fixedBits {4} \ + -fieldValue {4} \ + -auto False \ + -randomMask {4} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {4} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routeData-39" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routeData-39" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.ssrr.type-40" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.ssrr.type-40" + ixNet setMultiAttrs $sg_field \ + -singleValue {137} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{137}} \ + -stepValue {137} \ + -fixedBits {137} \ + -fieldValue {137} \ + -auto False \ + -randomMask {137} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {137} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.ssrr.length-41" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.ssrr.length-41" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {8} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.recordRoute.type-42" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.recordRoute.type-42" + ixNet setMultiAttrs $sg_field \ + -singleValue {7} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{7}} \ + -stepValue {7} \ + -fixedBits {7} \ + -fieldValue {7} \ + -auto False \ + -randomMask {7} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {7} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.recordRoute.length-43" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.recordRoute.length-43" + ixNet setMultiAttrs $sg_field \ + -singleValue {8} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {8} \ + -auto False \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.streamId.type-44" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.streamId.type-44" + ixNet setMultiAttrs $sg_field \ + -singleValue {136} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{136}} \ + -stepValue {136} \ + -fixedBits {136} \ + -fieldValue {136} \ + -auto False \ + -randomMask {136} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {136} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.streamId.length-45" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.streamId.length-45" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{4}} \ + -stepValue {4} \ + -fixedBits {4} \ + -fieldValue {4} \ + -auto False \ + -randomMask {4} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {4} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.streamId.id-46" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.streamId.id-46" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.type-47" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.type-47" + ixNet setMultiAttrs $sg_field \ + -singleValue {68} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{68}} \ + -stepValue {68} \ + -fixedBits {68} \ + -fieldValue {68} \ + -auto False \ + -randomMask {68} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {68} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.length-48" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.length-48" + ixNet setMultiAttrs $sg_field \ + -singleValue {12} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{12}} \ + -stepValue {12} \ + -fixedBits {12} \ + -fieldValue {12} \ + -auto False \ + -randomMask {12} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {12} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.pointer-49" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.pointer-49" + ixNet setMultiAttrs $sg_field \ + -singleValue {5} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{5}} \ + -stepValue {5} \ + -fixedBits {5} \ + -fieldValue {5} \ + -auto False \ + -randomMask {5} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {5} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.overflow-50" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.overflow-50" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.flags-51" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.flags-51" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Timestamps only, in consecutive 32-bit words} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.pair.address-52" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.pair.address-52" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.timestamp.pair.timestamp-53" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.timestamp.pair.timestamp-53" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.last-54" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.last-54" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routerAlert.type-55" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routerAlert.type-55" + ixNet setMultiAttrs $sg_field \ + -singleValue {94} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0x94}} \ + -stepValue {0x94} \ + -fixedBits {0x94} \ + -fieldValue {94} \ + -auto False \ + -randomMask {0x94} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0x94} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routerAlert.length-56" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routerAlert.length-56" + ixNet setMultiAttrs $sg_field \ + -singleValue {4} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0x04}} \ + -stepValue {0x04} \ + -fixedBits {0x04} \ + -fieldValue {4} \ + -auto False \ + -randomMask {0x04} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0x04} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.nextOption.option.routerAlert.value-57" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.nextOption.option.routerAlert.value-57" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {Router shall examine packet} \ + -auto False \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"ipv4-2"/field:"ipv4.header.options.pad-58" + # + set sg_field $ixNetSG_Stack(3)/field:"ipv4.header.options.pad-58" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled False \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"udp-3" + # + set sg_stack $ixNetSG_Stack(2)/fieldOffset/stack:"udp-3" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"udp-3"/field:"udp.header.srcPort-1" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.srcPort-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {63} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{63}} \ + -stepValue {63} \ + -fixedBits {63} \ + -fieldValue {Default} \ + -auto True \ + -randomMask {63} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {63} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"udp-3"/field:"udp.header.dstPort-2" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.dstPort-2" + ixNet setMultiAttrs $sg_field \ + -singleValue {63} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{63}} \ + -stepValue {63} \ + -fixedBits {63} \ + -fieldValue {Default} \ + -auto True \ + -randomMask {63} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {63} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"udp-3"/field:"udp.header.length-3" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.length-3" + ixNet setMultiAttrs $sg_field \ + -singleValue {72} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{8}} \ + -stepValue {8} \ + -fixedBits {8} \ + -fieldValue {72} \ + -auto True \ + -randomMask {8} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {8} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"udp-3"/field:"udp.header.checksum-4" + # + set sg_field $ixNetSG_Stack(3)/field:"udp.header.checksum-4" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"fcs-4" + # + set sg_stack $ixNetSG_Stack(2)/fieldOffset/stack:"fcs-4" + sg_commit + set sg_stack [lindex [ixNet remapIds $sg_stack] 0] + set ixNetSG_Stack(3) $sg_stack + + # + # configuring the object that corresponds to /traffic/trafficItem:1/egressTracking:1/fieldOffset/stack:"fcs-4"/field:"ethernet.fcs-1" + # + set sg_field $ixNetSG_Stack(3)/field:"ethernet.fcs-1" + ixNet setMultiAttrs $sg_field \ + -singleValue {0} \ + -seed {1} \ + -optionalEnabled True \ + -fullMesh False \ + -valueList {{0}} \ + -stepValue {0} \ + -fixedBits {0} \ + -fieldValue {0} \ + -auto True \ + -randomMask {0} \ + -trackingEnabled False \ + -valueType singleValue \ + -activeFieldChoice False \ + -startValue {0} \ + -countValue {1} + sg_commit + set sg_field [lindex [ixNet remapIds $sg_field] 0] + + # + # configuring the object that corresponds to /traffic/trafficItem:1/dynamicUpdate + # + set sg_dynamicUpdate $ixNetSG_Stack(1)/dynamicUpdate + ixNet setMultiAttrs $sg_dynamicUpdate \ + -enabledSessionAwareTrafficFields {} \ + -enabledDynamicUpdateFields {} + sg_commit + set sg_dynamicUpdate [lindex [ixNet remapIds $sg_dynamicUpdate] 0] + + ### + ### /quickTest area + ### + + # + # configuring the object that corresponds to /quickTest/rfc2544throughput:1 + # + if {$rfc2544TestType == "throughput"} { + set sg_rfc2544throughput [ixNet add $ixNetSG_Stack(0)/quickTest rfc2544throughput] + ixNet setMultiAttrs $sg_rfc2544throughput \ + -name {QuickTest1} \ + -mode existingMode \ + -inputParameters {{}} + ixNet setMultiAttrs $sg_rfc2544throughput/testConfig \ + -protocolItem {} \ + -enableMinFrameSize False \ + -framesize $frameSize \ + -reportTputRateUnit mbps \ + -duration $duration \ + -numtrials $numTrials \ + -trafficType constantLoading \ + -burstSize 1 \ + -framesPerBurstGap 1 \ + -tolerance 0 \ + -frameLossUnit {0} \ + -staggeredStart False \ + -framesizeList {64} \ + -frameSizeMode custom \ + -rateSelect percentMaxRate \ + -percentMaxRate 100 \ + -resolution 0.01 \ + -forceRegenerate False \ + -reportSequenceError False \ + -ipv4rate 50 \ + -ipv6rate 50 \ + -loadRateList $frameRate \ + -fixedLoadUnit percentMaxRate \ + -loadRateValue 80 \ + -incrementLoadUnit percentMaxRate \ + -initialIncrementLoadRate 10 \ + -stepIncrementLoadRate 10 \ + -maxIncrementLoadRate 100 \ + -randomLoadUnit percentMaxRate \ + -minRandomLoadRate 10 \ + -maxRandomLoadRate 80 \ + -countRandomLoadRate 1 \ + -minFpsRate 1000 \ + -minKbpsRate 64 \ + -txDelay 2 \ + -delayAfterTransmit 2 \ + -minRandomFrameSize 64 \ + -maxRandomFrameSize 1518 \ + -countRandomFrameSize 1 \ + -minIncrementFrameSize 64 \ + -stepIncrementFrameSize 64 \ + -maxIncrementFrameSize 1518 \ + -calculateLatency True \ + -latencyType storeForward \ + -calculateJitter False \ + -enableDataIntegrity False \ + -enableBackoffIteration False \ + -enableSaturationIteration False \ + -enableStopTestOnHighLoss False \ + -enableBackoffUseAs% False \ + -backoffIteration 1 \ + -saturationIteration 1 \ + -stopTestOnHighLoss 0 \ + -loadType $loadType \ + -stepLoadUnit percentMaxRate \ + -customLoadUnit percentMaxRate \ + -comboLoadUnit percentMaxRate \ + -binaryLoadUnit percentMaxRate \ + -initialBinaryLoadRate 100 \ + -minBinaryLoadRate 1 \ + -maxBinaryLoadRate 100 \ + -binaryResolution 1 \ + -binaryBackoff 50 \ + -binaryTolerance $tolerance \ + -binaryFrameLossUnit % \ + -comboFrameLossUnit % \ + -stepFrameLossUnit % \ + -initialStepLoadRate 10 \ + -maxStepLoadRate 100 \ + -stepStepLoadRate 10 \ + -stepTolerance 0 \ + -initialComboLoadRate 10 \ + -maxComboLoadRate 100 \ + -minComboLoadRate 10 \ + -stepComboLoadRate 10 \ + -comboResolution 1 \ + -comboBackoff 50 \ + -comboTolerance 0 \ + -binarySearchType linear \ + -unchangedValueList {0} \ + -enableFastConvergence $fastConvergence \ + -fastConvergenceDuration $convergenceDuration \ + -fastConvergenceThreshold 10 \ + -framesizeFixedValue 128 \ + -gap 3 \ + -unchangedInitial False \ + -generateTrackingOptionAggregationFiles False \ + -enableExtraIterations False \ + -extraIterationOffsets {10, -10} \ + -usePercentOffsets False \ + -imixDistribution weight \ + -imixAdd {0} \ + -imixDelete {0} \ + -imixData {{{{64}{{TOS S:0 S:0 S:0 S:0 S:0} S:0}{1 40}}{{128}{{TOS S:0 S:0 S:0 S:0 S:0} S:0}{1 30}}{{256}{{TOS S:0 S:0 S:0 S:0 S:0} S:0}{1 30}}}} \ + -imixEnabled False \ + -imixTemplates none \ + -framesizeImixList {64} \ + -imixTrafficType {UNCHNAGED} \ + -mapType {oneToOne} \ + -supportedTrafficTypes {mac,ipv4,ipv6,ipmix} + ixNet setMultiAttrs $sg_rfc2544throughput/learnFrames \ + -learnFrequency $learningFrequency \ + -learnNumFrames 10 \ + -learnRate 100 \ + -learnWaitTime 1000 \ + -learnFrameSize 64 \ + -fastPathLearnFrameSize 64 \ + -learnWaitTimeBeforeTransmit 0 \ + -learnSendMacOnly False \ + -learnSendRouterSolicitation False \ + -fastPathEnable $fastPathEnable \ + -fastPathRate 100 \ + -fastPathNumFrames 10 + ixNet setMultiAttrs $sg_rfc2544throughput/passCriteria \ + -passCriteriaLoadRateMode average \ + -passCriteriaLoadRateValue 100 \ + -passCriteriaLoadRateScale mbps \ + -enablePassFail False \ + -enableRatePassFail False \ + -enableLatencyPassFail False \ + -enableStandardDeviationPassFail False \ + -latencyThresholdValue 10 \ + -latencyThresholdScale us \ + -latencyThresholdMode average \ + -latencyVariationThresholdValue 0 \ + -latencyVariationThresholdScale us \ + -latencyVarThresholdMode average \ + -enableSequenceErrorsPassFail False \ + -seqErrorsThresholdValue 0 \ + -seqErrorsThresholdMode average \ + -enableDataIntegrityPassFail False \ + -dataErrorThresholdValue 0 \ + -dataErrorThresholdMode average + sg_commit + set sg_rfc2544throughput [lindex [ixNet remapIds $sg_rfc2544throughput] 0] + set ixNetSG_Stack(1) $sg_rfc2544throughput + + # + # configuring the object that corresponds to /quickTest/rfc2544throughput:1/protocols + # + set sg_protocols $ixNetSG_Stack(1)/protocols + ixNet setMultiAttrs $sg_protocols \ + -protocolState default \ + -waitAfterStart 120 \ + -waitAfterStop 30 + sg_commit + set sg_protocols [lindex [ixNet remapIds $sg_protocols] 0] + + # + # configuring the object that corresponds to /quickTest/rfc2544throughput:1/trafficSelection:1 + # + set sg_trafficSelection [ixNet add $ixNetSG_Stack(1) trafficSelection] + ixNet setMultiAttrs $sg_trafficSelection \ + -id $ixNetSG_ref(26) \ + -includeMode inTest \ + -itemType trafficItem + sg_commit + set sg_trafficSelection [lindex [ixNet remapIds $sg_trafficSelection] 0] + ixNet commit + + } elseif {$rfc2544TestType == "back2back"} { + # + # configuring the object that corresponds to /quickTest/rfc2544back2back:2 + # + set sg_rfc2544back2back [ixNet add $ixNetSG_Stack(0)/quickTest rfc2544back2back] + ixNet setMultiAttrs $sg_rfc2544back2back \ + -name {B2B} \ + -mode existingMode \ + -inputParameters {{}} + ixNet setMultiAttrs $sg_rfc2544back2back/testConfig \ + -protocolItem {} \ + -framesize $frameSize \ + -reportTputRateUnit mbps \ + -rfc2544ImixDataQoS False \ + -detailedResultsEnabled True \ + -rfc2889ordering noOrdering \ + -floodedFramesEnabled False \ + -duration $duration \ + -numtrials $numTrials \ + -trafficType constantLoading \ + -burstSize 1 \ + -framesPerBurstGap 1 \ + -tolerance 0 \ + -frameLossUnit {0} \ + -staggeredStart False \ + -framesizeList {64} \ + -frameSizeMode custom \ + -rateSelect percentMaxRate \ + -percentMaxRate 100 \ + -resolution 0.01 \ + -forceRegenerate False \ + -reportSequenceError False \ + -ipv4rate 50 \ + -ipv6rate 50 \ + -loadRateList $frameRate \ + -minFpsRate 1000 \ + -minKbpsRate 64 \ + -txDelay 2 \ + -delayAfterTransmit 2 \ + -minRandomFrameSize 64 \ + -maxRandomFrameSize 1518 \ + -countRandomFrameSize 1 \ + -minIncrementFrameSize 64 \ + -stepIncrementFrameSize 64 \ + -maxIncrementFrameSize 1518 \ + -calculateLatency False \ + -calibrateLatency False \ + -latencyType cutThrough \ + -calculateJitter False \ + -enableDataIntegrity False \ + -loadType $loadType \ + -binaryFrameLossUnit % \ + -loadUnit percentMaxRate \ + -customLoadUnit percentMaxRate \ + -randomLoadUnit percentMaxRate \ + -incrementLoadUnit percentMaxRate \ + -binaryResolution 100 \ + -binaryBackoff 50 \ + -binaryTolerance $tolerance \ + -initialIncrementLoadRate 100 \ + -stepIncrementLoadRate 10 \ + -maxIncrementLoadRate 100 \ + -minRandomLoadRate 10 \ + -maxRandomLoadRate 80 \ + -countRandomLoadRate 1 \ + -numFrames {100000} \ + -loadRate 100 \ + -enableMinFrameSize False \ + -gap 3 \ + -generateTrackingOptionAggregationFiles False \ + -sendFullyMeshed False \ + -imixDistribution weight \ + -imixAdd {0} \ + -imixDelete {0} \ + -imixData {{{{64}{{TOS S:0 S:0 S:0 S:0 S:0} S:0}{1 40}}{{128}{{TOS S:0 S:0 S:0 S:0 S:0} S:0}{1 30}}{{256}{{TOS S:0 S:0 S:0 S:0 S:0} S:0}{1 30}}}} \ + -imixEnabled False \ + -imixTemplates none \ + -framesizeImixList {64} \ + -imixTrafficType {UNCHNAGED} \ + -ipRatioMode fixed \ + -ipv4RatioList {10,25,50,75,90} \ + -ipv6RatioList {90,75,50,25,10} \ + -minIncrementIpv4Ratio {10} \ + -stepIncrementIpv4Ratio {10} \ + -maxIncrementIpv4Ratio {90} \ + -minIncrementIpv6Ratio {90} \ + -stepIncrementIpv6Ratio {-10} \ + -maxIncrementIpv6Ratio {10} \ + -minRandomIpv4Ratio {10} \ + -maxRandomIpv4Ratio {90} \ + -minRandomIpv6Ratio {90} \ + -maxRandomIpv6Ratio {10} \ + -countRandomIpRatio 1 \ + -mapType {oneToOne|manyToMany|fullMesh} \ + -supportedTrafficTypes {mac,ipv4,ipv6,ipmix} + ixNet setMultiAttrs $sg_rfc2544back2back/learnFrames \ + -learnFrequency $learningFrequency \ + -learnNumFrames 10 \ + -learnRate 100 \ + -learnWaitTime 1000 \ + -learnFrameSize 64 \ + -fastPathLearnFrameSize 64 \ + -learnWaitTimeBeforeTransmit 0 \ + -learnSendMacOnly False \ + -learnSendRouterSolicitation False \ + -fastPathEnable $fastPathEnable \ + -fastPathRate 100 \ + -fastPathNumFrames 10 + ixNet setMultiAttrs $sg_rfc2544back2back/passCriteria \ + -passCriteriaLoadRateMode average \ + -passCriteriaLoadRateValue 100 \ + -passCriteriaLoadRateScale mbps \ + -enablePassFail False \ + -enableRatePassFail False \ + -enableLatencyPassFail False \ + -enableStandardDeviationPassFail False \ + -latencyThresholdValue 10 \ + -latencyThresholdScale us \ + -latencyThresholdMode average \ + -latencyVariationThresholdValue 0 \ + -latencyVariationThresholdScale us \ + -latencyVarThresholdMode average \ + -enableSequenceErrorsPassFail False \ + -seqErrorsThresholdValue 0 \ + -seqErrorsThresholdMode average \ + -enableDataIntegrityPassFail False \ + -dataErrorThresholdValue 0 \ + -dataErrorThresholdMode average \ + -enableFrameCountPassFail False \ + -passCriteriaFrameCountValue 100 \ + -passCriteriaFrameCountMode average + sg_commit + set sg_rfc2544back2back [lindex [ixNet remapIds $sg_rfc2544back2back] 0] + set ixNetSG_Stack(1) $sg_rfc2544back2back + + # + # configuring the object that corresponds to /quickTest/rfc2544back2back:2/protocols + # + set sg_protocols $ixNetSG_Stack(1)/protocols + ixNet setMultiAttrs $sg_protocols \ + -protocolState default \ + -waitAfterStart 120 \ + -waitAfterStop 30 + sg_commit + set sg_protocols [lindex [ixNet remapIds $sg_protocols] 0] + + # + # configuring the object that corresponds to /quickTest/rfc2544back2back:2/trafficSelection:1 + # + set sg_trafficSelection [ixNet add $ixNetSG_Stack(1) trafficSelection] + ixNet setMultiAttrs $sg_trafficSelection \ + -id $ixNetSG_ref(26) \ + -includeMode inTest \ + -itemType trafficItem + sg_commit + set sg_trafficSelection [lindex [ixNet remapIds $sg_trafficSelection] 0] + ixNet commit + } + # + # getting and applying the RFC2544 test + # + set root [ixNet getRoot] + set qt [ixNet getList $root quickTest] + if {$rfc2544TestType == "throughput"} { + set rfc2544test [ixNet getList $qt rfc2544throughput] + } elseif {$rfc2544TestType == "back2back"} { + set rfc2544test [ixNet getList $qt rfc2544back2back] + } + ixNet exec apply $rfc2544test + after 5000 + + # + # starting the RFC2544 Throughput test + # + puts "Starting test..." + ixNet exec start $rfc2544test +} + +proc waitForRfc2544Test { } { + # Wait for- and return results of- RFC2544 quicktest. + + global rfc2544test + + puts "Waiting for test to complete..." + set result [ixNet exec waitForTest $rfc2544test] + puts "Finished Test" + + return "$result" +} diff --git a/tools/pkt_gen/trafficgen/__init__.py b/tools/pkt_gen/trafficgen/__init__.py new file mode 100755 index 00000000..2a3b9bd3 --- /dev/null +++ b/tools/pkt_gen/trafficgen/__init__.py @@ -0,0 +1,19 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Trafficgen interface and helpers. +""" + +from tools.pkt_gen.trafficgen.trafficgen import * +from tools.pkt_gen.trafficgen.trafficgenhelper import * diff --git a/tools/pkt_gen/trafficgen/trafficgen.py b/tools/pkt_gen/trafficgen/trafficgen.py new file mode 100755 index 00000000..13af6b81 --- /dev/null +++ b/tools/pkt_gen/trafficgen/trafficgen.py @@ -0,0 +1,221 @@ +# Copyright 2015 Intel Corporation. +# +# 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. +"""Abstract "traffic generator" model. + +This is an abstract class for traffic generators. +""" + +#TODO update Back2Back method description when Result implementation will +#be ready. + +from tools.pkt_gen.trafficgen.trafficgenhelper import TRAFFIC_DEFAULTS + +class ITrafficGenerator(object): + """Model of a traffic generator device. + """ + _traffic_defaults = TRAFFIC_DEFAULTS.copy() + + @property + def traffic_defaults(self): + """Default traffic values. + + These can be expected to be constant across traffic generators, + so no setter is provided. Changes to the structure or contents + will likely break traffic generator implementations or tests + respectively. + """ + return self._traffic_defaults + + def __enter__(self): + """Connect to the traffic generator. + + Provide a context manager interface to the traffic generators. + This simply calls the :func:`connect` function. + """ + return self.connect() + + def __exit__(self, type_, value, traceback): + """Disconnect from the traffic generator. + + Provide a context manager interface to the traffic generators. + This simply calls the :func:`disconnect` function. + """ + self.disconnect() + + def connect(self): + """Connect to the traffic generator. + + This is an optional function, designed for traffic generators + which must be "connected to" (i.e. via SSH or an API) before + they can be used. If not required, simply do nothing here. + + Where implemented, this function should raise an exception on + failure. + + :returns: None + """ + raise NotImplementedError('Please call an implementation.') + + def disconnect(self): + """Disconnect from the traffic generator. + + As with :func:`connect`, this function is optional. + + Where implemented, this function should raise an exception on + failure. + + :returns: None + """ + raise NotImplementedError('Please call an implementation.') + + def send_burst_traffic(self, traffic=None, numpkts=100, + time=20, framerate=100): + """Send a burst of traffic. + + Send a ``numpkts`` packets of traffic, using ``traffic`` + configuration, with a timeout of ``time``. + + Attributes: + :param traffic: Detailed "traffic" spec, i.e. IP address, VLAN tags + :param numpkts: Number of packets to send + :param framerate: Expected framerate + :param time: Time to wait to receive packets + + :returns: dictionary of strings with following data: + - List of Tx Frames, + - List of Rx Frames, + - List of Tx Bytes, + - List of List of Rx Bytes, + - Payload Errors and Sequence Errors. + """ + raise NotImplementedError('Please call an implementation.') + + def send_cont_traffic(self, traffic=None, time=20, framerate=0, + multistream=False): + """Send a continuous flow of traffic. + + Send packets at ``framerate``, using ``traffic`` configuration, + until timeout ``time`` occurs. + + :param traffic: Detailed "traffic" spec, i.e. IP address, VLAN tags + :param time: Time to wait to receive packets (secs) + :param framerate: Expected framerate + :param multistream: Enable multistream output by overriding the + UDP port number in ``traffic`` with values + from 1 to 64,000 + :returns: dictionary of strings with following data: + - Tx Throughput (fps), + - Rx Throughput (fps), + - Tx Throughput (mbps), + - Rx Throughput (mbps), + - Tx Throughput (% linerate), + - Rx Throughput (% linerate), + - Min Latency (ns), + - Max Latency (ns), + - Avg Latency (ns) + """ + raise NotImplementedError('Please call an implementation.') + + def start_cont_traffic(self, traffic=None, time=20, framerate=0, + multistream=False): + """Non-blocking version of 'send_cont_traffic'. + + Start transmission and immediately return. Do not wait for + results. + """ + raise NotImplementedError('Please call an implementation.') + + def stop_cont_traffic(self): + """Stop continuous transmission and return results. + """ + raise NotImplementedError('Please call an implementation.') + + def send_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + lossrate=0.0, multistream=False): + """Send traffic per RFC2544 throughput test specifications. + + Send packets at a variable rate, using ``traffic`` + configuration, until minimum rate at which no packet loss is + detected is found. + + :param traffic: Detailed "traffic" spec, i.e. IP address, VLAN tags + :param trials: Number of trials to execute + :param duration: Per iteration duration + :param lossrate: Acceptable lossrate percentage + :param multistream: Enable multistream output by overriding the + UDP port number in ``traffic`` with values + from 1 to 64,000 + :returns: dictionary of strings with following data: + - Tx Throughput (fps), + - Rx Throughput (fps), + - Tx Throughput (mbps), + - Rx Throughput (mbps), + - Tx Throughput (% linerate), + - Rx Throughput (% linerate), + - Min Latency (ns), + - Max Latency (ns), + - Avg Latency (ns) + """ + raise NotImplementedError('Please call an implementation.') + + def start_rfc2544_throughput(self, traffic=None, trials=3, duration=20, + lossrate=0.0, multistream=False): + """Non-blocking version of 'send_rfc2544_throughput'. + + Start transmission and immediately return. Do not wait for + results. + """ + raise NotImplementedError('Please call an implementation.') + + def wait_rfc2544_throughput(self): + """Wait for and return results of RFC2544 test. + """ + raise NotImplementedError('Please call an implementation.') + + def send_rfc2544_back2back(self, traffic=None, trials=1, duration=20, + lossrate=0.0, multistream=False): + """Send traffic per RFC2544 back2back test specifications. + + Send packets at a fixed rate, using ``traffic`` + configuration, until minimum time at which no packet loss is + detected is found. + + :param traffic: Detailed "traffic" spec, i.e. IP address, VLAN + tags + :param trials: Number of trials to execute + :param duration: Per iteration duration + :param lossrate: Acceptable loss percentage + :param multistream: Enable multistream output by overriding the + UDP port number in ``traffic`` with values from 1 to 64,000 + + :returns: Named tuple of Rx Throughput (fps), Rx Throughput (mbps), + Tx Rate (% linerate), Rx Rate (% linerate), Tx Count (frames), + Back to Back Count (frames), Frame Loss (frames), Frame Loss (%) + :rtype: :class:`Back2BackResult` + """ + raise NotImplementedError('Please call an implementation.') + + def start_rfc2544_back2back(self, traffic=None, trials=1, duration=20, + lossrate=0.0, multistream=False): + """Non-blocking version of 'send_rfc2544_back2back'. + + Start transmission and immediately return. Do not wait for + results. + """ + raise NotImplementedError('Please call an implementation.') + + def wait_rfc2544_back2back(self): + """Wait and set results of RFC2544 test. + """ + raise NotImplementedError('Please call an implementation.') diff --git a/tools/pkt_gen/trafficgen/trafficgenhelper.py b/tools/pkt_gen/trafficgen/trafficgenhelper.py new file mode 100644 index 00000000..2cd2d2b1 --- /dev/null +++ b/tools/pkt_gen/trafficgen/trafficgenhelper.py @@ -0,0 +1,84 @@ +# Copyright 2015 Intel Corporation. +# +# 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. +"""Helper methods collection. + +Collection of helper methods used by traffic generators +implementation. +""" + +from collections import namedtuple + +CMD_PREFIX = 'gencmd : ' +TRAFFIC_DEFAULTS = { + 'l2': { + 'framesize': 64, + 'srcmac': '00:00:00:00:00:00', + 'dstmac': '00:00:00:00:00:00', + 'srcport': 3000, + 'dstport': 3001, + }, + 'l3': { + 'proto': 'tcp', + 'srcip': '1.1.1.1', + 'dstip': '90.90.90.90', + }, + 'vlan': { + 'enabled': False, + 'id': 0, + 'priority': 0, + 'cfi': 0, + }, +} + +#TODO remove namedtuples and implement results through IResult interface found +#in core/results + +BurstResult = namedtuple( + 'BurstResult', + 'frames_tx frames_rx bytes_tx bytes_rx payload_err seq_err') +Back2BackResult = namedtuple( + 'Back2BackResult', + 'rx_fps rx_mbps tx_percent rx_percent tx_count b2b_frames ' + 'frame_loss_frames frame_loss_percent') + + +def merge_spec(orig, new): + """Merges ``new`` dict with ``orig`` dict, and return orig. + + This takes into account nested dictionaries. Example: + + >>> old = {'foo': 1, 'bar': {'foo': 2, 'bar': 3}} + >>> new = {'foo': 6, 'bar': {'foo': 7}} + >>> merge_spec(old, new) + {'foo': 3, 'bar': {'foo': 7, 'bar': 3}} + + You'll notice that ``bar.bar`` is not removed. This is the desired result. + """ + for key in orig: + if key not in new: + continue + + # Not allowing derived dictionary types for now + # pylint: disable=unidiomatic-typecheck + if type(orig[key]) == dict: + orig[key] = merge_spec(orig[key], new[key]) + else: + orig[key] = new[key] + + for key in new: + if key not in orig: + orig[key] = new[key] + + return orig + diff --git a/tools/tasks.py b/tools/tasks.py new file mode 100644 index 00000000..f8f11d4e --- /dev/null +++ b/tools/tasks.py @@ -0,0 +1,354 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Task management helper functions and classes. +""" + +import select +import subprocess +import logging +import pexpect +import threading +import sys +import os +import locale + +from conf import settings + + +CMD_PREFIX = 'cmd : ' +_MY_ENCODING = locale.getdefaultlocale()[1] + +def _get_stdout(): + """Get stdout value for ``subprocess`` calls. + """ + stdout = None + + if settings.getValue('VERBOSITY') != 'debug': + stdout = open(os.devnull, 'wb') + + return stdout + + +def run_task(cmd, logger, msg=None, check_error=False): + """Run task, report errors and log overall status. + + Run given task using ``subprocess.Popen``. Log the commands + used and any errors generated. Prints stdout to screen if + in verbose mode and returns it regardless. Prints stderr to + screen always. + + :param cmd: Exact command to be executed + :param logger: Logger to write details to + :param msg: Message to be shown to user + :param check_error: Throw exception on error + + :returns: (stdout, stderr) + """ + def handle_error(exception): + """Handle errors by logging and optionally raising an exception. + """ + logger.error( + 'Unable to execute %(cmd)s. Exception: %(exception)s', + {'cmd': ' '.join(cmd), 'exception': exception}) + if check_error: + raise exception + + stdout = [] + stderr = [] + + if msg: + logger.info(msg) + + logger.debug('%s%s', CMD_PREFIX, ' '.join(cmd)) + + try: + proc = subprocess.Popen( + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=0) + + while True: + reads = [proc.stdout.fileno(), proc.stderr.fileno()] + ret = select.select(reads, [], []) + + for file_d in ret[0]: + if file_d == proc.stdout.fileno(): + line = proc.stdout.readline() + if settings.getValue('VERBOSITY') == 'debug': + sys.stdout.write(line.decode(_MY_ENCODING)) + stdout.append(line) + if file_d == proc.stderr.fileno(): + line = proc.stderr.readline() + sys.stderr.write(line.decode(_MY_ENCODING)) + stderr.append(line) + + if proc.poll() is not None: + break + except OSError as ex: + handle_error(ex) + else: + if proc.returncode: + ex = subprocess.CalledProcessError(proc.returncode, cmd, stderr) + handle_error(ex) + + return ('\n'.join(sout.decode(_MY_ENCODING).strip() for sout in stdout), + ('\n'.join(sout.decode(_MY_ENCODING).strip() for sout in stderr))) + +def run_background_task(cmd, logger, msg): + """Run task in background and log when started. + + Run given task using ``subprocess.Popen``. Log the command + used. Print stdout to screen if in verbose mode. Prints stderr + to screen always. + + :param cmd: Exact command to be executed + :param logger: Logger to write details to + :param msg: Message to be shown to user + + :returns: Process PID + """ + logger.info(msg) + logger.debug('%s%s', CMD_PREFIX, ' '.join(cmd)) + + proc = subprocess.Popen(cmd, stdout=_get_stdout(), bufsize=0) + + return proc.pid + + +def run_interactive_task(cmd, logger, msg): + """Run a task interactively and log when started. + + Run given task using ``pexpect.spawn``. Log the command used. + Performs neither validation of the process - if the process + successfully started or is still running - nor killing of the + process. The user must do both. + + :param cmd: Exact command to be executed + :param logger: Logger to write details to + :param msg: Message to be shown to user + + :returns: ``pexpect.child`` object + """ + logger.info(msg) + logger.debug('%s%s', CMD_PREFIX, cmd) + child = pexpect.spawnu(cmd) + + if settings.getValue('VERBOSITY') == 'debug': + child.logfile_read = sys.stdout + + return child + + +class Process(object): + """Control an instance of a long-running process. + + This is basically a context-manager wrapper around the + ``run_interactive_task`` function above (with some extra helper + functions). + """ + _cmd = None + _child = None + _logfile = None + _logger = logging.getLogger(__name__) + _expect = None + _timeout = -1 + _proc_name = 'unnamed process' + _relinquish_thread = None + + # context manager + + def __enter__(self): + """Start process instance using context manager. + """ + self.start() + return self + + def __exit__(self, type_, value, traceback): + """Shutdown process instance. + """ + self.kill() + + # startup/shutdown + + def start(self): + """Start process instance. + """ + self._start_process() + if self._timeout > 0: + self._expect_process() + + def _start_process(self): + """Start process instance. + """ + cmd = ' '.join(settings.getValue('SHELL_CMD') + + ['"%s"' % ' '.join(self._cmd)]) + + self._child = run_interactive_task(cmd, self._logger, + 'Starting %s...' % self._proc_name) + self._child.logfile = open(self._logfile, 'w') + + def expect(self, msg, timeout=None): + """Expect string from process. + + Expect string and die if not received. + + :param msg: String to expect. + :param timeout: Time to wait for string. + + :returns: None + """ + self._expect_process(msg, timeout) + + def _expect_process(self, msg=None, timeout=None): + """Expect string from process. + """ + if not msg: + msg = self._expect + if not timeout: + timeout = self._timeout + + # we use exceptions rather than catching conditions in ``expect`` list + # as we want to fail catastrophically after handling; there is likely + # little we can do from within the scripts to fix issues such as + # hugepages not being mounted + try: + self._child.expect([msg], timeout=timeout) + except pexpect.EOF as exc: + self._logger.critical( + 'An error occurred. Please check the logs (%s) for more' + ' information. Exiting...', self._logfile) + raise exc + except pexpect.TIMEOUT as exc: + self._logger.critical( + 'Failed to execute in \'%d\' seconds. Please check the logs' + ' (%s) for more information. Exiting...', + timeout, self._logfile) + self.kill() + raise exc + except (Exception, KeyboardInterrupt) as exc: + self._logger.critical('General exception raised. Exiting...') + self.kill() + raise exc + + def kill(self): + """Kill process instance if it is alive. + """ + if self._child and self._child.isalive(): + run_task(['sudo', 'kill', '-2', str(self._child.pid)], + self._logger) + + if self.is_relinquished(): + self._relinquish_thread.join() + + self._logger.info( + 'Log available at %s', self._logfile) + + def is_relinquished(self): + """Returns True if process is relinquished. + + If relinquished the process is no longer controllable and can + only be killed. + + :returns: True if process is relinquished, else False. + """ + return self._relinquish_thread + + def is_running(self): + """Returns True if process is running. + + :returns: True if process is running, else False + """ + return self._child is not None + + def _affinitize_pid(self, core, pid): + """Affinitize a process with ``pid`` to ``core``. + + :param core: Core to affinitize process to. + :param pid: Process ID to affinitize. + + :returns: None + """ + run_task(['sudo', 'taskset', '-c', '-p', str(core), + str(pid)], + self._logger) + + def affinitize(self, core): + """Affinitize process to a specific ``core``. + + :param core: Core to affinitize process to. + + :returns: None + """ + self._logger.info('Affinitizing process') + + if self._child and self._child.isalive(): + self._affinitize_pid(core, self._child.pid) + + class ContinueReadPrintLoop(threading.Thread): + """Thread to read output from child and log. + + Taken from: https://github.com/pexpect/pexpect/issues/90 + """ + def __init__(self, child): + self.child = child + threading.Thread.__init__(self) + + def run(self): + while True: + try: + self.child.read_nonblocking() + except (pexpect.EOF, pexpect.TIMEOUT): + break + + def relinquish(self): + """Relinquish control of process. + + Give up control of application in order to ensure logging + continues for the application. After relinquishing control it + will no longer be possible to :func:`expect` anything. + + This works around an issue described here: + + https://github.com/pexpect/pexpect/issues/90 + + It is hoped that future versions of pexpect will avoid this + issue. + """ + self._relinquish_thread = self.ContinueReadPrintLoop(self._child) + self._relinquish_thread.start() + + +class CustomProcess(Process): + """An sample implementation of ``Process``. + + This is essentially a more detailed version of the + ``run_interactive_task`` function that checks for process execution + and kills the process (assuming use of the context manager). + """ + def __init__(self, cmd, timeout, logfile, expect, name): + """Initialise process state. + + :param cmd: Command to execute. + :param timeout: Time to wait for ``expect``. + :param logfile: Path to logfile. + :param expect: String to expect indicating startup. This is a + regex and should be escaped as such. + :param name: Name of process to use in logs. + + :returns: None + """ + self._cmd = cmd + self._logfile = logfile + self._expect = expect + self._proc_name = name + self._timeout = timeout diff --git a/vnfs/vnf/vnf.py b/vnfs/vnf/vnf.py new file mode 100644 index 00000000..c746aa83 --- /dev/null +++ b/vnfs/vnf/vnf.py @@ -0,0 +1,119 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +""" +Interface for VNF. +""" + + +class IVnf(object): + + """ + Interface for VNF. + """ + + def __init__(self, memory, cpus, + monitor_path, shared_path_host, + shared_path_guest, guest_prompt): + """ + Initialization method. + + Purpose of this method is to initialize all + common Vnf data, no services should be started by + this call (use ``start`` method instead). + + :param memory: Virtual RAM size in megabytes. + :param cpus: Number of Processors. + :param monitor_path: Configure monitor to given path. + :param shared_path_host: HOST path to shared location. + :param shared_path_guest: GUEST path to shared location. + :param guest_prompt: preconfigured command prompt which is used + in execute_and_wait & wait methods + to detect if particular call is finished. + """ + raise NotImplementedError() + + def start(self): + """ + Starts VNF instance. + """ + raise NotImplementedError() + + def stop(self): + """ + Stops VNF instance. + """ + raise NotImplementedError() + + def execute(self, command, delay=30): + """ + execute ``command`` with given ``delay``. + + This method makes asynchronous call to guest system + and waits given ``delay`` before returning. Can be + used with ``wait`` method to create synchronous call. + + :param command: Command to execute on guest system. + :param delay: Delay (in seconds) to wait after sending + command before returning. Please note that + this value can be floating point which + allows to pass milliseconds. + + :returns: None. + """ + raise NotImplementedError() + + def wait(self, guest_prompt, timeout=30): + """ + wait for ``guest_prompt`` on guest system for given ``timeout``. + + This method ends based on two conditions: + * ``guest_prompt`` has been detected + * ``timeout`` has been reached. + + :param guest_prompt: method end condition. If ``guest_prompt`` + won't be detected during given timeout, + method will return False. + :param timeout: Time to wait for prompt (in seconds). + Please note that this value can be floating + point which allows to pass milliseconds. + + :returns: True if result_cmd has been detected before + timeout has been reached, False otherwise. + """ + raise NotImplementedError() + + def execute_and_wait(self, command, timeout=30, guest_prompt=None): + """ + execute ``command`` with given ``timeout``. + + This method makes synchronous call to guest system + and waits till ``command`` execution is finished + (based on ``guest_prompt value) or ''timeout'' has + been reached. + + :param command: Command to execute on guest system. + :param timeout: Timeout till the end of execution is not + detected. + :param guest_prompt: method end condition. If ``guest_prompt`` + won't be detected during given timeout, + method will return False. If no argument + or None value will be passed, default + ``guest_prompt`` passed in __init__ + method will be used. + + :returns: True if end of execution has been detected + before timeout has been reached, False otherwise. + """ + raise NotImplementedError() @@ -0,0 +1,337 @@ +#!/usr/bin/env python3 + +# Copyright 2015 Intel Corporation. +# +# 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. + +"""VSPERF main script. +""" + +import logging +import os +import sys +import argparse +import time +import datetime +import shutil + +sys.dont_write_bytecode = True + +from conf import settings +from core.loader import Loader +from testcases import TestCase +from tools import tasks +from tools.collectors import collector +from tools.pkt_gen import trafficgen + +VERBOSITY_LEVELS = { + 'debug': logging.DEBUG, + 'info': logging.INFO, + 'warning': logging.WARNING, + 'error': logging.ERROR, + 'critical': logging.CRITICAL +} + + +def parse_arguments(): + """ + Parse command line arguments. + """ + class _SplitTestParamsAction(argparse.Action): + """ + Parse and split the '--test-params' argument. + + This expects either 'x=y' or 'x' (implicit true) values. + """ + def __call__(self, parser, namespace, values, option_string=None): + results = {} + + for value in values.split(';'): + result = [key.strip() for key in value.split('=')] + if len(result) == 1: + results[result[0]] = True + elif len(result) == 2: + results[result[0]] = result[1] + else: + raise argparse.ArgumentTypeError( + 'expected \'%s\' to be of format \'key=val\' or' + ' \'key\'' % result) + + setattr(namespace, self.dest, results) + + class _ValidateFileAction(argparse.Action): + """Validate a file can be read from before using it. + """ + def __call__(self, parser, namespace, values, option_string=None): + if not os.path.isfile(values): + raise argparse.ArgumentTypeError( + 'the path \'%s\' is not a valid path' % values) + elif not os.access(values, os.R_OK): + raise argparse.ArgumentTypeError( + 'the path \'%s\' is not accessible' % values) + + setattr(namespace, self.dest, values) + + class _ValidateDirAction(argparse.Action): + """Validate a directory can be written to before using it. + """ + def __call__(self, parser, namespace, values, option_string=None): + if not os.path.isdir(values): + raise argparse.ArgumentTypeError( + 'the path \'%s\' is not a valid path' % values) + elif not os.access(values, os.W_OK): + raise argparse.ArgumentTypeError( + 'the path \'%s\' is not accessible' % values) + + setattr(namespace, self.dest, values) + + def list_logging_levels(): + """Give a summary of all available logging levels. + + :return: List of verbosity level names in decreasing order of + verbosity + """ + return sorted(VERBOSITY_LEVELS.keys(), + key=lambda x: VERBOSITY_LEVELS[x]) + + parser = argparse.ArgumentParser(prog=__file__, formatter_class= + argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument('--version', action='version', version='%(prog)s 0.2') + parser.add_argument('--list', '--list-tests', action='store_true', + help='list all tests and exit') + parser.add_argument('--list-trafficgens', action='store_true', + help='list all traffic generators and exit') + parser.add_argument('--list-collectors', action='store_true', + help='list all system metrics loggers and exit') + parser.add_argument('--list-vswitches', action='store_true', + help='list all system vswitches and exit') + parser.add_argument('--list-settings', action='store_true', + help='list effective settings configuration and exit') + parser.add_argument('test', nargs='*', help='test specification(s)') + + group = parser.add_argument_group('test selection options') + group.add_argument('-f', '--test-spec', help='test specification file') + group.add_argument('-d', '--test-dir', help='directory containing tests') + group.add_argument('-t', '--tests', help='Comma-separated list of terms \ + indicating tests to run. e.g. "RFC2544,!p2p" - run all tests whose\ + name contains RFC2544 less those containing "p2p"') + group.add_argument('--verbosity', choices=list_logging_levels(), + help='debug level') + group.add_argument('--trafficgen', help='traffic generator to use') + group.add_argument('--sysmetrics', help='system metrics logger to use') + group = parser.add_argument_group('test behavior options') + group.add_argument('--load-env', action='store_true', + help='enable loading of settings from the environment') + group.add_argument('--conf-file', action=_ValidateFileAction, + help='settings file') + group.add_argument('--test-params', action=_SplitTestParamsAction, + help='csv list of test parameters: key=val;...') + + args = vars(parser.parse_args()) + + return args + + +def configure_logging(level): + """Configure logging. + """ + log_file_default = os.path.join( + settings.getValue('LOG_DIR'), settings.getValue('LOG_FILE_DEFAULT')) + log_file_host_cmds = os.path.join( + settings.getValue('LOG_DIR'), settings.getValue('LOG_FILE_HOST_CMDS')) + log_file_traffic_gen = os.path.join( + settings.getValue('LOG_DIR'), + settings.getValue('LOG_FILE_TRAFFIC_GEN')) + log_file_sys_metrics = os.path.join( + settings.getValue('LOG_DIR'), + settings.getValue('LOG_FILE_SYS_METRICS')) + + logger = logging.getLogger() + logger.setLevel(logging.DEBUG) + + stream_logger = logging.StreamHandler(sys.stdout) + stream_logger.setLevel(VERBOSITY_LEVELS[level]) + stream_logger.setFormatter(logging.Formatter( + '[%(levelname)s] %(asctime)s : (%(name)s) - %(message)s')) + logger.addHandler(stream_logger) + + file_logger = logging.FileHandler(filename=log_file_default) + file_logger.setLevel(logging.DEBUG) + logger.addHandler(file_logger) + + class CommandFilter(logging.Filter): + """Filter out strings beginning with 'cmd :'""" + def filter(self, record): + return record.getMessage().startswith(tasks.CMD_PREFIX) + + class TrafficGenCommandFilter(logging.Filter): + """Filter out strings beginning with 'gencmd :'""" + def filter(self, record): + return record.getMessage().startswith(trafficgen.CMD_PREFIX) + + class SystemMetricsCommandFilter(logging.Filter): + """Filter out strings beginning with 'gencmd :'""" + def filter(self, record): + return record.getMessage().startswith(collector.CMD_PREFIX) + + cmd_logger = logging.FileHandler(filename=log_file_host_cmds) + cmd_logger.setLevel(logging.DEBUG) + cmd_logger.addFilter(CommandFilter()) + logger.addHandler(cmd_logger) + + gen_logger = logging.FileHandler(filename=log_file_traffic_gen) + gen_logger.setLevel(logging.DEBUG) + gen_logger.addFilter(TrafficGenCommandFilter()) + logger.addHandler(gen_logger) + + metrics_logger = logging.FileHandler(filename=log_file_sys_metrics) + metrics_logger.setLevel(logging.DEBUG) + metrics_logger.addFilter(SystemMetricsCommandFilter()) + logger.addHandler(metrics_logger) + + +def apply_filter(tests, tc_filter): + """Allow a subset of tests to be conveniently selected + + :param tests: The list of Tests from which to select. + :param tc_filter: A case-insensitive string of comma-separated terms + indicating the Tests to select. + e.g. 'RFC' - select all tests whose name contains 'RFC' + e.g. 'RFC,burst' - select all tests whose name contains 'RFC' or + 'burst' + e.g. 'RFC,burst,!p2p' - select all tests whose name contains 'RFC' + or 'burst' and from these remove any containing 'p2p'. + e.g. '' - empty string selects all tests. + :return: A list of the selected Tests. + """ + result = [] + if tc_filter is None: + tc_filter = "" + + for term in [x.strip() for x in tc_filter.lower().split(",")]: + if not term or term[0] != '!': + # Add matching tests from 'tests' into results + result.extend([test for test in tests \ + if test.name.lower().find(term) >= 0]) + else: + # Term begins with '!' so we remove matching tests + result = [test for test in result \ + if test.name.lower().find(term[1:]) < 0] + + return result + + +def main(): + """Main function. + """ + args = parse_arguments() + + # configure settings + + settings.load_from_dir('conf') + + # load command line parameters first in case there are settings files + # to be used + settings.load_from_dict(args) + + if args['conf_file']: + settings.load_from_file(args['conf_file']) + + if args['load_env']: + settings.load_from_env() + + # reload command line parameters since these should take higher priority + # than both a settings file and environment variables + settings.load_from_dict(args) + + configure_logging(settings.getValue('VERBOSITY')) + logger = logging.getLogger() + + # configure trafficgens + + if args['trafficgen']: + trafficgens = Loader().get_trafficgens() + if args['trafficgen'] not in trafficgens: + logging.error('There are no trafficgens matching \'%s\' found in' + ' \'%s\'. Exiting...', args['trafficgen'], + settings.getValue('TRAFFICGEN_DIR')) + sys.exit(1) + + + # generate results directory name + date = datetime.datetime.fromtimestamp(time.time()) + results_dir = "results_" + date.strftime('%Y-%m-%d_%H-%M-%S') + results_path = os.path.join(settings.getValue('LOG_DIR'), results_dir) + + # configure tests + testcases = settings.getValue('PERFORMANCE_TESTS') + all_tests = [] + for cfg in testcases: + try: + all_tests.append(TestCase(cfg, results_path)) + except (Exception) as _: + logger.exception("Failed to create test: %s", + cfg.get('Name', '<Name not set>')) + raise + + # TODO(BOM) Apply filter to select requested tests + all_tests = apply_filter(all_tests, args['tests']) + + # if required, handle list-* operations + + if args['list']: + print("Available Tests:") + print("======") + for test in all_tests: + print('* %-18s%s' % ('%s:' % test.name, test.desc)) + exit() + + if args['list_trafficgens']: + print(Loader().get_trafficgens_printable()) + exit() + + if args['list_collectors']: + print(Loader().get_collectors_printable()) + exit() + + if args['list_vswitches']: + print(Loader().get_vswitches_printable()) + exit() + + if args['list_settings']: + print(str(settings)) + exit() + + # create results directory + if not os.path.exists(results_dir): + logger.info("Creating result directory: " + results_path) + os.makedirs(results_path) + + # run tests + for test in all_tests: + try: + test.run() + #pylint: disable=broad-except + except (Exception) as _: + logger.exception("Failed to run test: %s", test.name) + logger.info("Continuing with next test...") + + #remove directory if no result files were created. + if os.path.exists(results_path): + if os.listdir(results_path) == []: + shutil.rmtree(results_path) + +if __name__ == "__main__": + main() + + diff --git a/vswitches/__init__.py b/vswitches/__init__.py new file mode 100644 index 00000000..a34475be --- /dev/null +++ b/vswitches/__init__.py @@ -0,0 +1,20 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Package for vswitch wrappers for use with VSPERF. + +This package contains an interface the VSPERF core uses for controlling +vSwitches and vSwitch-specific implementation modules of this interface. +""" + diff --git a/vswitches/ovs_dpdk_vhost.py b/vswitches/ovs_dpdk_vhost.py new file mode 100644 index 00000000..d2e8907f --- /dev/null +++ b/vswitches/ovs_dpdk_vhost.py @@ -0,0 +1,143 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""VSPERF VSwitch implementation using DPDK and vhost ports +""" + +from conf import settings +from vswitches.vswitch import IVSwitch +from src.ovs import VSwitchd, OFBridge +from src.dpdk import dpdk + +VSWITCHD_CONST_ARGS = ['--', '--log-file'] + +class OvsDpdkVhost(IVSwitch): + """VSwitch implementation using DPDK and vhost ports + + Generic OVS wrapper functionality in src.ovs is maximally used. This + class wraps DPDK system configuration along with DPDK specific OVS + parameters + + The method docstrings document only considerations specific to this + implementation. For generic information of the nature of the methods, + see the interface. + """ + def __init__(self): + vswitchd_args = ['--dpdk'] + vswitchd_args += settings.getValue('VSWITCHD_DPDK_ARGS') + vswitchd_args += VSWITCHD_CONST_ARGS + + self._vswitchd = VSwitchd(vswitchd_args=vswitchd_args) + self._bridges = {} + + def start(self): + """See IVswitch for general description + + Activates DPDK kernel modules, ovsdb and vswitchd. + """ + dpdk.init() + self._vswitchd.start() + + def stop(self): + """See IVswitch for general description + + Kills ovsdb and vswitchd and removes DPDK kernel modules. + """ + self._vswitchd.kill() + dpdk.cleanup() + + def add_switch(self, switch_name): + """See IVswitch for general description + """ + bridge = OFBridge(switch_name) + bridge.create() + bridge.set_db_attribute('Open_vSwitch', '.', + 'other_config:max-idle', '60000') + bridge.set_db_attribute('Bridge', bridge.br_name, + 'datapath_type', 'netdev') + self._bridges[switch_name] = bridge + + def del_switch(self, switch_name): + """See IVswitch for general description + """ + bridge = self._bridges[switch_name] + self._bridges.pop(switch_name) + bridge.destroy() + + def add_phy_port(self, switch_name): + """See IVswitch for general description + + Creates a port of type dpdk. + The new port is named dpdk<n> where n is an integer starting from 0. + """ + bridge = self._bridges[switch_name] + dpdk_count = self._get_port_count(bridge, 'type=dpdk') + port_name = 'dpdk' + str(dpdk_count) + params = ['--', 'set', 'Interface', port_name, 'type=dpdk'] + of_port = bridge.add_port(port_name, params) + + return (port_name, of_port) + + def add_vport(self, switch_name): + """See IVswitch for general description + + Creates a port of type dpdkvhost + The new port is named dpdkvhost<n> where n is an integer starting + from 0 + """ + bridge = self._bridges[switch_name] + vhost_count = self._get_port_count(bridge, 'type=dpdkvhost') + port_name = 'dpdkvhost' + str(vhost_count) + params = ['--', 'set', 'Interface', port_name, 'type=dpdkvhost'] + of_port = bridge.add_port(port_name, params) + + return (port_name, of_port) + + def get_ports(self, switch_name): + """See IVswitch for general description + """ + bridge = self._bridges[switch_name] + ports = list(bridge.get_ports().items()) + return [(name, of_port) for (name, (of_port, _)) in ports] + + def del_port(self, switch_name, port_name): + """See IVswitch for general description + """ + bridge = self._bridges[switch_name] + bridge.del_port(port_name) + + def add_flow(self, switch_name, flow): + """See IVswitch for general description + """ + bridge = self._bridges[switch_name] + bridge.add_flow(flow) + + def del_flow(self, switch_name, flow=None): + """See IVswitch for general description + """ + flow = flow or {} + bridge = self._bridges[switch_name] + bridge.del_flow(flow) + + @staticmethod + def _get_port_count(bridge, param): + """Returns the number of ports having a certain parameter + + :param bridge: The src.ovs.ofctl.OFBridge on which to operate + :param param: The parameter to search for + :returns: Count of matches + """ + port_params = [c for (_, (_, c)) in list(bridge.get_ports().items())] + param_hits = [i for i in port_params if param in i] + return len(param_hits) diff --git a/vswitches/utils.py b/vswitches/utils.py new file mode 100644 index 00000000..7350de31 --- /dev/null +++ b/vswitches/utils.py @@ -0,0 +1,40 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Utility functions for working with vSwitches and flows +""" + +import copy + +def add_ports_to_flow(flow, in_port, out_port): + """Creates a new flow based on the given flow and adds in port and out port + to it. + + The flow dictionary structure is described in IVswitch + + :param flow: Description of the flow as a dictionary + :param in_port: OpenFlow number of the ingress port for the rule + :param out_port: OpenFlow number of the eggress port for the rule + + :returns: A new dictionary describing a flow combining the parameters + """ + new_flow = copy.deepcopy(flow) + new_flow['in_port'] = in_port + + if 'actions' in new_flow: + new_flow['actions'].append('output:' + str(out_port)) + else: + new_flow['actions'] = ['output:' + str(out_port)] + + return new_flow diff --git a/vswitches/vswitch.py b/vswitches/vswitch.py new file mode 100644 index 00000000..713974ae --- /dev/null +++ b/vswitches/vswitch.py @@ -0,0 +1,114 @@ +# Copyright 2015 Intel Corporation. +# +# 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. + +"""Generic interface VSPERF uses for controlling a vSwitch +""" + +class IVSwitch(object): + """Interface class that is implemented by vSwitch-specific classes + + Other methods are called only between start() and stop() + """ + def start(self): + """Start the vSwitch + + If vSwitch is split to multiple processes, has kernel modules etc., + this is expected to set them all up in correct sequence + """ + raise NotImplementedError() + + def stop(self): + """Stop the vSwitch + + If vSwitch is split to multiple processes, has kernel modules etc., + this is expected to terminate and clean all of them in correct sequence + """ + raise NotImplementedError() + + def add_switch(self, switch_name): + """Create a new logical switch with no ports + + :param switch_name: The name of the new logical switch + :returns: None + """ + raise NotImplementedError() + + def del_switch(self, switch_name): + """Destroy the given logical switch + + :param switch_name: The name of the logical switch to be destroyed + :returns: None + """ + raise NotImplementedError() + + def add_phy_port(self, switch_name): + """Create a new port to the logical switch that is attached to a + physical port + + :param switch_name: The switch where the port is attached to + :returns: (port name, OpenFlow port number) + """ + raise NotImplementedError() + + def add_vport(self, switch_name): + """Create a new port to the logical switch for VM connections + + :param switch_name: The switch where the port is attached to + :returns: (port name, OpenFlow port number) + """ + raise NotImplementedError() + + def get_ports(self, switch_name): + """Return a list of tuples describing the ports of the logical switch + + :param switch_name: The switch whose ports to return + :returns: [(port name, OpenFlow port number), ...] + """ + raise NotImplementedError() + + def del_port(self, switch_name, port_name): + """Delete the port from the logical switch + + The port can be either physical or virtual + + :param switch_name: The switch on which to operate + :param port_name: The port to delete + """ + raise NotImplementedError() + + def add_flow(self, switch_name, flow): + """Add a flow rule to the logical switch + + :param switch_name: The switch on which to operate + :param flow: Flow description as a dictionary + + Example flow dictionary: + flow = { + 'in_port': '1', + 'idle_timeout': '0', + 'actions': ['output:3'] + } + """ + raise NotImplementedError() + + def del_flow(self, switch_name, flow=None): + """Delete the flow rule from the logical switch + + :param switch_name: The switch on which to operate + :param flow: Flow description as a dictionary + + For flow dictionary description, see add_flow + For flow==None, all flows are deleted + """ + raise NotImplementedError() |