diff options
author | Maryam Tahhan <maryam.tahhan@intel.com> | 2015-06-08 15:03:08 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@172.30.200.206> | 2015-06-08 15:03:08 +0000 |
commit | f3f1ff9b08efa4a18bdcd2284d0a5f3b6ee526e0 (patch) | |
tree | a736bab8be95381d2277626c8df2f88ccce714d0 | |
parent | 1612a95c88e6ccff6f9b158f9b106e410b1d7324 (diff) | |
parent | 8d6777df09c3dc441013a31f21cc50ab3b0f42a3 (diff) |
Merge "framework: Add reworked framework to repo"
69 files changed, 14874 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/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() |